Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Eric Dumazet and committed by
Rusty Russell
bd77c047 48fd1188

+21 -10
+16 -5
include/linux/module.h
··· 205 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 + */ 217 + struct module_ref { 218 + unsigned long incs; 219 + unsigned long decs; 220 + } __attribute((aligned(2 * sizeof(unsigned long)))); 221 + 208 222 struct module 209 223 { 210 224 enum module_state state; ··· 361 347 /* Destruction function. */ 362 348 void (*exit)(void); 363 349 364 - struct module_ref { 365 - unsigned int incs; 366 - unsigned int decs; 367 - } __percpu *refptr; 350 + struct module_ref __percpu *refptr; 368 351 #endif 369 352 370 353 #ifdef CONFIG_CONSTRUCTORS ··· 445 434 #define module_put_and_exit(code) __module_put_and_exit(THIS_MODULE, code); 446 435 447 436 #ifdef CONFIG_MODULE_UNLOAD 448 - unsigned int module_refcount(struct module *mod); 437 + unsigned long module_refcount(struct module *mod); 449 438 void __symbol_put(const char *symbol); 450 439 #define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x) 451 440 void symbol_put_addr(void *addr);
+1 -1
kernel/debug/kdb/kdb_main.c
··· 1982 1982 kdb_printf("%-20s%8u 0x%p ", mod->name, 1983 1983 mod->core_size, (void *)mod); 1984 1984 #ifdef CONFIG_MODULE_UNLOAD 1985 - kdb_printf("%4d ", module_refcount(mod)); 1985 + kdb_printf("%4ld ", module_refcount(mod)); 1986 1986 #endif 1987 1987 if (mod->state == MODULE_STATE_GOING) 1988 1988 kdb_printf(" (Unloading)");
+4 -4
kernel/module.c
··· 725 725 } 726 726 } 727 727 728 - unsigned int module_refcount(struct module *mod) 728 + unsigned long module_refcount(struct module *mod) 729 729 { 730 - unsigned int incs = 0, decs = 0; 730 + unsigned long incs = 0, decs = 0; 731 731 int cpu; 732 732 733 733 for_each_possible_cpu(cpu) ··· 853 853 struct module_use *use; 854 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 858 /* Always include a trailing , so userspace can differentiate 859 859 between this and the old multi-field proc format. */ ··· 903 903 static ssize_t show_refcnt(struct module_attribute *mattr, 904 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 909 909 static struct module_attribute refcnt = {