]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.suse/module-ref-dynamic-alloc
Merge branch 'master' of git://git.ipfire.org/ipfire-2.x
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.suse / module-ref-dynamic-alloc
1 From: Takashi Iwai <tiwai@suse.de>
2 Subject: [PATCH] Allocate module.ref array dynamically
3 Patch-mainline:
4 References: bnc#425240
5
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
9 like 4096.
10
11 Reference: Novell bnc#425240
12 https://bugzilla.novell.com/show_bug.cgi?id=425240
13
14 Signed-off-by: Takashi Iwai <tiwai@suse.de>
15
16 ---
17 include/linux/module.h | 2 +-
18 kernel/module.c | 21 ++++++++++++++++-----
19 2 files changed, 17 insertions(+), 6 deletions(-)
20
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_
26
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)
31 {
32 unsigned int i;
33 + size_t refsize = nr_cpu_ids * sizeof(*mod->ref);
34
35 INIT_LIST_HEAD(&mod->modules_which_use_me);
36 - for (i = 0; i < NR_CPUS; i++)
37 +
38 + mod->ref = kzalloc(refsize, GFP_KERNEL);
39 + if (!mod->ref) {
40 + mod->ref = vmalloc(refsize);
41 + if (!mod->ref)
42 + return -ENOMEM;
43 + memset(mod->ref, 0, refsize);
44 + }
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;
51 +
52 + return 0;
53 }
54
55 /* modules using other modules */
56 @@ -647,6 +658,10 @@ static void module_unload_free(struct mo
57 }
58 }
59 }
60 + if (is_vmalloc_addr(mod->ref))
61 + vfree(mod->ref);
62 + else
63 + kfree(mod->ref);
64 }
65
66 #ifdef CONFIG_MODULE_FORCE_UNLOAD
67 @@ -705,7 +720,7 @@ unsigned int module_refcount(struct modu
68 {
69 unsigned int i, total = 0;
70
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);
74 return total;
75 }
76 @@ -894,8 +909,9 @@ static inline int use_module(struct modu
77 return strong_try_module_get(b) == 0;
78 }
79
80 -static inline void module_unload_init(struct module *mod)
81 +static inline int module_unload_init(struct module *mod)
82 {
83 + return 0;
84 }
85 #endif /* CONFIG_MODULE_UNLOAD */
86
87 @@ -2108,7 +2124,9 @@ static noinline struct module *load_modu
88 mod = (void *)sechdrs[modindex].sh_addr;
89
90 /* Now we've moved module, initialize linked lists, etc. */
91 - module_unload_init(mod);
92 + err = module_unload_init(mod);
93 + if (err)
94 + goto free_unload;
95
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
103 void (*exit)(void);
104
105 /* Reference counts */
106 - struct module_ref ref[NR_CPUS];
107 + struct module_ref *ref;
108 #endif
109 };
110 #ifndef MODULE_ARCH_INIT