diff options
author | Haavard Skinnemoen <haavard.skinnemoen@atmel.com> | 2009-03-27 11:14:38 -0400 |
---|---|---|
committer | Haavard Skinnemoen <haavard.skinnemoen@atmel.com> | 2009-03-27 11:14:38 -0400 |
commit | b92efa9abffc4a634cd2e7a0f81f8aa6310d67c9 (patch) | |
tree | 9847508d9b8d4e585f90db4a453bfbc3700c997e /kernel/module.c | |
parent | a16fffdd8eb95ebab7dc22414896fe6493951e0e (diff) | |
parent | be0ea69674ed95e1e98cb3687a241badc756d228 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into avr32-arch
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 60 |
1 files changed, 36 insertions, 24 deletions
diff --git a/kernel/module.c b/kernel/module.c index e8b51d41dd72..77672233387f 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -573,13 +573,13 @@ static char last_unloaded_module[MODULE_NAME_LEN+1]; | |||
573 | /* Init the unload section of the module. */ | 573 | /* Init the unload section of the module. */ |
574 | static void module_unload_init(struct module *mod) | 574 | static void module_unload_init(struct module *mod) |
575 | { | 575 | { |
576 | unsigned int i; | 576 | int cpu; |
577 | 577 | ||
578 | INIT_LIST_HEAD(&mod->modules_which_use_me); | 578 | INIT_LIST_HEAD(&mod->modules_which_use_me); |
579 | for (i = 0; i < NR_CPUS; i++) | 579 | for_each_possible_cpu(cpu) |
580 | local_set(&mod->ref[i].count, 0); | 580 | local_set(__module_ref_addr(mod, cpu), 0); |
581 | /* Hold reference count during initialization. */ | 581 | /* Hold reference count during initialization. */ |
582 | local_set(&mod->ref[raw_smp_processor_id()].count, 1); | 582 | local_set(__module_ref_addr(mod, raw_smp_processor_id()), 1); |
583 | /* Backwards compatibility macros put refcount during init. */ | 583 | /* Backwards compatibility macros put refcount during init. */ |
584 | mod->waiter = current; | 584 | mod->waiter = current; |
585 | } | 585 | } |
@@ -717,10 +717,11 @@ static int try_stop_module(struct module *mod, int flags, int *forced) | |||
717 | 717 | ||
718 | unsigned int module_refcount(struct module *mod) | 718 | unsigned int module_refcount(struct module *mod) |
719 | { | 719 | { |
720 | unsigned int i, total = 0; | 720 | unsigned int total = 0; |
721 | int cpu; | ||
721 | 722 | ||
722 | for (i = 0; i < NR_CPUS; i++) | 723 | for_each_possible_cpu(cpu) |
723 | total += local_read(&mod->ref[i].count); | 724 | total += local_read(__module_ref_addr(mod, cpu)); |
724 | return total; | 725 | return total; |
725 | } | 726 | } |
726 | EXPORT_SYMBOL(module_refcount); | 727 | EXPORT_SYMBOL(module_refcount); |
@@ -821,7 +822,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user, | |||
821 | mutex_lock(&module_mutex); | 822 | mutex_lock(&module_mutex); |
822 | /* Store the name of the last unloaded module for diagnostic purposes */ | 823 | /* Store the name of the last unloaded module for diagnostic purposes */ |
823 | strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module)); | 824 | strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module)); |
824 | unregister_dynamic_debug_module(mod->name); | 825 | ddebug_remove_module(mod->name); |
825 | free_module(mod); | 826 | free_module(mod); |
826 | 827 | ||
827 | out: | 828 | out: |
@@ -894,7 +895,7 @@ void module_put(struct module *module) | |||
894 | { | 895 | { |
895 | if (module) { | 896 | if (module) { |
896 | unsigned int cpu = get_cpu(); | 897 | unsigned int cpu = get_cpu(); |
897 | local_dec(&module->ref[cpu].count); | 898 | local_dec(__module_ref_addr(module, cpu)); |
898 | /* Maybe they're waiting for us to drop reference? */ | 899 | /* Maybe they're waiting for us to drop reference? */ |
899 | if (unlikely(!module_is_live(module))) | 900 | if (unlikely(!module_is_live(module))) |
900 | wake_up_process(module->waiter); | 901 | wake_up_process(module->waiter); |
@@ -1464,7 +1465,10 @@ static void free_module(struct module *mod) | |||
1464 | kfree(mod->args); | 1465 | kfree(mod->args); |
1465 | if (mod->percpu) | 1466 | if (mod->percpu) |
1466 | percpu_modfree(mod->percpu); | 1467 | percpu_modfree(mod->percpu); |
1467 | 1468 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) | |
1469 | if (mod->refptr) | ||
1470 | percpu_modfree(mod->refptr); | ||
1471 | #endif | ||
1468 | /* Free lock-classes: */ | 1472 | /* Free lock-classes: */ |
1469 | lockdep_free_key_range(mod->module_core, mod->core_size); | 1473 | lockdep_free_key_range(mod->module_core, mod->core_size); |
1470 | 1474 | ||
@@ -1823,19 +1827,13 @@ static inline void add_kallsyms(struct module *mod, | |||
1823 | } | 1827 | } |
1824 | #endif /* CONFIG_KALLSYMS */ | 1828 | #endif /* CONFIG_KALLSYMS */ |
1825 | 1829 | ||
1826 | static void dynamic_printk_setup(struct mod_debug *debug, unsigned int num) | 1830 | static void dynamic_debug_setup(struct _ddebug *debug, unsigned int num) |
1827 | { | 1831 | { |
1828 | #ifdef CONFIG_DYNAMIC_PRINTK_DEBUG | 1832 | #ifdef CONFIG_DYNAMIC_DEBUG |
1829 | unsigned int i; | 1833 | if (ddebug_add_module(debug, num, debug->modname)) |
1830 | 1834 | printk(KERN_ERR "dynamic debug error adding module: %s\n", | |
1831 | for (i = 0; i < num; i++) { | 1835 | debug->modname); |
1832 | register_dynamic_debug_module(debug[i].modname, | 1836 | #endif |
1833 | debug[i].type, | ||
1834 | debug[i].logical_modname, | ||
1835 | debug[i].flag_names, | ||
1836 | debug[i].hash, debug[i].hash2); | ||
1837 | } | ||
1838 | #endif /* CONFIG_DYNAMIC_PRINTK_DEBUG */ | ||
1839 | } | 1837 | } |
1840 | 1838 | ||
1841 | static void *module_alloc_update_bounds(unsigned long size) | 1839 | static void *module_alloc_update_bounds(unsigned long size) |
@@ -2070,6 +2068,14 @@ static noinline struct module *load_module(void __user *umod, | |||
2070 | /* Module has been moved. */ | 2068 | /* Module has been moved. */ |
2071 | mod = (void *)sechdrs[modindex].sh_addr; | 2069 | mod = (void *)sechdrs[modindex].sh_addr; |
2072 | 2070 | ||
2071 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) | ||
2072 | mod->refptr = percpu_modalloc(sizeof(local_t), __alignof__(local_t), | ||
2073 | mod->name); | ||
2074 | if (!mod->refptr) { | ||
2075 | err = -ENOMEM; | ||
2076 | goto free_init; | ||
2077 | } | ||
2078 | #endif | ||
2073 | /* Now we've moved module, initialize linked lists, etc. */ | 2079 | /* Now we've moved module, initialize linked lists, etc. */ |
2074 | module_unload_init(mod); | 2080 | module_unload_init(mod); |
2075 | 2081 | ||
@@ -2201,12 +2207,13 @@ static noinline struct module *load_module(void __user *umod, | |||
2201 | add_kallsyms(mod, sechdrs, symindex, strindex, secstrings); | 2207 | add_kallsyms(mod, sechdrs, symindex, strindex, secstrings); |
2202 | 2208 | ||
2203 | if (!mod->taints) { | 2209 | if (!mod->taints) { |
2204 | struct mod_debug *debug; | 2210 | struct _ddebug *debug; |
2205 | unsigned int num_debug; | 2211 | unsigned int num_debug; |
2206 | 2212 | ||
2207 | debug = section_objs(hdr, sechdrs, secstrings, "__verbose", | 2213 | debug = section_objs(hdr, sechdrs, secstrings, "__verbose", |
2208 | sizeof(*debug), &num_debug); | 2214 | sizeof(*debug), &num_debug); |
2209 | dynamic_printk_setup(debug, num_debug); | 2215 | if (debug) |
2216 | dynamic_debug_setup(debug, num_debug); | ||
2210 | } | 2217 | } |
2211 | 2218 | ||
2212 | /* sechdrs[0].sh_size is always zero */ | 2219 | /* sechdrs[0].sh_size is always zero */ |
@@ -2276,9 +2283,14 @@ static noinline struct module *load_module(void __user *umod, | |||
2276 | ftrace_release(mod->module_core, mod->core_size); | 2283 | ftrace_release(mod->module_core, mod->core_size); |
2277 | free_unload: | 2284 | free_unload: |
2278 | module_unload_free(mod); | 2285 | module_unload_free(mod); |
2286 | free_init: | ||
2287 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) | ||
2288 | percpu_modfree(mod->refptr); | ||
2289 | #endif | ||
2279 | module_free(mod, mod->module_init); | 2290 | module_free(mod, mod->module_init); |
2280 | free_core: | 2291 | free_core: |
2281 | module_free(mod, mod->module_core); | 2292 | module_free(mod, mod->module_core); |
2293 | /* mod will be freed with core. Don't access it beyond this line! */ | ||
2282 | free_percpu: | 2294 | free_percpu: |
2283 | if (percpu) | 2295 | if (percpu) |
2284 | percpu_modfree(percpu); | 2296 | percpu_modfree(percpu); |