diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-03-26 13:49:48 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-03-26 13:49:48 -0400 |
| commit | 18ffa418aead13c56515ac74cd26105102128aca (patch) | |
| tree | 2096ea8db3b2594bd25ad39a70edc691219f669b /kernel/module.c | |
| parent | ab76f3d771590d5c89faa3219559c5d3fc0ce0c2 (diff) | |
| parent | 8e0ee43bc2c3e19db56a4adaa9a9b04ce885cd84 (diff) | |
Merge commit 'v2.6.29' into x86/setup-lzma
Diffstat (limited to 'kernel/module.c')
| -rw-r--r-- | kernel/module.c | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/kernel/module.c b/kernel/module.c index c9332c90d5a0..1196f5d11700 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); |
| @@ -743,8 +744,8 @@ static void wait_for_zero_refcount(struct module *mod) | |||
| 743 | mutex_lock(&module_mutex); | 744 | mutex_lock(&module_mutex); |
| 744 | } | 745 | } |
| 745 | 746 | ||
| 746 | asmlinkage long | 747 | SYSCALL_DEFINE2(delete_module, const char __user *, name_user, |
| 747 | sys_delete_module(const char __user *name_user, unsigned int flags) | 748 | unsigned int, flags) |
| 748 | { | 749 | { |
| 749 | struct module *mod; | 750 | struct module *mod; |
| 750 | char name[MODULE_NAME_LEN]; | 751 | char name[MODULE_NAME_LEN]; |
| @@ -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 | ||
| @@ -2070,6 +2074,14 @@ static noinline struct module *load_module(void __user *umod, | |||
| 2070 | /* Module has been moved. */ | 2074 | /* Module has been moved. */ |
| 2071 | mod = (void *)sechdrs[modindex].sh_addr; | 2075 | mod = (void *)sechdrs[modindex].sh_addr; |
| 2072 | 2076 | ||
| 2077 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) | ||
| 2078 | mod->refptr = percpu_modalloc(sizeof(local_t), __alignof__(local_t), | ||
| 2079 | mod->name); | ||
| 2080 | if (!mod->refptr) { | ||
| 2081 | err = -ENOMEM; | ||
| 2082 | goto free_init; | ||
| 2083 | } | ||
| 2084 | #endif | ||
| 2073 | /* Now we've moved module, initialize linked lists, etc. */ | 2085 | /* Now we've moved module, initialize linked lists, etc. */ |
| 2074 | module_unload_init(mod); | 2086 | module_unload_init(mod); |
| 2075 | 2087 | ||
| @@ -2276,9 +2288,14 @@ static noinline struct module *load_module(void __user *umod, | |||
| 2276 | ftrace_release(mod->module_core, mod->core_size); | 2288 | ftrace_release(mod->module_core, mod->core_size); |
| 2277 | free_unload: | 2289 | free_unload: |
| 2278 | module_unload_free(mod); | 2290 | module_unload_free(mod); |
| 2291 | free_init: | ||
| 2292 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) | ||
| 2293 | percpu_modfree(mod->refptr); | ||
| 2294 | #endif | ||
| 2279 | module_free(mod, mod->module_init); | 2295 | module_free(mod, mod->module_init); |
| 2280 | free_core: | 2296 | free_core: |
| 2281 | module_free(mod, mod->module_core); | 2297 | module_free(mod, mod->module_core); |
| 2298 | /* mod will be freed with core. Don't access it beyond this line! */ | ||
| 2282 | free_percpu: | 2299 | free_percpu: |
| 2283 | if (percpu) | 2300 | if (percpu) |
| 2284 | percpu_modfree(percpu); | 2301 | percpu_modfree(percpu); |
| @@ -2296,10 +2313,8 @@ static noinline struct module *load_module(void __user *umod, | |||
| 2296 | } | 2313 | } |
| 2297 | 2314 | ||
| 2298 | /* This is where the real work happens */ | 2315 | /* This is where the real work happens */ |
| 2299 | asmlinkage long | 2316 | SYSCALL_DEFINE3(init_module, void __user *, umod, |
| 2300 | sys_init_module(void __user *umod, | 2317 | unsigned long, len, const char __user *, uargs) |
| 2301 | unsigned long len, | ||
| 2302 | const char __user *uargs) | ||
| 2303 | { | 2318 | { |
| 2304 | struct module *mod; | 2319 | struct module *mod; |
| 2305 | int ret = 0; | 2320 | int ret = 0; |
