diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-03-28 18:34:14 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-03-28 18:34:14 -0400 |
commit | 38a6ed3ed8e108b662f4016a1ebf068dcf4c1ef4 (patch) | |
tree | a83d5e4e86edf6cb2de22db6f2ff2274753a2bab /kernel/module.c | |
parent | f2d28a2ebcb525a6ec7e2152106ddb385ef52b73 (diff) | |
parent | 7c730ccdc1188b97f5c8cb690906242c7ed75c22 (diff) |
Merge branch 'linus' into core/printk
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 115 |
1 files changed, 73 insertions, 42 deletions
diff --git a/kernel/module.c b/kernel/module.c index ba22484a987e..f77ac320d0b5 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <linux/tracepoint.h> | 51 | #include <linux/tracepoint.h> |
52 | #include <linux/ftrace.h> | 52 | #include <linux/ftrace.h> |
53 | #include <linux/async.h> | 53 | #include <linux/async.h> |
54 | #include <linux/percpu.h> | ||
54 | 55 | ||
55 | #if 0 | 56 | #if 0 |
56 | #define DEBUGP printk | 57 | #define DEBUGP printk |
@@ -366,6 +367,34 @@ static struct module *find_module(const char *name) | |||
366 | } | 367 | } |
367 | 368 | ||
368 | #ifdef CONFIG_SMP | 369 | #ifdef CONFIG_SMP |
370 | |||
371 | #ifdef CONFIG_HAVE_DYNAMIC_PER_CPU_AREA | ||
372 | |||
373 | static void *percpu_modalloc(unsigned long size, unsigned long align, | ||
374 | const char *name) | ||
375 | { | ||
376 | void *ptr; | ||
377 | |||
378 | if (align > PAGE_SIZE) { | ||
379 | printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n", | ||
380 | name, align, PAGE_SIZE); | ||
381 | align = PAGE_SIZE; | ||
382 | } | ||
383 | |||
384 | ptr = __alloc_reserved_percpu(size, align); | ||
385 | if (!ptr) | ||
386 | printk(KERN_WARNING | ||
387 | "Could not allocate %lu bytes percpu data\n", size); | ||
388 | return ptr; | ||
389 | } | ||
390 | |||
391 | static void percpu_modfree(void *freeme) | ||
392 | { | ||
393 | free_percpu(freeme); | ||
394 | } | ||
395 | |||
396 | #else /* ... !CONFIG_HAVE_DYNAMIC_PER_CPU_AREA */ | ||
397 | |||
369 | /* Number of blocks used and allocated. */ | 398 | /* Number of blocks used and allocated. */ |
370 | static unsigned int pcpu_num_used, pcpu_num_allocated; | 399 | static unsigned int pcpu_num_used, pcpu_num_allocated; |
371 | /* Size of each block. -ve means used. */ | 400 | /* Size of each block. -ve means used. */ |
@@ -480,21 +509,6 @@ static void percpu_modfree(void *freeme) | |||
480 | } | 509 | } |
481 | } | 510 | } |
482 | 511 | ||
483 | static unsigned int find_pcpusec(Elf_Ehdr *hdr, | ||
484 | Elf_Shdr *sechdrs, | ||
485 | const char *secstrings) | ||
486 | { | ||
487 | return find_sec(hdr, sechdrs, secstrings, ".data.percpu"); | ||
488 | } | ||
489 | |||
490 | static void percpu_modcopy(void *pcpudest, const void *from, unsigned long size) | ||
491 | { | ||
492 | int cpu; | ||
493 | |||
494 | for_each_possible_cpu(cpu) | ||
495 | memcpy(pcpudest + per_cpu_offset(cpu), from, size); | ||
496 | } | ||
497 | |||
498 | static int percpu_modinit(void) | 512 | static int percpu_modinit(void) |
499 | { | 513 | { |
500 | pcpu_num_used = 2; | 514 | pcpu_num_used = 2; |
@@ -513,7 +527,26 @@ static int percpu_modinit(void) | |||
513 | return 0; | 527 | return 0; |
514 | } | 528 | } |
515 | __initcall(percpu_modinit); | 529 | __initcall(percpu_modinit); |
530 | |||
531 | #endif /* CONFIG_HAVE_DYNAMIC_PER_CPU_AREA */ | ||
532 | |||
533 | static unsigned int find_pcpusec(Elf_Ehdr *hdr, | ||
534 | Elf_Shdr *sechdrs, | ||
535 | const char *secstrings) | ||
536 | { | ||
537 | return find_sec(hdr, sechdrs, secstrings, ".data.percpu"); | ||
538 | } | ||
539 | |||
540 | static void percpu_modcopy(void *pcpudest, const void *from, unsigned long size) | ||
541 | { | ||
542 | int cpu; | ||
543 | |||
544 | for_each_possible_cpu(cpu) | ||
545 | memcpy(pcpudest + per_cpu_offset(cpu), from, size); | ||
546 | } | ||
547 | |||
516 | #else /* ... !CONFIG_SMP */ | 548 | #else /* ... !CONFIG_SMP */ |
549 | |||
517 | static inline void *percpu_modalloc(unsigned long size, unsigned long align, | 550 | static inline void *percpu_modalloc(unsigned long size, unsigned long align, |
518 | const char *name) | 551 | const char *name) |
519 | { | 552 | { |
@@ -535,6 +568,7 @@ static inline void percpu_modcopy(void *pcpudst, const void *src, | |||
535 | /* pcpusec should be 0, and size of that section should be 0. */ | 568 | /* pcpusec should be 0, and size of that section should be 0. */ |
536 | BUG_ON(size != 0); | 569 | BUG_ON(size != 0); |
537 | } | 570 | } |
571 | |||
538 | #endif /* CONFIG_SMP */ | 572 | #endif /* CONFIG_SMP */ |
539 | 573 | ||
540 | #define MODINFO_ATTR(field) \ | 574 | #define MODINFO_ATTR(field) \ |
@@ -822,7 +856,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user, | |||
822 | mutex_lock(&module_mutex); | 856 | mutex_lock(&module_mutex); |
823 | /* Store the name of the last unloaded module for diagnostic purposes */ | 857 | /* Store the name of the last unloaded module for diagnostic purposes */ |
824 | strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module)); | 858 | strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module)); |
825 | unregister_dynamic_debug_module(mod->name); | 859 | ddebug_remove_module(mod->name); |
826 | free_module(mod); | 860 | free_module(mod); |
827 | 861 | ||
828 | out: | 862 | out: |
@@ -1827,19 +1861,13 @@ static inline void add_kallsyms(struct module *mod, | |||
1827 | } | 1861 | } |
1828 | #endif /* CONFIG_KALLSYMS */ | 1862 | #endif /* CONFIG_KALLSYMS */ |
1829 | 1863 | ||
1830 | static void dynamic_printk_setup(struct mod_debug *debug, unsigned int num) | 1864 | static void dynamic_debug_setup(struct _ddebug *debug, unsigned int num) |
1831 | { | 1865 | { |
1832 | #ifdef CONFIG_DYNAMIC_PRINTK_DEBUG | 1866 | #ifdef CONFIG_DYNAMIC_DEBUG |
1833 | unsigned int i; | 1867 | if (ddebug_add_module(debug, num, debug->modname)) |
1834 | 1868 | printk(KERN_ERR "dynamic debug error adding module: %s\n", | |
1835 | for (i = 0; i < num; i++) { | 1869 | debug->modname); |
1836 | register_dynamic_debug_module(debug[i].modname, | 1870 | #endif |
1837 | debug[i].type, | ||
1838 | debug[i].logical_modname, | ||
1839 | debug[i].flag_names, | ||
1840 | debug[i].hash, debug[i].hash2); | ||
1841 | } | ||
1842 | #endif /* CONFIG_DYNAMIC_PRINTK_DEBUG */ | ||
1843 | } | 1871 | } |
1844 | 1872 | ||
1845 | static void *module_alloc_update_bounds(unsigned long size) | 1873 | static void *module_alloc_update_bounds(unsigned long size) |
@@ -2015,14 +2043,6 @@ static noinline struct module *load_module(void __user *umod, | |||
2015 | if (err < 0) | 2043 | if (err < 0) |
2016 | goto free_mod; | 2044 | goto free_mod; |
2017 | 2045 | ||
2018 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) | ||
2019 | mod->refptr = percpu_modalloc(sizeof(local_t), __alignof__(local_t), | ||
2020 | mod->name); | ||
2021 | if (!mod->refptr) { | ||
2022 | err = -ENOMEM; | ||
2023 | goto free_mod; | ||
2024 | } | ||
2025 | #endif | ||
2026 | if (pcpuindex) { | 2046 | if (pcpuindex) { |
2027 | /* We have a special allocation for this section. */ | 2047 | /* We have a special allocation for this section. */ |
2028 | percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size, | 2048 | percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size, |
@@ -2030,7 +2050,7 @@ static noinline struct module *load_module(void __user *umod, | |||
2030 | mod->name); | 2050 | mod->name); |
2031 | if (!percpu) { | 2051 | if (!percpu) { |
2032 | err = -ENOMEM; | 2052 | err = -ENOMEM; |
2033 | goto free_percpu; | 2053 | goto free_mod; |
2034 | } | 2054 | } |
2035 | sechdrs[pcpuindex].sh_flags &= ~(unsigned long)SHF_ALLOC; | 2055 | sechdrs[pcpuindex].sh_flags &= ~(unsigned long)SHF_ALLOC; |
2036 | mod->percpu = percpu; | 2056 | mod->percpu = percpu; |
@@ -2082,6 +2102,14 @@ static noinline struct module *load_module(void __user *umod, | |||
2082 | /* Module has been moved. */ | 2102 | /* Module has been moved. */ |
2083 | mod = (void *)sechdrs[modindex].sh_addr; | 2103 | mod = (void *)sechdrs[modindex].sh_addr; |
2084 | 2104 | ||
2105 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) | ||
2106 | mod->refptr = percpu_modalloc(sizeof(local_t), __alignof__(local_t), | ||
2107 | mod->name); | ||
2108 | if (!mod->refptr) { | ||
2109 | err = -ENOMEM; | ||
2110 | goto free_init; | ||
2111 | } | ||
2112 | #endif | ||
2085 | /* Now we've moved module, initialize linked lists, etc. */ | 2113 | /* Now we've moved module, initialize linked lists, etc. */ |
2086 | module_unload_init(mod); | 2114 | module_unload_init(mod); |
2087 | 2115 | ||
@@ -2213,12 +2241,13 @@ static noinline struct module *load_module(void __user *umod, | |||
2213 | add_kallsyms(mod, sechdrs, symindex, strindex, secstrings); | 2241 | add_kallsyms(mod, sechdrs, symindex, strindex, secstrings); |
2214 | 2242 | ||
2215 | if (!mod->taints) { | 2243 | if (!mod->taints) { |
2216 | struct mod_debug *debug; | 2244 | struct _ddebug *debug; |
2217 | unsigned int num_debug; | 2245 | unsigned int num_debug; |
2218 | 2246 | ||
2219 | debug = section_objs(hdr, sechdrs, secstrings, "__verbose", | 2247 | debug = section_objs(hdr, sechdrs, secstrings, "__verbose", |
2220 | sizeof(*debug), &num_debug); | 2248 | sizeof(*debug), &num_debug); |
2221 | dynamic_printk_setup(debug, num_debug); | 2249 | if (debug) |
2250 | dynamic_debug_setup(debug, num_debug); | ||
2222 | } | 2251 | } |
2223 | 2252 | ||
2224 | /* sechdrs[0].sh_size is always zero */ | 2253 | /* sechdrs[0].sh_size is always zero */ |
@@ -2288,15 +2317,17 @@ static noinline struct module *load_module(void __user *umod, | |||
2288 | ftrace_release(mod->module_core, mod->core_size); | 2317 | ftrace_release(mod->module_core, mod->core_size); |
2289 | free_unload: | 2318 | free_unload: |
2290 | module_unload_free(mod); | 2319 | module_unload_free(mod); |
2320 | free_init: | ||
2321 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) | ||
2322 | percpu_modfree(mod->refptr); | ||
2323 | #endif | ||
2291 | module_free(mod, mod->module_init); | 2324 | module_free(mod, mod->module_init); |
2292 | free_core: | 2325 | free_core: |
2293 | module_free(mod, mod->module_core); | 2326 | module_free(mod, mod->module_core); |
2327 | /* mod will be freed with core. Don't access it beyond this line! */ | ||
2294 | free_percpu: | 2328 | free_percpu: |
2295 | if (percpu) | 2329 | if (percpu) |
2296 | percpu_modfree(percpu); | 2330 | percpu_modfree(percpu); |
2297 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) | ||
2298 | percpu_modfree(mod->refptr); | ||
2299 | #endif | ||
2300 | free_mod: | 2331 | free_mod: |
2301 | kfree(args); | 2332 | kfree(args); |
2302 | free_hdr: | 2333 | free_hdr: |