1 From: Takashi Iwai <tiwai@suse.de>
2 Subject: [PATCH] Allocate module.ref array dynamically
6 This patch makes the module handling code to allocate the ref
7 array of each module struct dynamically. It saves both module
8 disk space and memory footprints when number of CPUs is high
11 Reference: Novell bnc#425240
12 https://bugzilla.novell.com/show_bug.cgi?id=425240
14 Signed-off-by: Takashi Iwai <tiwai@suse.de>
17 include/linux/module.h | 2 +-
18 kernel/module.c | 21 ++++++++++++++++-----
19 2 files changed, 17 insertions(+), 6 deletions(-)
21 Index: linux-2.6.27/kernel/module.c
22 ===================================================================
23 --- linux-2.6.27.orig/kernel/module.c
24 +++ linux-2.6.27/kernel/module.c
25 @@ -557,17 +557,28 @@ static char last_unloaded_module[MODULE_
27 #ifdef CONFIG_MODULE_UNLOAD
28 /* Init the unload section of the module. */
29 -static void module_unload_init(struct module *mod)
30 +static int module_unload_init(struct module *mod)
33 + size_t refsize = nr_cpu_ids * sizeof(*mod->ref);
35 INIT_LIST_HEAD(&mod->modules_which_use_me);
36 - for (i = 0; i < NR_CPUS; i++)
38 + mod->ref = kzalloc(refsize, GFP_KERNEL);
40 + mod->ref = vmalloc(refsize);
43 + memset(mod->ref, 0, refsize);
45 + for (i = 0; i < nr_cpu_ids; i++)
46 local_set(&mod->ref[i].count, 0);
47 /* Hold reference count during initialization. */
48 local_set(&mod->ref[raw_smp_processor_id()].count, 1);
49 /* Backwards compatibility macros put refcount during init. */
50 mod->waiter = current;
55 /* modules using other modules */
56 @@ -647,6 +658,10 @@ static void module_unload_free(struct mo
60 + if (is_vmalloc_addr(mod->ref))
66 #ifdef CONFIG_MODULE_FORCE_UNLOAD
67 @@ -705,7 +720,7 @@ unsigned int module_refcount(struct modu
69 unsigned int i, total = 0;
71 - for (i = 0; i < NR_CPUS; i++)
72 + for (i = 0; i < nr_cpu_ids; i++)
73 total += local_read(&mod->ref[i].count);
76 @@ -894,8 +909,9 @@ static inline int use_module(struct modu
77 return strong_try_module_get(b) == 0;
80 -static inline void module_unload_init(struct module *mod)
81 +static inline int module_unload_init(struct module *mod)
85 #endif /* CONFIG_MODULE_UNLOAD */
87 @@ -2108,7 +2124,9 @@ static noinline struct module *load_modu
88 mod = (void *)sechdrs[modindex].sh_addr;
90 /* Now we've moved module, initialize linked lists, etc. */
91 - module_unload_init(mod);
92 + err = module_unload_init(mod);
96 /* add kobject, so we can reference it. */
97 err = mod_sysfs_init(mod);
98 Index: linux-2.6.27/include/linux/module.h
99 ===================================================================
100 --- linux-2.6.27.orig/include/linux/module.h
101 +++ linux-2.6.27/include/linux/module.h
102 @@ -343,7 +343,7 @@ struct module
105 /* Reference counts */
106 - struct module_ref ref[NR_CPUS];
107 + struct module_ref *ref;
110 #ifndef MODULE_ARCH_INIT