aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2012-01-12 18:02:14 -0500
committerRusty Russell <rusty@rustcorp.com.au>2012-01-12 18:02:14 -0500
commitbd77c04772da38fca510c81f78e51f727123b919 (patch)
tree8554b40191d3d5adebbd2461d26450c0ed7295d4
parent48fd11880b5ef04270be8a87d9a9a9ee2fdae338 (diff)
module: struct module_ref should contains long fields
module_ref contains two "unsigned int" fields. Thats now too small, since some machines can open more than 2^32 files. Check commit 518de9b39e8 (fs: allow for more than 2^31 files) for reference. We can add an aligned(2 * sizeof(unsigned long)) attribute to force alloc_percpu() allocating module_ref areas in single cache lines. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> CC: Rusty Russell <rusty@rustcorp.com.au> CC: Tejun Heo <tj@kernel.org> CC: Robin Holt <holt@sgi.com> CC: David Miller <davem@davemloft.net> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r--include/linux/module.h21
-rw-r--r--kernel/debug/kdb/kdb_main.c2
-rw-r--r--kernel/module.c8
3 files changed, 21 insertions, 10 deletions
diff --git a/include/linux/module.h b/include/linux/module.h
index 3cb7839a60b9..4598bf03e98b 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -205,6 +205,20 @@ enum module_state
205 MODULE_STATE_GOING, 205 MODULE_STATE_GOING,
206}; 206};
207 207
208/**
209 * struct module_ref - per cpu module reference counts
210 * @incs: number of module get on this cpu
211 * @decs: number of module put on this cpu
212 *
213 * We force an alignment on 8 or 16 bytes, so that alloc_percpu()
214 * put @incs/@decs in same cache line, with no extra memory cost,
215 * since alloc_percpu() is fine grained.
216 */
217struct module_ref {
218 unsigned long incs;
219 unsigned long decs;
220} __attribute((aligned(2 * sizeof(unsigned long))));
221
208struct module 222struct module
209{ 223{
210 enum module_state state; 224 enum module_state state;
@@ -347,10 +361,7 @@ struct module
347 /* Destruction function. */ 361 /* Destruction function. */
348 void (*exit)(void); 362 void (*exit)(void);
349 363
350 struct module_ref { 364 struct module_ref __percpu *refptr;
351 unsigned int incs;
352 unsigned int decs;
353 } __percpu *refptr;
354#endif 365#endif
355 366
356#ifdef CONFIG_CONSTRUCTORS 367#ifdef CONFIG_CONSTRUCTORS
@@ -434,7 +445,7 @@ extern void __module_put_and_exit(struct module *mod, long code)
434#define module_put_and_exit(code) __module_put_and_exit(THIS_MODULE, code); 445#define module_put_and_exit(code) __module_put_and_exit(THIS_MODULE, code);
435 446
436#ifdef CONFIG_MODULE_UNLOAD 447#ifdef CONFIG_MODULE_UNLOAD
437unsigned int module_refcount(struct module *mod); 448unsigned long module_refcount(struct module *mod);
438void __symbol_put(const char *symbol); 449void __symbol_put(const char *symbol);
439#define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x) 450#define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x)
440void symbol_put_addr(void *addr); 451void symbol_put_addr(void *addr);
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
index 63786e71a3cd..e2ae7349437f 100644
--- a/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -1982,7 +1982,7 @@ static int kdb_lsmod(int argc, const char **argv)
1982 kdb_printf("%-20s%8u 0x%p ", mod->name, 1982 kdb_printf("%-20s%8u 0x%p ", mod->name,
1983 mod->core_size, (void *)mod); 1983 mod->core_size, (void *)mod);
1984#ifdef CONFIG_MODULE_UNLOAD 1984#ifdef CONFIG_MODULE_UNLOAD
1985 kdb_printf("%4d ", module_refcount(mod)); 1985 kdb_printf("%4ld ", module_refcount(mod));
1986#endif 1986#endif
1987 if (mod->state == MODULE_STATE_GOING) 1987 if (mod->state == MODULE_STATE_GOING)
1988 kdb_printf(" (Unloading)"); 1988 kdb_printf(" (Unloading)");
diff --git a/kernel/module.c b/kernel/module.c
index 4928cffc3dcc..14b8e82e05d4 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -725,9 +725,9 @@ static int try_stop_module(struct module *mod, int flags, int *forced)
725 } 725 }
726} 726}
727 727
728unsigned int module_refcount(struct module *mod) 728unsigned long module_refcount(struct module *mod)
729{ 729{
730 unsigned int incs = 0, decs = 0; 730 unsigned long incs = 0, decs = 0;
731 int cpu; 731 int cpu;
732 732
733 for_each_possible_cpu(cpu) 733 for_each_possible_cpu(cpu)
@@ -853,7 +853,7 @@ static inline void print_unload_info(struct seq_file *m, struct module *mod)
853 struct module_use *use; 853 struct module_use *use;
854 int printed_something = 0; 854 int printed_something = 0;
855 855
856 seq_printf(m, " %u ", module_refcount(mod)); 856 seq_printf(m, " %lu ", module_refcount(mod));
857 857
858 /* Always include a trailing , so userspace can differentiate 858 /* Always include a trailing , so userspace can differentiate
859 between this and the old multi-field proc format. */ 859 between this and the old multi-field proc format. */
@@ -903,7 +903,7 @@ EXPORT_SYMBOL_GPL(symbol_put_addr);
903static ssize_t show_refcnt(struct module_attribute *mattr, 903static ssize_t show_refcnt(struct module_attribute *mattr,
904 struct module_kobject *mk, char *buffer) 904 struct module_kobject *mk, char *buffer)
905{ 905{
906 return sprintf(buffer, "%u\n", module_refcount(mk->mod)); 906 return sprintf(buffer, "%lu\n", module_refcount(mk->mod));
907} 907}
908 908
909static struct module_attribute refcnt = { 909static struct module_attribute refcnt = {