Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus
* git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus:
module: fix refptr allocation and release order
diff --git a/kernel/module.c b/kernel/module.c
index ba22484..1196f5d 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2015,14 +2015,6 @@
if (err < 0)
goto free_mod;
-#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
- mod->refptr = percpu_modalloc(sizeof(local_t), __alignof__(local_t),
- mod->name);
- if (!mod->refptr) {
- err = -ENOMEM;
- goto free_mod;
- }
-#endif
if (pcpuindex) {
/* We have a special allocation for this section. */
percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size,
@@ -2030,7 +2022,7 @@
mod->name);
if (!percpu) {
err = -ENOMEM;
- goto free_percpu;
+ goto free_mod;
}
sechdrs[pcpuindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
mod->percpu = percpu;
@@ -2082,6 +2074,14 @@
/* Module has been moved. */
mod = (void *)sechdrs[modindex].sh_addr;
+#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
+ mod->refptr = percpu_modalloc(sizeof(local_t), __alignof__(local_t),
+ mod->name);
+ if (!mod->refptr) {
+ err = -ENOMEM;
+ goto free_init;
+ }
+#endif
/* Now we've moved module, initialize linked lists, etc. */
module_unload_init(mod);
@@ -2288,15 +2288,17 @@
ftrace_release(mod->module_core, mod->core_size);
free_unload:
module_unload_free(mod);
- module_free(mod, mod->module_init);
- free_core:
- module_free(mod, mod->module_core);
- free_percpu:
- if (percpu)
- percpu_modfree(percpu);
+ free_init:
#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
percpu_modfree(mod->refptr);
#endif
+ module_free(mod, mod->module_init);
+ free_core:
+ module_free(mod, mod->module_core);
+ /* mod will be freed with core. Don't access it beyond this line! */
+ free_percpu:
+ if (percpu)
+ percpu_modfree(percpu);
free_mod:
kfree(args);
free_hdr: