[PATCH] module: kzalloc mod->ref

From: Kyle McMartin
Date: Tue Jan 13 2009 - 22:35:46 EST


From: Kyle McMartin <kyle@xxxxxxxxxx>

Dynamically allocate mod->ref instead of fixing it in the struct module.
Reduces on disk space wasted in the module .ko, and kills a loop
initializing the local_t it contains since we can just kzalloc it.

This matters when we're talking about large NR_CPUS.

Signed-off-by: Kyle McMartin <kyle@xxxxxxxxxx>
---
The patch removing cacheline_aligned from struct module_ref should be
applied as well to cut down on the amount of memory we allocate. This
patch makes a nice stopgap until we have per_cpu module references.

cheers, Kyle

diff --git a/include/linux/module.h b/include/linux/module.h
index 4f7ea12..5863998 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -345,7 +345,7 @@ struct module
void (*exit)(void);

/* Reference counts */
- struct module_ref ref[NR_CPUS];
+ struct module_ref *ref;
#endif
};
#ifndef MODULE_ARCH_INIT
diff --git a/kernel/module.c b/kernel/module.c
index c9332c9..bc0a9b0 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -571,17 +571,19 @@ static char last_unloaded_module[MODULE_NAME_LEN+1];

#ifdef CONFIG_MODULE_UNLOAD
/* Init the unload section of the module. */
-static void module_unload_init(struct module *mod)
+static int module_unload_init(struct module *mod)
{
- unsigned int i;
+ mod->ref = kzalloc(NR_CPUS * sizeof(*mod->ref), GFP_KERNEL);
+ if (!mod->ref)
+ return -ENOMEM;

INIT_LIST_HEAD(&mod->modules_which_use_me);
- for (i = 0; i < NR_CPUS; i++)
- local_set(&mod->ref[i].count, 0);
/* Hold reference count during initialization. */
local_set(&mod->ref[raw_smp_processor_id()].count, 1);
/* Backwards compatibility macros put refcount during init. */
mod->waiter = current;
+
+ return 0;
}

/* modules using other modules */
@@ -919,8 +921,9 @@ static inline int use_module(struct module *a, struct module *b)
return strong_try_module_get(b) == 0;
}

-static inline void module_unload_init(struct module *mod)
+static inline int module_unload_init(struct module *mod)
{
+ return 0;
}
#endif /* CONFIG_MODULE_UNLOAD */

@@ -2071,7 +2074,9 @@ static noinline struct module *load_module(void __user *umod,
mod = (void *)sechdrs[modindex].sh_addr;

/* Now we've moved module, initialize linked lists, etc. */
- module_unload_init(mod);
+ err = module_unload_init(mod);
+ if (err < 0)
+ goto free_unload;

/* add kobject, so we can reference it. */
err = mod_sysfs_init(mod);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/