powerpc/ftrace: Move ftrace sequence out of line
v2 cover powerpc/ftrace: Move ftrace sequence out of line
This is v2 of the series posted here:
http://lkml.kernel.org/r/[email protected]
Since v2, the primary change is that the entire ftrace sequence is moved out of line and this is now restricted to 64-bit powerpc by default. Patch 5 has the details.
I have dropped patches to enable DYNAMIC_FTRACE_WITH_CALL_OPS and ftrace direct support so that this approach can be finalized.
This series depends on Benjamin Gray's series adding support for patch_ulong():
http://lkml.kernel.org/r/[email protected]
Appreciate feedback on the approach.
Thanks,
Naveen
Naveen N Rao (5):
powerpc/kprobes: Use ftrace to determine if a probe is at function
entry
powerpc/ftrace: Remove pointer to struct module from dyn_arch_ftrace powerpc/ftrace: Unify 32-bit and 64-bit ftrace entry code
kbuild: Add generic hook for architectures to use before the final
vmlinux link
powerpc64/ftrace: Move ftrace sequence out of line
arch/Kconfig | 3 + arch/powerpc/Kconfig | 4 + arch/powerpc/Makefile | 4 + arch/powerpc/include/asm/ftrace.h | 11 +- arch/powerpc/include/asm/module.h | 5 + arch/powerpc/kernel/asm-offsets.c | 4 + arch/powerpc/kernel/kprobes.c | 18 +-- arch/powerpc/kernel/module_64.c | 67 +++++++- arch/powerpc/kernel/trace/ftrace.c | 196 ++++++++++++++++++++--- arch/powerpc/kernel/trace/ftrace_64_pg.c | 73 ++++----- arch/powerpc/kernel/trace/ftrace_entry.S | 75 ++++++--- arch/powerpc/kernel/vmlinux.lds.S | 3 +- arch/powerpc/tools/vmlinux_o.sh | 47 ++++++ scripts/link-vmlinux.sh | 18 ++- 14 files changed, 419 insertions(+), 109 deletions(-) create mode 100755 arch/powerpc/tools/vmlinux_o.sh
base-commit: 2c644f2847c188b4fa545e602e4a1d4db55e8c8d
prerequisite-patch-id: a1d50e589288239d5a8b1c1f354cd4737057c9d3
prerequisite-patch-id: da4142d56880861bd0ad7ad7087c9e2670a2ee54
prerequisite-patch-id: 609d292e054b2396b603890522a940fa0bdfb6d8
prerequisite-patch-id: 6f7213fb77b1260defbf43be0e47bff9c80054cc
prerequisite-patch-id: ad3b71bf071ae4ba1bee5b087e61a2055772a74f
Signature · 1 line
2.45.2
RFC PATCH v2 1/5 powerpc/kprobes: Use ftrace to determine if a probe is at function entry
Rather than hard-coding the offset into a function to be used to determine if a kprobe is at function entry, use ftrace_location() to determine the ftrace location within the function and categorize all instructions till that offset to be function entry.
For functions that cannot be traced, we fall back to using a fixed offset of 8 (two instructions) to categorize a probe as being at function entry for 64-bit elfv2, unless we are using pcrel.
--- arch/powerpc/kernel/kprobes.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-)
arch/powerpc/kernel/kprobes.c +8 -10
@@ -105,24 +105,22 @@ kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset)return addr; } -static bool arch_kprobe_on_func_entry (unsigned long offset) +static bool arch_kprobe_on_func_entry (unsigned long addr,unsigned long offset) { -#ifdef CONFIG_PPC64_ELF_ABI_V2 -#ifdef CONFIG_KPROBES_ON_FTRACE -return offset <=16 ; -#else -return offset <=8 ; -#endif -#else +unsigned long ip =ftrace_location (addr); + +if (ip) +return offset <= (ip - addr); +if (IS_ENABLED (CONFIG_PPC64_ELF_ABI_V2 ) && !IS_ENABLED (CONFIG_PPC_KERNEL_PCREL )) +return offset <=8 ;return !offset; -#endif }/* XXX try and fold the magic of kprobe_lookup_name() in this */ kprobe_opcode_t *arch_adjust_kprobe_addr (unsigned long addr,unsigned long offset,bool *on_func_entry) { - *on_func_entry =arch_kprobe_on_func_entry (offset); + *on_func_entry =arch_kprobe_on_func_entry (addr, offset);return (kprobe_opcode_t *)(addr + offset); }
Signature · 1 line
2.45.2
RFC PATCH v2 2/5 powerpc/ftrace: Remove pointer to struct module from dyn_arch_ftrace
In reply to Naveen N RaoPointer to struct module is only relevant for ftrace records belonging to kernel modules. Having this field in dyn_arch_ftrace wastes memory for all ftrace records belonging to the kernel. Remove the same in favour of looking up the module from the ftrace record address, similar to other architectures.
--- arch/powerpc/include/asm/ftrace.h | 1 - arch/powerpc/kernel/trace/ftrace.c | 47 ++++++++++----- arch/powerpc/kernel/trace/ftrace_64_pg.c | 73 +++++++++++------------- 3 files changed, 64 insertions(+), 57 deletions(-)
arch/powerpc/include/asm/ftrace.h +0 -1
@@ -26,7 +26,6 @@ unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip,struct module ;struct dyn_ftrace ;struct dyn_arch_ftrace { -struct module *mod; };#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
arch/powerpc/kernel/trace/ftrace.c +32 -15
73 lines not on this page · raw message
arch/powerpc/kernel/trace/ftrace_64_pg.c +32 -41
115 lines not on this page · raw message
Signature · 1 line
2.45.2
Steven Rostedt
maintainerRe: [RFC PATCH v2 2/5] powerpc/ftrace: Remove pointer to struct module from dyn_arch_ftrace
Quoted 18 lines · On Mon, 10 Jun 2024 14:08:15 +0530 Naveen N Rao <[email protected]> wrote:
Pointer to struct module is only relevant for ftrace records belonging to kernel modules. Having this field in
dyn_arch_ftracewastes memory for all ftrace records belonging to the kernel. Remove the same in favour of looking up the module from the ftrace record address, similar to other architectures.Signed-off-by Naveen N Rao <[email protected]>--- arch/powerpc/include/asm/ftrace.h | 1 - arch/powerpc/kernel/trace/ftrace.c | 47 ++++++++++----- arch/powerpc/kernel/trace/ftrace_64_pg.c | 73 +++++++++++------------- 3 files changed, 64 insertions(+), 57 deletions(-)arch/powerpc/include/asm/ftrace.h +0
-0
arch/powerpc/include/asm/ftrace.h unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip, · line 29
Quoted 5 lines
arch/powerpc/include/asm/ftrace.h +0
-1@@ -26,7 +26,6 @@ unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip,struct module ;struct dyn_ftrace ;struct dyn_arch_ftrace { -struct module *mod; };
Nice. I always hated that extra field.
Quoted 20 lines
arch/powerpc/include/asm/ftrace.h +0
-0#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS arch/powerpc/kernel/trace/ftrace.c +10
-0@@ -106,20 +106,36 @@ static unsigned long find_ftrace_tramp(unsigned long ip)return 0 ; } +static struct module *ftrace_lookup_module (struct dyn_ftrace *rec) +{ +struct module *mod =NULL ; + +#ifdef CONFIG_MODULES +/* +* NOTE: __module_text_address() must be called with preemption +* disabled, but we can rely on ftrace_lock to ensure that 'mod' +* retains its validity throughout the remainder of this code. +*/
arch/powerpc/kernel/trace/ftrace.c static unsigned long find_ftrace_tramp(unsigned long ip) · line 128
Quoted 10 lines
arch/powerpc/kernel/trace/ftrace.c +10
-0+preempt_disable (); + mod =__module_text_address (rec->ip); +preempt_enable (); + +if (!mod) +pr_err ("No module loaded at addr=%lx\n" , rec->ip); +#endif + +return mod; +}
It may look nicer to have:
#ifdef CONFIG_MODULES
static struct module *ftrace_lookup_module(struct dyn_ftrace *rec)
{
struct module *mod = NULL;
/*
* NOTE: __module_text_address() must be called with preemption
* disabled, but we can rely on ftrace_lock to ensure that 'mod'
* retains its validity throughout the remainder of this code.
*/
preempt_disable();
mod = __module_text_address(rec->ip);
preempt_enable();
if (!mod)
pr_err("No module loaded at addr=%lx\n", rec->ip);
return mod;
}
#else
static inline struct module *ftrace_lookup_module(struct dyn_ftrace *rec)
{
return NULL;
}#endif
Quoted 21 lines
arch/powerpc/kernel/trace/ftrace.c +2
-6+static int ftrace_get_call_inst (struct dyn_ftrace *rec,unsigned long addr,ppc_inst_t *call_inst) {unsigned long ip = rec->ip;unsigned long stub; +struct module *mod;if (is_offset_in_branch_range (addr - ip)) {/* Within range */ stub = addr; -#ifdef CONFIG_MODULES - }else if (rec->arch.mod) { -/* Module code would be going to one of the module stubs */ - stub = (addr == (unsigned long )ftrace_caller ? rec->arch.mod->arch.tramp : - rec->arch.mod->arch.tramp_regs); -#endif }else if (core_kernel_text (ip)) {/* We would be branching to one of our ftrace stubs */ stub =find_ftrace_tramp (ip);@@ -128,7 +144,16 @@ static int ftrace_get_call_inst(struct dyn_ftrace *rec, unsigned long addr, ppc_return -EINVAL ;
arch/powerpc/kernel/trace/ftrace.c static int ftrace_get_call_inst(struct dyn_ftrace *rec, unsigned long addr, ppc_ · line 153
Quoted 10 lines
arch/powerpc/kernel/trace/ftrace.c +7
-1} }else { -return -EINVAL ; + mod =ftrace_lookup_module (rec); +if (mod) { +#ifdef CONFIG_MODULES +/* Module code would be going to one of the module stubs */ + stub = (addr == (unsigned long )ftrace_caller ? mod->arch.tramp : + mod->arch.tramp_regs); +#endif
You have CONFIG_MODULES here and in ftrace_lookup_module() above, which would always return NULL. Could you combine the above to be done in ftrace_lookup_module() so that there's no #ifdef CONFIG_MODULES here?
Quoted 11 lines
arch/powerpc/kernel/trace/ftrace.c +3
-1+ }else { +return -EINVAL ; + } } *call_inst =ftrace_create_branch_inst (ip, stub,1 );@@ -256,14 +281,6 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)if (ret)return ret; -if (!core_kernel_text (ip)) {
arch/powerpc/kernel/trace/ftrace.c int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec) · line 286
Quoted 10 lines
arch/powerpc/kernel/trace/ftrace.c +0
-7-if (!mod) { -pr_err ("0x%lx: No module provided for non-kernel address\n" , ip); -return -EFAULT ; - } - rec->arch.mod = mod; - } -/* Nop-out the ftrace location */ new =ppc_inst (PPC_RAW_NOP ()); addr =MCOUNT_ADDR ;
-- Steve
Re: [RFC PATCH v2 2/5] powerpc/ftrace: Remove pointer to struct module from dyn_arch_ftrace
Quoted 16 lines · Steven Rostedt
Quoted 13 lines · On Mon, 10 Jun 2024 14:08:15 +0530 Naveen N Rao <[email protected]> wrote:
Pointer to struct module is only relevant for ftrace records belonging to kernel modules. Having this field in
dyn_arch_ftracewastes memory for all ftrace records belonging to the kernel. Remove the same in favour of looking up the module from the ftrace record address, similar to other architectures.Signed-off-by Naveen N Rao <[email protected]>--- arch/powerpc/include/asm/ftrace.h | 1 - arch/powerpc/kernel/trace/ftrace.c | 47 ++++++++++----- arch/powerpc/kernel/trace/ftrace_64_pg.c | 73 +++++++++++------------- 3 files changed, 64 insertions(+), 57 deletions(-)
Quoted 12 lines
arch/powerpc/include/asm/ftrace.h unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip, · line 29
Quoted 10 lines
arch/powerpc/include/asm/ftrace.h +0
-1@@ -26,7 +26,6 @@ unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip,struct module ;struct dyn_ftrace ;struct dyn_arch_ftrace { -struct module *mod; };Nice. I always hated that extra field.
It was your complaint a while back that prompted this change :)
Though I introduce a different pointer here in the next patch. /me ducks.
Quoted 59 lines
Quoted 22 lines
arch/powerpc/include/asm/ftrace.h +0
-0#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS arch/powerpc/kernel/trace/ftrace.c +10
-0@@ -106,20 +106,36 @@ static unsigned long find_ftrace_tramp(unsigned long ip)return 0 ; } +static struct module *ftrace_lookup_module (struct dyn_ftrace *rec) +{ +struct module *mod =NULL ; + +#ifdef CONFIG_MODULES +/* +* NOTE: __module_text_address() must be called with preemption +* disabled, but we can rely on ftrace_lock to ensure that 'mod' +* retains its validity throughout the remainder of this code. +*/ arch/powerpc/kernel/trace/ftrace.c static unsigned long find_ftrace_tramp(unsigned long ip) · line 128
Quoted 10 lines
arch/powerpc/kernel/trace/ftrace.c +10
-0+preempt_disable (); + mod =__module_text_address (rec->ip); +preempt_enable (); + +if (!mod) +pr_err ("No module loaded at addr=%lx\n" , rec->ip); +#endif + +return mod; +}It may look nicer to have:
#ifdef
CONFIG_MODULES
static struct module *ftrace_lookup_module(structdyn_ftrace*rec){ struct module *mod = NULL; /* * NOTE: __module_text_address() must be called with preemption * disabled, but we can rely on ftrace_lock to ensure that 'mod' * retains its validity throughout the remainder of this code. */ preempt_disable(); mod = __module_text_address(rec->ip); preempt_enable(); if (!mod) pr_err("No module loaded at addr=%lx\n", rec->ip); return mod; } #else static inline struct module *ftrace_lookup_module(struct dyn_ftrace *rec) { return NULL; }
Quoted 1 line
#endif
I wrote this, and then I thought it will be simpler to do the version I posted. I will move back to this since it looks to be the preferred way.
Quoted 28 lines
Quoted 28 lines
arch/powerpc/kernel/trace/ftrace.c +5
-7+static int ftrace_get_call_inst (struct dyn_ftrace *rec,unsigned long addr,ppc_inst_t *call_inst) {unsigned long ip = rec->ip;unsigned long stub; +struct module *mod;if (is_offset_in_branch_range (addr - ip)) {/* Within range */ stub = addr; -#ifdef CONFIG_MODULES - }else if (rec->arch.mod) { -/* Module code would be going to one of the module stubs */ - stub = (addr == (unsigned long )ftrace_caller ? rec->arch.mod->arch.tramp : - rec->arch.mod->arch.tramp_regs); -#endif }else if (core_kernel_text (ip)) {/* We would be branching to one of our ftrace stubs */ stub =find_ftrace_tramp (ip);@@ -128,7 +144,16 @@ static int ftrace_get_call_inst(struct dyn_ftrace *rec, unsigned long addr, ppc_return -EINVAL ; } }else { -return -EINVAL ; + mod =ftrace_lookup_module (rec); +if (mod) { +#ifdef CONFIG_MODULES
Quoted 8 lines
arch/powerpc/kernel/trace/ftrace.c static int ftrace_get_call_inst(struct dyn_ftrace *rec, unsigned long addr, ppc_ · line 153
Quoted 4 lines
arch/powerpc/kernel/trace/ftrace.c +4
-0+/* Module code would be going to one of the module stubs */ + stub = (addr == (unsigned long )ftrace_caller ? mod->arch.tramp : + mod->arch.tramp_regs); +#endif You have
CONFIG_MODULEShere and inftrace_lookup_module()above, which would always return NULL. Could you combine the above to be done inftrace_lookup_module()so that there's no #ifdefCONFIG_MODULEShere?
Yes, indeed. That will look cleaner.
Thanks,
Naveen
RFC PATCH v2 3/5 powerpc/ftrace: Unify 32-bit and 64-bit ftrace entry code
In reply to Naveen N RaoOn 32-bit powerpc, gcc generates a three instruction sequence for function profiling:
mflr r0 stw r0, 4(r1) bl _mcount
On kernel boot, the call to _mcount() is nop-ed out, to be patched back in when ftrace is actually enabled. The 'stw' instruction therefore is not necessary unless ftrace is enabled. Nop it out during ftrace init.
When ftrace is enabled, we want the 'stw' so that stack unwinding works properly. Perform the same within the ftrace handler, similar to 64-bit powerpc.
For 64-bit powerpc, early versions of gcc used to emit a three instruction sequence for function profiling (with -mprofile-kernel) with a 'std' instruction to mimic the 'stw' above. Address that scenario also by nop-ing out the 'std' instruction during ftrace init.
--- arch/powerpc/kernel/trace/ftrace.c | 6 ++++-- arch/powerpc/kernel/trace/ftrace_entry.S | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-)
arch/powerpc/kernel/trace/ftrace.c +4 -2
@@ -266,13 +266,15 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)/* Expected sequence: 'mflr r0', 'stw r0,4(r1)', 'bl _mcount' */ ret =ftrace_validate_inst (ip -8 ,ppc_inst (PPC_RAW_MFLR (_R0)));if (!ret) - ret =ftrace_validate_inst (ip -4 ,ppc_inst (PPC_RAW_STW (_R0, _R1,4 ))); + ret =ftrace_modify_code (ip -4 ,ppc_inst (PPC_RAW_STW (_R0, _R1,4 )), +ppc_inst (PPC_RAW_NOP ())); }else if (IS_ENABLED (CONFIG_MPROFILE_KERNEL )) {/* Expected sequence: 'mflr r0', ['std r0,16(r1)'], 'bl _mcount' */ ret =ftrace_read_inst (ip -4 , &old);if (!ret && !ppc_inst_equal (old,ppc_inst (PPC_RAW_MFLR (_R0)))) { ret =ftrace_validate_inst (ip -8 ,ppc_inst (PPC_RAW_MFLR (_R0))); - ret |=ftrace_validate_inst (ip -4 ,ppc_inst (PPC_RAW_STD (_R0, _R1,16 ))); + ret |=ftrace_modify_code (ip -4 ,ppc_inst (PPC_RAW_STD (_R0, _R1,16 )), +ppc_inst (PPC_RAW_NOP ())); } }else {return -EINVAL ;
arch/powerpc/kernel/trace/ftrace_entry.S +2 -2
@@ -33,6 +33,8 @@ * and then arrange for the ftrace function to be called. */ .macro ftrace_regs_entry allregs + /* Save the original return address in A's stack frame */ + PPC_STL r0, LRSAVE(r1) /* Create a minimal stack frame for representing B */ PPC_STLU r1, -STACK_FRAME_MIN_SIZE(r1)
@@ -44,8 +46,6 @@ SAVE_GPRS(3, 10, r1) #ifdef CONFIG_PPC64 - /* Save the original return address in A's stack frame */ - std r0, LRSAVE+SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE(r1) /* Ok to continue? */ lbz r3, PACA_FTRACE_ENABLED(r13) cmpdi r3, 0
Signature · 1 line
2.45.2
Steven Rostedt
maintainerRe: [RFC PATCH v2 3/5] powerpc/ftrace: Unify 32-bit and 64-bit ftrace entry code
Quoted 14 lines · On Mon, 10 Jun 2024 14:08:16 +0530 Naveen N Rao <[email protected]> wrote:
On 32-bit powerpc, gcc generates a three instruction sequence for function profiling:
mflr r0 stw r0, 4(r1) bl _mcountOn kernel boot, the call to
_mcount()is nop-ed out, to be patched back in when ftrace is actually enabled. The 'stw' instruction therefore is not necessary unless ftrace is enabled. Nop it out during ftrace init.When ftrace is enabled, we want the 'stw' so that stack unwinding works properly. Perform the same within the ftrace handler, similar to 64-bit powerpc.
Quoted 6 lines
For 64-bit powerpc, early versions of gcc used to emit a three instruction sequence for function profiling (with -mprofile-kernel) with a 'std' instruction to mimic the 'stw' above. Address that scenario also by nop-ing out the 'std' instruction during ftrace init.
Signed-off-by Naveen N Rao <[email protected]>
Isn't there still the race that there's a preemption between the:
stw r0, 4(r1)
and
bl _mcount
And if this breaks stack unwinding, couldn't this cause an issue for live kernel patching?
I know it's very unlikely, but in theory, I think the race exists.
-- Steve
Re: [RFC PATCH v2 3/5] powerpc/ftrace: Unify 32-bit and 64-bit ftrace entry code
Quoted 26 lines · Steven Rostedt
Quoted 14 lines · On Mon, 10 Jun 2024 14:08:16 +0530 Naveen N Rao <[email protected]> wrote:
On 32-bit powerpc, gcc generates a three instruction sequence for function profiling:
mflr r0 stw r0, 4(r1) bl _mcountOn kernel boot, the call to
_mcount()is nop-ed out, to be patched back in when ftrace is actually enabled. The 'stw' instruction therefore is not necessary unless ftrace is enabled. Nop it out during ftrace init.When ftrace is enabled, we want the 'stw' so that stack unwinding works properly. Perform the same within the ftrace handler, similar to 64-bit powerpc.
Quoted 6 lines
For 64-bit powerpc, early versions of gcc used to emit a three instruction sequence for function profiling (with -mprofile-kernel) with a 'std' instruction to mimic the 'stw' above. Address that scenario also by nop-ing out the 'std' instruction during ftrace init.
Signed-off-by Naveen N Rao <[email protected]>Isn't there still the race that there's a preemption between the:
Quoted 8 lines
stw r0, 4(r1)and
bl_mcountAnd if this breaks stack unwinding, couldn't this cause an issue for live kernel patching?
I know it's very unlikely, but in theory, I think the race exists.
I *think* you are assuming that we will be patching back the 'stw' instruction here? So, there could be an issue if a cpu has executed the nop instead of 'stw' and then sees the call to _mcount().
But, we don't patch back the 'stw' instruction. That is instead done as part of ftrace_caller(), along with setting up an additional stack frame to ensure reliable stack unwinding. Commit 41a506ef71eb ("powerpc/ftrace: Create a dummy stackframe to fix stack unwind") has more details.
The primary motivation for this patch is to address differences in the function profile sequence with various toolchains. Since commit 0f71dcfb4aef ("powerpc/ftrace: Add support for -fpatchable-function-entry"), we use the same two-instruction profile sequence across 32-bit and 64-bit powerpc:
mflr r0 bl ftrace_caller
This has also been true on 64-bit powerpc with -mprofile-kernel, except the very early versions of gcc that supported that option (gcc v5).
On 32-bit powerpc, we used to use the three instruction sequence before support for -fpatchable-function-entry was introduced.
In this patch, we move all toolchain variants to use the two-instruction sequence for consistency.
Thanks,
Naveen
Steven Rostedt
maintainerRe: [RFC PATCH v2 3/5] powerpc/ftrace: Unify 32-bit and 64-bit ftrace entry code
Quoted 3 lines · On Tue, 11 Jun 2024 20:17:19 +0530 Naveen N Rao <[email protected]> wrote:
Quoted 1 line
I know it's very unlikely, but in theory, I think the race exists.
I *think* you are assuming that we will be patching back the 'stw'
Yes, that was what I was assuming :-p
Quoted 17 lines
instruction here? So, there could be an issue if a cpu has executed the nop instead of 'stw' and then sees the call to
_mcount().But, we don't patch back the 'stw' instruction. That is instead done as part of
ftrace_caller(), along with setting up an additional stack frame to ensure reliable stack unwinding. Commit41a506ef71eb("powerpc/ftrace: Create a dummy stackframe to fix stack unwind") has more details.The primary motivation for this patch is to address differences in the function profile sequence with various toolchains. Since commit
0f71dcfb4aef("powerpc/ftrace: Add support for -fpatchable-function-entry"), we use the same two-instruction profile sequence across 32-bit and 64-bit powerpc:mflr r0 bl ftrace_caller
Quoted 8 lines
This has also been true on 64-bit powerpc with -mprofile-kernel, except the very early versions of gcc that supported that option (gcc v5).
On 32-bit powerpc, we used to use the three instruction sequence before support for -fpatchable-function-entry was introduced.
In this patch, we move all toolchain variants to use the two-instruction sequence for consistency.
OK, if you are not patching that back, then all should be good.
-- Steve
RFC PATCH v2 4/5 kbuild: Add generic hook for architectures to use before the final vmlinux link
In reply to Naveen N RaoOn powerpc, we would like to be able to make a pass on vmlinux.o and generate a new object file to be linked into vmlinux. Add a generic pass in link-vmlinux.sh that architectures can use for this purpose. Architectures need to select CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX and must provide arch/<arch>/tools/vmlinux_o.sh, which will be invoked prior to the final vmlinux link step.
--- arch/Kconfig | 3 +++ scripts/link-vmlinux.sh | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-)
arch/Kconfig +3 -0
@@ -1643,4 +1643,7 @@ config CC_HAS_SANE_FUNCTION_ALIGNMENT config ARCH_NEED_CMPXCHG_1_EMU bool +config ARCH_WANTS_PRE_LINK_VMLINUX + def_bool n + endmenu
scripts/link-vmlinux.sh +15 -3
@@ -122,7 +122,7 @@ gen_btf() return 1 fi - vmlinux_link ${1} + vmlinux_link ${1} ${arch_vmlinux_o} info "BTF" ${2} LLVM_OBJCOPY="${OBJCOPY}" ${PAHOLE} -J ${PAHOLE_FLAGS} ${1}
@@ -178,7 +178,7 @@ kallsyms_step() kallsymso=${kallsyms_vmlinux}.o kallsyms_S=${kallsyms_vmlinux}.S - vmlinux_link ${kallsyms_vmlinux} "${kallsymso_prev}" ${btf_vmlinux_bin_o} + vmlinux_link ${kallsyms_vmlinux} "${kallsymso_prev}" ${btf_vmlinux_bin_o} ${arch_vmlinux_o} mksysmap ${kallsyms_vmlinux} ${kallsyms_vmlinux}.syms kallsyms ${kallsyms_vmlinux}.syms ${kallsyms_S}
@@ -203,6 +203,7 @@ sorttable() cleanup() { + rm -f .arch.vmlinux.* rm -f .btf.* rm -f System.map rm -f vmlinux
@@ -223,6 +224,17 @@ fi ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init init/version-timestamp.o +arch_vmlinux_o="" +if is_enabled CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX; then + arch_vmlinux_o=.arch.vmlinux.o + info "ARCH" ${arch_vmlinux_o} + if ! ${srctree}/arch/${SRCARCH}/tools/vmlinux_o.sh ${arch_vmlinux_o} ; then + echo >&2 "Failed to generate ${arch_vmlinux_o}" + echo >&2 "Try to disable CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX" + exit 1 + fi +fi + btf_vmlinux_bin_o="" if is_enabled CONFIG_DEBUG_INFO_BTF; then btf_vmlinux_bin_o=.btf.vmlinux.bin.o
@@ -273,7 +285,7 @@ if is_enabled CONFIG_KALLSYMS; then fi fi -vmlinux_link vmlinux "${kallsymso}" ${btf_vmlinux_bin_o} +vmlinux_link vmlinux "${kallsymso}" ${btf_vmlinux_bin_o} ${arch_vmlinux_o} # fill in BTF IDs if is_enabled CONFIG_DEBUG_INFO_BTF && is_enabled CONFIG_BPF; then
Signature · 1 line
2.45.2
Re: [RFC PATCH v2 4/5] kbuild: Add generic hook for architectures to use before the final vmlinux link
Quoted 60 lines · Naveen N Rao
On powerpc, we would like to be able to make a pass on vmlinux.o and generate a new object file to be linked into vmlinux. Add a generic pass in
link-vmlinux.shthat architectures can use for this purpose. Architectures need to selectCONFIG_ARCH_WANTS_PRE_LINK_VMLINUXand must provide arch/<arch>/tools/vmlinux_o.sh, which will be invoked prior to the final vmlinux link step.Signed-off-by Naveen N Rao <[email protected]>--- arch/Kconfig | 3 +++ scripts/link-vmlinux.sh | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-)arch/Kconfig +3
-0@@ -1643,4 +1643,7 @@ config CC_HAS_SANE_FUNCTION_ALIGNMENT config ARCH_NEED_CMPXCHG_1_EMU bool +config ARCH_WANTS_PRE_LINK_VMLINUX + def_bool n + endmenuscripts/link-vmlinux.sh +3
-2@@ -122,7 +122,7 @@ gen_btf() return 1 fi - vmlinux_link ${1} + vmlinux_link ${1} ${arch_vmlinux_o} info "BTF" ${2} LLVM_OBJCOPY="${OBJCOPY}" ${PAHOLE} -J ${PAHOLE_FLAGS} ${1}@@ -178,7 +178,7 @@ kallsyms_step() kallsymso=${kallsyms_vmlinux}.o kallsyms_S=${kallsyms_vmlinux}.S - vmlinux_link ${kallsyms_vmlinux} "${kallsymso_prev}" ${btf_vmlinux_bin_o} + vmlinux_link ${kallsyms_vmlinux} "${kallsymso_prev}" ${btf_vmlinux_bin_o} ${arch_vmlinux_o} mksysmap ${kallsyms_vmlinux} ${kallsyms_vmlinux}.syms kallsyms ${kallsyms_vmlinux}.syms ${kallsyms_S}@@ -203,6 +203,7 @@ sorttable() cleanup() { + rm -f .arch.vmlinux.* rm -f .btf.* rm -f System.map rm -f vmlinux@@ -223,6 +224,17 @@ fi ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init init/version-timestamp.o
scripts/link-vmlinux.sh fi · line 236
Quoted 10 lines
scripts/link-vmlinux.sh +10
-0+arch_vmlinux_o="" +if is_enabled CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX; then + arch_vmlinux_o=.arch.vmlinux.o + info "ARCH" ${arch_vmlinux_o} + if ! ${srctree}/arch/${SRCARCH}/tools/vmlinux_o.sh ${arch_vmlinux_o} ; then + echo >&2 "Failed to generate ${arch_vmlinux_o}" + echo >&2 "Try to disable CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX" + exit 1 + fi +fi
This is wrong because scripts/link-vmlinux.sh is not triggered even when source files under arch/powerpc/tools/ are changed.
Presumably, scripts/Makefile.vmlinux will be the right place.
Quoted 16 lines
scripts/link-vmlinux.sh +2
-2+ btf_vmlinux_bin_o="" if is_enabled CONFIG_DEBUG_INFO_BTF; then btf_vmlinux_bin_o=.btf.vmlinux.bin.o@@ -273,7 +285,7 @@ if is_enabled CONFIG_KALLSYMS; then fi fi -vmlinux_link vmlinux "${kallsymso}" ${btf_vmlinux_bin_o} +vmlinux_link vmlinux "${kallsymso}" ${btf_vmlinux_bin_o} ${arch_vmlinux_o} # fill in BTF IDs if is_enabled CONFIG_DEBUG_INFO_BTF && is_enabled CONFIG_BPF; then --2.45.2
Signature · 2 lines
Best Regards Masahiro Yamada
Re: [RFC PATCH v2 4/5] kbuild: Add generic hook for architectures to use before the final vmlinux link
Quoted 31 lines · Masahiro Yamada
Quoted 30 lines · Naveen N Rao
On powerpc, we would like to be able to make a pass on vmlinux.o and generate a new object file to be linked into vmlinux. Add a generic pass in
link-vmlinux.shthat architectures can use for this purpose. Architectures need to selectCONFIG_ARCH_WANTS_PRE_LINK_VMLINUXand must provide arch/<arch>/tools/vmlinux_o.sh, which will be invoked prior to the final vmlinux link step.Signed-off-by Naveen N Rao <[email protected]>--- arch/Kconfig | 3 +++ scripts/link-vmlinux.sh | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-)arch/Kconfig +3
-0@@ -1643,4 +1643,7 @@ config CC_HAS_SANE_FUNCTION_ALIGNMENT config ARCH_NEED_CMPXCHG_1_EMU bool +config ARCH_WANTS_PRE_LINK_VMLINUX + def_bool n + endmenuscripts/link-vmlinux.sh +0
-0
...
Quoted 17 lines
scripts/link-vmlinux.sh
Quoted 11 lines
scripts/link-vmlinux.sh +10
-0+arch_vmlinux_o="" +if is_enabled CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX; then + arch_vmlinux_o=.arch.vmlinux.o + info "ARCH" ${arch_vmlinux_o} + if ! ${srctree}/arch/${SRCARCH}/tools/vmlinux_o.sh ${arch_vmlinux_o} ; then + echo >&2 "Failed to generate ${arch_vmlinux_o}" + echo >&2 "Try to disable CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX" + exit 1 + fi +fiThis is wrong because
scripts/link-vmlinux.shis not triggered even when source files underarch/powerpc/tools/are changed.
Quoted 1 line
Presumably,
scripts/Makefile.vmlinuxwill be the right place.
Ah, yes. Something like this?
scripts/Makefile.vmlinux +4 -0
@@ -22,6 +22,10 @@ targets += .vmlinux.export.o vmlinux: .vmlinux.export.o endif +ifdef CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX +vmlinux: $(srctree)/arch/$(SRCARCH)/tools/vmlinux_o.sh +endif + ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) # Final link of vmlinux with optional arch pass after final link
Thanks,
Naveen
Re: [RFC PATCH v2 4/5] kbuild: Add generic hook for architectures to use before the final vmlinux link
Quoted 72 lines · Naveen N Rao
Quoted 31 lines · Masahiro Yamada
Quoted 30 lines · Naveen N Rao
On powerpc, we would like to be able to make a pass on vmlinux.o and generate a new object file to be linked into vmlinux. Add a generic pass in
link-vmlinux.shthat architectures can use for this purpose. Architectures need to selectCONFIG_ARCH_WANTS_PRE_LINK_VMLINUXand must provide arch/<arch>/tools/vmlinux_o.sh, which will be invoked prior to the final vmlinux link step.Signed-off-by Naveen N Rao <[email protected]>--- arch/Kconfig | 3 +++ scripts/link-vmlinux.sh | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-)arch/Kconfig +3
-0@@ -1643,4 +1643,7 @@ config CC_HAS_SANE_FUNCTION_ALIGNMENT config ARCH_NEED_CMPXCHG_1_EMU bool +config ARCH_WANTS_PRE_LINK_VMLINUX + def_bool n + endmenuscripts/link-vmlinux.sh +0
-0...
Quoted 17 lines
scripts/link-vmlinux.sh
Quoted 11 lines
scripts/link-vmlinux.sh +10
-0+arch_vmlinux_o="" +if is_enabled CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX; then + arch_vmlinux_o=.arch.vmlinux.o + info "ARCH" ${arch_vmlinux_o} + if ! ${srctree}/arch/${SRCARCH}/tools/vmlinux_o.sh ${arch_vmlinux_o} ; then + echo >&2 "Failed to generate ${arch_vmlinux_o}" + echo >&2 "Try to disable CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX" + exit 1 + fi +fiThis is wrong because
scripts/link-vmlinux.shis not triggered even when source files underarch/powerpc/tools/are changed.Quoted 1 line
Presumably,
scripts/Makefile.vmlinuxwill be the right place.Ah, yes. Something like this?
scripts/Makefile.vmlinux +4
-0@@ -22,6 +22,10 @@ targets += .vmlinux.export.o vmlinux: .vmlinux.export.o endif +ifdef CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX +vmlinux: $(srctree)/arch/$(SRCARCH)/tools/vmlinux_o.sh +endif + ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) # Final link of vmlinux with optional arch pass after final link
Quoted 3 lines
Thanks,
Naveen
No.
Something like below.
Then, you can do everything in Makefile, not a shell script.
ifdef CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX
vmlinux: .arch.vmlinux.o
.arch.vmlinux.o: FORCE
$(Q)$(MAKE) $(build)=arch/$(SRCARCH)/tools .arch.vmlinux.o
endif
I did not test it, though.
Signature · 2 lines
Best Regards Masahiro Yamada
Re: [RFC PATCH v2 4/5] kbuild: Add generic hook for architectures to use before the final vmlinux link
Quoted 90 lines · Masahiro Yamada
Quoted 72 lines · Naveen N Rao
Quoted 31 lines · Masahiro Yamada
Quoted 30 lines · Naveen N Rao
On powerpc, we would like to be able to make a pass on vmlinux.o and generate a new object file to be linked into vmlinux. Add a generic pass in
link-vmlinux.shthat architectures can use for this purpose. Architectures need to selectCONFIG_ARCH_WANTS_PRE_LINK_VMLINUXand must provide arch/<arch>/tools/vmlinux_o.sh, which will be invoked prior to the final vmlinux link step.Signed-off-by Naveen N Rao <[email protected]>--- arch/Kconfig | 3 +++ scripts/link-vmlinux.sh | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-)arch/Kconfig +3
-0@@ -1643,4 +1643,7 @@ config CC_HAS_SANE_FUNCTION_ALIGNMENT config ARCH_NEED_CMPXCHG_1_EMU bool +config ARCH_WANTS_PRE_LINK_VMLINUX + def_bool n + endmenuscripts/link-vmlinux.sh +0
-0...
Quoted 17 lines
scripts/link-vmlinux.sh
Quoted 11 lines
scripts/link-vmlinux.sh +10
-0+arch_vmlinux_o="" +if is_enabled CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX; then + arch_vmlinux_o=.arch.vmlinux.o + info "ARCH" ${arch_vmlinux_o} + if ! ${srctree}/arch/${SRCARCH}/tools/vmlinux_o.sh ${arch_vmlinux_o} ; then + echo >&2 "Failed to generate ${arch_vmlinux_o}" + echo >&2 "Try to disable CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX" + exit 1 + fi +fiThis is wrong because
scripts/link-vmlinux.shis not triggered even when source files underarch/powerpc/tools/are changed.Quoted 1 line
Presumably,
scripts/Makefile.vmlinuxwill be the right place.Ah, yes. Something like this?
scripts/Makefile.vmlinux +4
-0@@ -22,6 +22,10 @@ targets += .vmlinux.export.o vmlinux: .vmlinux.export.o endif +ifdef CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX +vmlinux: $(srctree)/arch/$(SRCARCH)/tools/vmlinux_o.sh +endif + ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) # Final link of vmlinux with optional arch pass after final linkQuoted 3 lines
Thanks,
NaveenNo.
Something like below.
Then, you can do everything in
Makefile, not a shell script.ifdef
CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX
vmlinux: .arch.vmlinux.o
Quoted 8 lines
.arch.vmlinux.o: FORCE
$(Q)$(MAKE) $(build)=arch/$(SRCARCH)/tools .arch.vmlinux.oendif
I did not test it, though.
Thanks for the pointer. I will try and build on that.
Just to be completely sure, does the below incremetal diff on top of the existing patch capture your suggestion?
---
scripts/Makefile.vmlinux +7 -0
@@ -22,6 +22,13 @@ targets += .vmlinux.export.o vmlinux: .vmlinux.export.o endif +ifdef CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX +vmlinux: .arch.vmlinux.o + +.arch.vmlinux.o: FORCE + $(Q)$(MAKE) $(build)=arch/$(SRCARCH)/tools .arch.vmlinux.o +endif + ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) # Final link of vmlinux with optional arch pass after final link
scripts/link-vmlinux.sh +0 -6
@@ -227,12 +227,6 @@ ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init init/version-timestamp.o arch_vmlinux_o="" if is_enabled CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX; then arch_vmlinux_o=.arch.vmlinux.o - info "ARCH" ${arch_vmlinux_o} - if ! ${srctree}/arch/${SRCARCH}/tools/vmlinux_o.sh ${arch_vmlinux_o} ; then - echo >&2 "Failed to generate ${arch_vmlinux_o}" - echo >&2 "Try to disable CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX" - exit 1 - fi fi btf_vmlinux_bin_o=""
Thanks,
Naveen
Re: [RFC PATCH v2 4/5] kbuild: Add generic hook for architectures to use before the final vmlinux link
Quoted 100 lines · Naveen N Rao
Quoted 59 lines · Masahiro Yamada
Quoted 41 lines · Naveen N Rao
Quoted 18 lines · Masahiro Yamada
Review
Quoted 11 lines · Naveen N Rao
(quoted diff) +10
-0+arch_vmlinux_o="" +if is_enabled CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX; then + arch_vmlinux_o=.arch.vmlinux.o + info "ARCH" ${arch_vmlinux_o} + if ! ${srctree}/arch/${SRCARCH}/tools/vmlinux_o.sh ${arch_vmlinux_o} ; then + echo >&2 "Failed to generate ${arch_vmlinux_o}" + echo >&2 "Try to disable CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX" + exit 1 + fi +fiThis is wrong because
scripts/link-vmlinux.shis not triggered even when source files underarch/powerpc/tools/are changed.Quoted 1 line
Presumably,
scripts/Makefile.vmlinuxwill be the right place.Ah, yes. Something like this?
scripts/Makefile.vmlinux +4
-0@@ -22,6 +22,10 @@ targets += .vmlinux.export.o vmlinux: .vmlinux.export.o endif +ifdef CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX +vmlinux: $(srctree)/arch/$(SRCARCH)/tools/vmlinux_o.sh +endif + ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) # Final link of vmlinux with optional arch pass after final linkQuoted 3 lines
Thanks,
NaveenNo.
Something like below.
Then, you can do everything in
Makefile, not a shell script.ifdef
CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX
vmlinux: .arch.vmlinux.oQuoted 8 lines
.arch.vmlinux.o: FORCE
$(Q)$(MAKE) $(build)=arch/$(SRCARCH)/tools .arch.vmlinux.oendif
I did not test it, though.
Thanks for the pointer. I will try and build on that.
Just to be completely sure, does the below incremetal diff on top of the existing patch capture your suggestion?
---
scripts/Makefile.vmlinux +7
-0@@ -22,6 +22,13 @@ targets += .vmlinux.export.o vmlinux: .vmlinux.export.o endif +ifdef CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX +vmlinux: .arch.vmlinux.o + +.arch.vmlinux.o: FORCE + $(Q)$(MAKE) $(build)=arch/$(SRCARCH)/tools .arch.vmlinux.o +endif + ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) # Final link of vmlinux with optional arch pass after final linkscripts/link-vmlinux.sh +0
-0@@ -227,12 +227,6 @@ ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init init/version-timestamp.o arch_vmlinux_o="" if is_enabled CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX; then
scripts/link-vmlinux.sh ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init init/version-timestamp.o · line 232
Quoted 10 lines
scripts/link-vmlinux.sh +0
-6arch_vmlinux_o=.arch.vmlinux.o - info "ARCH" ${arch_vmlinux_o} - if ! ${srctree}/arch/${SRCARCH}/tools/vmlinux_o.sh ${arch_vmlinux_o} ; then - echo >&2 "Failed to generate ${arch_vmlinux_o}" - echo >&2 "Try to disable CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX" - exit 1 - fi fi btf_vmlinux_bin_o=""
This is what I ended up with:
---
arch/Kconfig +3 -0
@@ -1643,4 +1643,7 @@ config CC_HAS_SANE_FUNCTION_ALIGNMENT config ARCH_NEED_CMPXCHG_1_EMU bool +config ARCH_WANTS_PRE_LINK_VMLINUX + def_bool n + endmenu
scripts/Makefile.vmlinux +8 -0
@@ -22,6 +22,14 @@ targets += .vmlinux.export.o vmlinux: .vmlinux.export.o endif +ifdef CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX +targets += .arch.vmlinux.o +.arch.vmlinux.o: vmlinux.o FORCE + $(Q)$(MAKE) $(build)=arch/$(SRCARCH)/tools .arch.vmlinux.o + +vmlinux: .arch.vmlinux.o +endif + ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) # Final link of vmlinux with optional arch pass after final link
scripts/link-vmlinux.sh +8 -3
@@ -122,7 +122,7 @@ gen_btf() return 1 fi - vmlinux_link ${1} + vmlinux_link ${1} ${arch_vmlinux_o} info "BTF" ${2} LLVM_OBJCOPY="${OBJCOPY}" ${PAHOLE} -J ${PAHOLE_FLAGS} ${1}
@@ -178,7 +178,7 @@ kallsyms_step() kallsymso=${kallsyms_vmlinux}.o kallsyms_S=${kallsyms_vmlinux}.S - vmlinux_link ${kallsyms_vmlinux} "${kallsymso_prev}" ${btf_vmlinux_bin_o} + vmlinux_link ${kallsyms_vmlinux} "${kallsymso_prev}" ${btf_vmlinux_bin_o} ${arch_vmlinux_o} mksysmap ${kallsyms_vmlinux} ${kallsyms_vmlinux}.syms kallsyms ${kallsyms_vmlinux}.syms ${kallsyms_S}
@@ -223,6 +223,11 @@ fi ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init init/version-timestamp.o +arch_vmlinux_o="" +if is_enabled CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX; then + arch_vmlinux_o=.arch.vmlinux.o +fi + btf_vmlinux_bin_o="" if is_enabled CONFIG_DEBUG_INFO_BTF; then btf_vmlinux_bin_o=.btf.vmlinux.bin.o
@@ -273,7 +278,7 @@ if is_enabled CONFIG_KALLSYMS; then fi fi -vmlinux_link vmlinux "${kallsymso}" ${btf_vmlinux_bin_o} +vmlinux_link vmlinux "${kallsymso}" ${btf_vmlinux_bin_o} ${arch_vmlinux_o} # fill in BTF IDs if is_enabled CONFIG_DEBUG_INFO_BTF && is_enabled CONFIG_BPF; then
---
Along with the below Makefile, things seem to be working properly in my limited tests:
arch/powerpc/tools/Makefile new file +10 -0
@@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +quiet_cmd_gen_ftrace_pfe_stubs = FTRACE $@ + cmd_gen_ftrace_pfe_stubs = $< $(objtree)/vmlinux.o $@ + +targets += .arch.vmlinux.o +.arch.vmlinux.o: $(srctree)/arch/powerpc/tools/gen-ftrace-pfe-stubs.sh $(objtree)/vmlinux.o FORCE + $(call if_changed,gen_ftrace_pfe_stubs) + +clean-files += $(objtree)/.arch.vmlinux.S $(objtree)/.arch.vmlinux.o
- Naveen
RFC PATCH v2 5/5 powerpc64/ftrace: Move ftrace sequence out of line
In reply to Naveen N RaoFunction profile sequence on powerpc includes two instructions at the beginning of each function:
mflr r0 bl ftrace_caller
The call to ftrace_caller() gets nop'ed out during kernel boot and is patched in when ftrace is enabled.
Given the sequence, we cannot return from ftrace_caller with 'blr' as we need to keep LR and r0 intact. This results in link stack imbalance when ftrace is enabled. To address that, we would like to use a three instruction sequence:
mflr r0 bl ftrace_caller mtlr r0
Further more, to support DYNAMIC_FTRACE_WITH_CALL_OPS, we need to reserve two instruction slots before the function. This results in a total of five instruction slots to be reserved for ftrace use on each function that is traced.
Move the function profile sequence out-of-line to minimize its impact. To do this, we reserve a single nop at function entry using -fpatchable-function-entry=1 and add a pass on vmlinux.o to determine the total number of functions that can be traced. This is then used to generate a .S file reserving the appropriate amount of space for use as ftrace stubs, which is built and linked into vmlinux.
On bootup, the stub space is split into separate stubs per function and populated with the proper instruction sequence. A pointer to the associated stub is maintained in dyn_arch_ftrace.
For modules, space for ftrace stubs is reserved from the generic module stub space.
This is restricted to and enabled by default only on 64-bit powerpc.
--- arch/powerpc/Kconfig | 4 + arch/powerpc/Makefile | 4 + arch/powerpc/include/asm/ftrace.h | 10 ++ arch/powerpc/include/asm/module.h | 5 + arch/powerpc/kernel/asm-offsets.c | 4 + arch/powerpc/kernel/module_64.c | 67 +++++++++-- arch/powerpc/kernel/trace/ftrace.c | 145 +++++++++++++++++++++-- arch/powerpc/kernel/trace/ftrace_entry.S | 71 ++++++++--- arch/powerpc/kernel/vmlinux.lds.S | 3 +- arch/powerpc/tools/vmlinux_o.sh | 47 ++++++++ 10 files changed, 324 insertions(+), 36 deletions(-) create mode 100755 arch/powerpc/tools/vmlinux_o.sh
arch/powerpc/Kconfig +4 -0
@@ -568,6 +568,10 @@ config ARCH_USING_PATCHABLE_FUNCTION_ENTRY def_bool $(success,$(srctree)/arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh $(CC) -mlittle-endian) if PPC64 && CPU_LITTLE_ENDIAN def_bool $(success,$(srctree)/arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh $(CC) -mbig-endian) if PPC64 && CPU_BIG_ENDIAN +config FTRACE_PFE_OUT_OF_LINE + def_bool PPC64 && ARCH_USING_PATCHABLE_FUNCTION_ENTRY + select ARCH_WANTS_PRE_LINK_VMLINUX + config HOTPLUG_CPU bool "Support for enabling/disabling CPUs" depends on SMP && (PPC_PSERIES || \
arch/powerpc/Makefile +4 -0
@@ -155,7 +155,11 @@ CC_FLAGS_NO_FPU := $(call cc-option,-msoft-float) ifdef CONFIG_FUNCTION_TRACER ifdef CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY +ifdef CONFIG_FTRACE_PFE_OUT_OF_LINE +CC_FLAGS_FTRACE := -fpatchable-function-entry=1 +else CC_FLAGS_FTRACE := -fpatchable-function-entry=2 +endif else CC_FLAGS_FTRACE := -pg ifdef CONFIG_MPROFILE_KERNEL
arch/powerpc/include/asm/ftrace.h +10 -0
@@ -26,6 +26,9 @@ unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip,struct module ;struct dyn_ftrace ;struct dyn_arch_ftrace { +#ifdef CONFIG_FTRACE_PFE_OUT_OF_LINE +unsigned long pfe_stub; +#endif };#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
@@ -132,6 +135,13 @@ static inline u8 this_cpu_get_ftrace_enabled(void) { return 1; }#ifdef CONFIG_FUNCTION_TRACER extern unsigned int ftrace_tramp_text[], ftrace_tramp_init[]; +#ifdef CONFIG_FTRACE_PFE_OUT_OF_LINE +struct ftrace_pfe_stub { +u32 insn[4 ]; +}; +extern struct ftrace_pfe_stub ftrace_pfe_stub_text[], ftrace_pfe_stub_inittext[]; +extern unsigned long ftrace_pfe_stub_text_count, ftrace_pfe_stub_inittext_count; +#endif void ftrace_free_init_tramp (void );unsigned long ftrace_call_adjust (unsigned long addr);#else
arch/powerpc/include/asm/module.h +5 -0
@@ -47,6 +47,11 @@ struct mod_arch_specific {#ifdef CONFIG_DYNAMIC_FTRACE unsigned long tramp;unsigned long tramp_regs; +#ifdef CONFIG_FTRACE_PFE_OUT_OF_LINE +struct ftrace_pfe_stub *pfe_stubs; +unsigned int pfe_stub_count; +unsigned int pfe_stub_index; +#endif #endif };
arch/powerpc/kernel/asm-offsets.c +4 -0
@@ -674,5 +674,9 @@ int main(void)DEFINE (BPT_SIZE ,BPT_SIZE );#endif +#ifdef CONFIG_FTRACE_PFE_OUT_OF_LINE +DEFINE (FTRACE_PFE_STUB_SIZE ,sizeof (struct ftrace_pfe_stub )); +#endif +return 0 ; }
arch/powerpc/kernel/module_64.c +60 -7
99 lines not on this page · raw message
arch/powerpc/kernel/trace/ftrace.c +135 -10
217 lines not on this page · raw message
arch/powerpc/kernel/trace/ftrace_entry.S +54 -17
137 lines not on this page · raw message
arch/powerpc/kernel/vmlinux.lds.S +1 -2
@@ -267,14 +267,13 @@ SECTIONS .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { _sinittext = .; INIT_TEXT - + *(.tramp.ftrace.init); /* *.init.text might be RO so we must ensure this section ends on * a page boundary. */ . = ALIGN(PAGE_SIZE); _einittext = .; - *(.tramp.ftrace.init); } :text /* .exit.text is discarded at runtime, not link time,
arch/powerpc/tools/vmlinux_o.sh new file +47 -0
47 lines not on this page · raw message
Signature · 1 line
2.45.2