X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=kernel%2Fmodule.c;h=cab4bce49c23dbe3779d02db8259dda28b7b4258;hb=91e14b294f3fe4d8b28516b21ceef187ea9b1bdf;hp=10a3af821d2863c105a43e4ab3dc9be34615a15f;hpb=bb0dddf6157bc679de9143507375fce3f13fcd00;p=firefly-linux-kernel-4.4.55.git diff --git a/kernel/module.c b/kernel/module.c index 10a3af821d28..cab4bce49c23 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2927,6 +2927,7 @@ static struct module *layout_and_allocate(struct load_info *info, int flags) { /* Module within temporary copy. */ struct module *mod; + Elf_Shdr *pcpusec; int err; mod = setup_load_info(info, flags); @@ -2941,10 +2942,17 @@ static struct module *layout_and_allocate(struct load_info *info, int flags) err = module_frob_arch_sections(info->hdr, info->sechdrs, info->secstrings, mod); if (err < 0) - return ERR_PTR(err); + goto out; - /* We will do a special allocation for per-cpu sections later. */ - info->sechdrs[info->index.pcpu].sh_flags &= ~(unsigned long)SHF_ALLOC; + pcpusec = &info->sechdrs[info->index.pcpu]; + if (pcpusec->sh_size) { + /* We have a special allocation for this section. */ + err = percpu_modalloc(mod, + pcpusec->sh_size, pcpusec->sh_addralign); + if (err) + goto out; + pcpusec->sh_flags &= ~(unsigned long)SHF_ALLOC; + } /* Determine total sizes, and put offsets in sh_entsize. For now this is done generically; there doesn't appear to be any @@ -2955,22 +2963,17 @@ static struct module *layout_and_allocate(struct load_info *info, int flags) /* Allocate and move to the final place */ err = move_module(mod, info); if (err) - return ERR_PTR(err); + goto free_percpu; /* Module has been copied to its final place now: return it. */ mod = (void *)info->sechdrs[info->index.mod].sh_addr; kmemleak_load_module(mod, info); return mod; -} - -static int alloc_module_percpu(struct module *mod, struct load_info *info) -{ - Elf_Shdr *pcpusec = &info->sechdrs[info->index.pcpu]; - if (!pcpusec->sh_size) - return 0; - /* We have a special allocation for this section. */ - return percpu_modalloc(mod, pcpusec->sh_size, pcpusec->sh_addralign); +free_percpu: + percpu_modfree(mod); +out: + return ERR_PTR(err); } /* mod is no longer valid after this! */ @@ -3234,11 +3237,6 @@ static int load_module(struct load_info *info, const char __user *uargs, } #endif - /* To avoid stressing percpu allocator, do this once we're unique. */ - err = alloc_module_percpu(mod, info); - if (err) - goto unlink_mod; - /* Now module is in final location, initialize linked lists, etc. */ err = module_unload_init(mod); if (err) @@ -3279,9 +3277,6 @@ static int load_module(struct load_info *info, const char __user *uargs, dynamic_debug_setup(info->debug, info->num_debug); - /* Ftrace init must be called in the MODULE_STATE_UNFORMED state */ - ftrace_module_init(mod); - /* Finally it's fully formed, ready to start executing. */ err = complete_formation(mod, info); if (err)