Message ID | 1456324115-21144-1-git-send-email-mpe@ellerman.id.au (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
On 25/02/16 01:28, Michael Ellerman wrote: > Currently we generate the module stub for ftrace_caller() at the bottom > of apply_relocate_add(). However apply_relocate_add() is potentially > called more than once per module, which means we will try to generate > the ftrace_caller() stub multiple times. This makes sense Reviewed-by: Balbir Singh <bsingharora@gmail.com>
On 25/02/16 10:55, Balbir Singh wrote: > > On 25/02/16 01:28, Michael Ellerman wrote: >> Currently we generate the module stub for ftrace_caller() at the bottom >> of apply_relocate_add(). However apply_relocate_add() is potentially >> called more than once per module, which means we will try to generate >> the ftrace_caller() stub multiple times. > This makes sense > Reviewed-by: Balbir Singh <bsingharora@gmail.com> For the entire series also Tested-by: Balbir Singh <bsingharora@gmail.com>
On Thu, Feb 25, 2016 at 01:28:24AM +1100, Michael Ellerman wrote: > Currently we generate the module stub for ftrace_caller() at the bottom > of apply_relocate_add(). However apply_relocate_add() is potentially > called more than once per module, which means we will try to generate > the ftrace_caller() stub multiple times. > > Although the current code deals with that correctly, ie. it only > generates a stub the first time, it would be clearer to only try to > generate the stub once. > > Note also on first reading it may appear that we generate a different > stub for each section that requires relocation, but that is not the > case. The code in stub_for_addr() that searches for an existing stub > uses sechdrs[me->arch.stubs_section], ie. the single stub section for > this module. > > A cleaner approach is to only generate the ftrace_caller() stub once, > from module_finalize(). An additional benefit is we can clean the ifdefs > up a little. > > Finally we must propagate the const'ness of some of the pointers passed > to module_finalize(), but that is also an improvement. > > Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Reviewed-by: Torsten Duwe <duwe@suse.de> Torsten
* Michael Ellerman <mpe@ellerman.id.au> [2016-02-25 01:28:24]: > Currently we generate the module stub for ftrace_caller() at the bottom > of apply_relocate_add(). However apply_relocate_add() is potentially > called more than once per module, which means we will try to generate > the ftrace_caller() stub multiple times. > > Although the current code deals with that correctly, ie. it only > generates a stub the first time, it would be clearer to only try to > generate the stub once. > > Note also on first reading it may appear that we generate a different > stub for each section that requires relocation, but that is not the > case. The code in stub_for_addr() that searches for an existing stub > uses sechdrs[me->arch.stubs_section], ie. the single stub section for > this module. > > A cleaner approach is to only generate the ftrace_caller() stub once, > from module_finalize(). An additional benefit is we can clean the ifdefs > up a little. > > Finally we must propagate the const'ness of some of the pointers passed > to module_finalize(), but that is also an improvement. > > Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> For all of the patches in the series. Tested-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com> Regards, Kamalesh.
diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h index dcfcad139bcc..74d25a749018 100644 --- a/arch/powerpc/include/asm/module.h +++ b/arch/powerpc/include/asm/module.h @@ -82,6 +82,15 @@ bool is_module_trampoline(u32 *insns); int module_trampoline_target(struct module *mod, u32 *trampoline, unsigned long *target); +#ifdef CONFIG_DYNAMIC_FTRACE +int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sechdrs); +#else +static inline int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sechdrs) +{ + return 0; +} +#endif + struct exception_table_entry; void sort_ex_table(struct exception_table_entry *start, struct exception_table_entry *finish); diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c index 9547381b631a..d1f1b35bf0c7 100644 --- a/arch/powerpc/kernel/module.c +++ b/arch/powerpc/kernel/module.c @@ -47,6 +47,11 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) { const Elf_Shdr *sect; + int rc; + + rc = module_finalize_ftrace(me, sechdrs); + if (rc) + return rc; /* Apply feature fixups */ sect = find_section(hdr, sechdrs, "__ftr_fixup"); diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c index 2c01665eb410..98f698f10956 100644 --- a/arch/powerpc/kernel/module_32.c +++ b/arch/powerpc/kernel/module_32.c @@ -294,11 +294,16 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, return -ENOEXEC; } } + + return 0; +} + #ifdef CONFIG_DYNAMIC_FTRACE - module->arch.tramp = - do_plt_call(module->core_layout.base, - (unsigned long)ftrace_caller, - sechdrs, module); -#endif +int module_finalize_ftrace(struct module *module, const Elf_Shdr *sechdrs) +{ + module->arch.tramp = do_plt_call(module->core_layout.base, + (unsigned long)ftrace_caller, + sechdrs, module); return 0; } +#endif diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index ac64ffdb52c8..599c753c7960 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c @@ -413,7 +413,7 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr, /* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this gives the value maximum span in an instruction which uses a signed offset) */ -static inline unsigned long my_r2(Elf64_Shdr *sechdrs, struct module *me) +static inline unsigned long my_r2(const Elf64_Shdr *sechdrs, struct module *me) { return sechdrs[me->arch.toc_section].sh_addr + 0x8000; } @@ -426,7 +426,7 @@ static inline unsigned long my_r2(Elf64_Shdr *sechdrs, struct module *me) #define PPC_HA(v) PPC_HI ((v) + 0x8000) /* Patch stub to reference function and correct r2 value. */ -static inline int create_stub(Elf64_Shdr *sechdrs, +static inline int create_stub(const Elf64_Shdr *sechdrs, struct ppc64_stub_entry *entry, unsigned long addr, struct module *me) @@ -452,7 +452,7 @@ static inline int create_stub(Elf64_Shdr *sechdrs, /* Create stub to jump to function described in this OPD/ptr: we need the stub to set up the TOC ptr (r2) for the function. */ -static unsigned long stub_for_addr(Elf64_Shdr *sechdrs, +static unsigned long stub_for_addr(const Elf64_Shdr *sechdrs, unsigned long addr, struct module *me) { @@ -693,12 +693,18 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, } } + return 0; +} + #ifdef CONFIG_DYNAMIC_FTRACE - me->arch.toc = my_r2(sechdrs, me); - me->arch.tramp = stub_for_addr(sechdrs, - (unsigned long)ftrace_caller, - me); -#endif +int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sechdrs) +{ + mod->arch.toc = my_r2(sechdrs, mod); + mod->arch.tramp = stub_for_addr(sechdrs, (unsigned long)ftrace_caller, mod); + + if (!mod->arch.tramp) + return -ENOENT; return 0; } +#endif
Currently we generate the module stub for ftrace_caller() at the bottom of apply_relocate_add(). However apply_relocate_add() is potentially called more than once per module, which means we will try to generate the ftrace_caller() stub multiple times. Although the current code deals with that correctly, ie. it only generates a stub the first time, it would be clearer to only try to generate the stub once. Note also on first reading it may appear that we generate a different stub for each section that requires relocation, but that is not the case. The code in stub_for_addr() that searches for an existing stub uses sechdrs[me->arch.stubs_section], ie. the single stub section for this module. A cleaner approach is to only generate the ftrace_caller() stub once, from module_finalize(). An additional benefit is we can clean the ifdefs up a little. Finally we must propagate the const'ness of some of the pointers passed to module_finalize(), but that is also an improvement. Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> --- arch/powerpc/include/asm/module.h | 9 +++++++++ arch/powerpc/kernel/module.c | 5 +++++ arch/powerpc/kernel/module_32.c | 15 ++++++++++----- arch/powerpc/kernel/module_64.c | 22 ++++++++++++++-------- 4 files changed, 38 insertions(+), 13 deletions(-)