diff options
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/kernel/module.c b/kernel/module.c index 8b742f2b3845..7fa134e0cc24 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -2049,14 +2049,6 @@ static noinline struct module *load_module(void __user *umod, | |||
2049 | if (err < 0) | 2049 | if (err < 0) |
2050 | goto free_mod; | 2050 | goto free_mod; |
2051 | 2051 | ||
2052 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) | ||
2053 | mod->refptr = percpu_modalloc(sizeof(local_t), __alignof__(local_t), | ||
2054 | mod->name); | ||
2055 | if (!mod->refptr) { | ||
2056 | err = -ENOMEM; | ||
2057 | goto free_mod; | ||
2058 | } | ||
2059 | #endif | ||
2060 | if (pcpuindex) { | 2052 | if (pcpuindex) { |
2061 | /* We have a special allocation for this section. */ | 2053 | /* We have a special allocation for this section. */ |
2062 | percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size, | 2054 | percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size, |
@@ -2064,7 +2056,7 @@ static noinline struct module *load_module(void __user *umod, | |||
2064 | mod->name); | 2056 | mod->name); |
2065 | if (!percpu) { | 2057 | if (!percpu) { |
2066 | err = -ENOMEM; | 2058 | err = -ENOMEM; |
2067 | goto free_percpu; | 2059 | goto free_mod; |
2068 | } | 2060 | } |
2069 | sechdrs[pcpuindex].sh_flags &= ~(unsigned long)SHF_ALLOC; | 2061 | sechdrs[pcpuindex].sh_flags &= ~(unsigned long)SHF_ALLOC; |
2070 | mod->percpu = percpu; | 2062 | mod->percpu = percpu; |
@@ -2116,6 +2108,14 @@ static noinline struct module *load_module(void __user *umod, | |||
2116 | /* Module has been moved. */ | 2108 | /* Module has been moved. */ |
2117 | mod = (void *)sechdrs[modindex].sh_addr; | 2109 | mod = (void *)sechdrs[modindex].sh_addr; |
2118 | 2110 | ||
2111 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) | ||
2112 | mod->refptr = percpu_modalloc(sizeof(local_t), __alignof__(local_t), | ||
2113 | mod->name); | ||
2114 | if (!mod->refptr) { | ||
2115 | err = -ENOMEM; | ||
2116 | goto free_init; | ||
2117 | } | ||
2118 | #endif | ||
2119 | /* Now we've moved module, initialize linked lists, etc. */ | 2119 | /* Now we've moved module, initialize linked lists, etc. */ |
2120 | module_unload_init(mod); | 2120 | module_unload_init(mod); |
2121 | 2121 | ||
@@ -2322,15 +2322,17 @@ static noinline struct module *load_module(void __user *umod, | |||
2322 | ftrace_release(mod->module_core, mod->core_size); | 2322 | ftrace_release(mod->module_core, mod->core_size); |
2323 | free_unload: | 2323 | free_unload: |
2324 | module_unload_free(mod); | 2324 | module_unload_free(mod); |
2325 | free_init: | ||
2326 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) | ||
2327 | percpu_modfree(mod->refptr); | ||
2328 | #endif | ||
2325 | module_free(mod, mod->module_init); | 2329 | module_free(mod, mod->module_init); |
2326 | free_core: | 2330 | free_core: |
2327 | module_free(mod, mod->module_core); | 2331 | module_free(mod, mod->module_core); |
2332 | /* mod will be freed with core. Don't access it beyond this line! */ | ||
2328 | free_percpu: | 2333 | free_percpu: |
2329 | if (percpu) | 2334 | if (percpu) |
2330 | percpu_modfree(percpu); | 2335 | percpu_modfree(percpu); |
2331 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) | ||
2332 | percpu_modfree(mod->refptr); | ||
2333 | #endif | ||
2334 | free_mod: | 2336 | free_mod: |
2335 | kfree(args); | 2337 | kfree(args); |
2336 | free_hdr: | 2338 | free_hdr: |