]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.suse/module-ref-dynamic-alloc
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.suse / module-ref-dynamic-alloc
CommitLineData
2cb7cef9
BS
1From: Takashi Iwai <tiwai@suse.de>
2Subject: [PATCH] Allocate module.ref array dynamically
3Patch-mainline:
4References: bnc#425240
5
6This patch makes the module handling code to allocate the ref
7array of each module struct dynamically. It saves both module
8disk space and memory footprints when number of CPUs is high
9like 4096.
10
11Reference: Novell bnc#425240
12 https://bugzilla.novell.com/show_bug.cgi?id=425240
13
14Signed-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
21Index: 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);
98Index: 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