ftrace: Add use of -mfentry for x86_64
Steven Rostedt
maintainercover ftrace: Add use of -mfentry for x86_64
This is an RFC patch set that makes gcc use the -mfentry option with -pg. This will set the ftrace 'hook' to the beginning of the function and also remove the requirement that -pg enables frame pointers.
This has a couple of benefits (and probably more).
1) removal of the frame pointer requirement makes for smaller and faster code.
2) Having the function trace hook at the beginning of the function instead of after the frame is set up, gives the function tracing callbacks access to the parameters. This means that kprobes can take advantage of this. When a kprobe is set on top of a ftrace hook (nop), it will automatically use the function tracing callback. This makes it into an 'optimized' probe as there's no need to hit a breakpoint and trigger the probe that way. The function tracing code can do the work for it. Note, optimized probes are only allowed with !PREEMPT, but a ftrace optimize probe is allowed in any context (another benefit).
This only implements fentry for x86_64.
Steven Rostedt (4):
ftrace: Make recordmcount.c handle __fentry__
ftrace: Add -mfentry to Makefile on function tracer
ftrace: Do not test frame pointers if -mfentry is used ftrace/x86: Add support for -mfentry to x86_64
----
Makefile | 6 +++++- arch/x86/Kconfig | 1 + arch/x86/include/asm/ftrace.h | 7 ++++++- arch/x86/kernel/entry_64.S | 18 +++++++++++++++++- arch/x86/kernel/x8664_ksyms_64.c | 6 +++++- kernel/trace/Kconfig | 5 +++++ kernel/trace/trace_functions_graph.c | 5 ++++- scripts/recordmcount.h | 4 +++- 8 files changed, 46 insertions(+), 6 deletions(-)
Steven Rostedt
maintainerRFC PATCH 1/4 ftrace: Make recordmcount.c handle __fentry__
From: Steven Rostedt <[email protected]>
With gcc 4.6.0 the -mfentry feature places the function profiling call at the start of the function. When this is used, the call is to __fentry__ and not mcount.
Change recordmcount.c to record both callers to __fentry__ and mcount.
--- scripts/recordmcount.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
scripts/recordmcount.h +3 -1
@@ -261,11 +261,13 @@ static unsigned get_mcountsym(Elf_Sym const *const sym0, &sym0[Elf_r_sym (relp)];char const *symname = &str0[w (symp->st_name)];char const *mcount = gpfx =='_' ?"_mcount" :"mcount" ; +char const *fentry ="__fentry__" ;if (symname[0 ] =='.' ) ++symname;/* ppc64 hack */ if (strcmp (mcount, symname) ==0 || - (altmcount &&strcmp (altmcount, symname) ==0 )) + (altmcount &&strcmp (altmcount, symname) ==0 ) || + (strcmp (fentry, symname) ==0 )) mcountsym =Elf_r_sym (relp);return mcountsym;
Signature · 1 line
1.7.10.4
Re: [RFC PATCH 1/4] ftrace: Make recordmcount.c handle __fentry__
Quoted 5 lines · Steven Rostedt
From: Steven Rostedt <[email protected]>
With gcc 4.6.0 the -mfentry feature places the function profiling call at the start of the function. When this is used, the call is to
__fentry__and not mcount.Change
recordmcount.cto record both callers to__fentry__and mcount.
[snip]
scripts/recordmcount.h static unsigned get_mcountsym(Elf_Sym const *const sym0, · line 270
Quoted 3 lines
scripts/recordmcount.h +2
-1- (altmcount && strcmp(altmcount, symname) == 0)) + (altmcount &&strcmp (altmcount, symname) ==0 ) || + (strcmp(fentry, symname) == 0))
The proposed change will work as long as all the *.o use the same name. Only one of {"__fentry__", "mcount", "_mcount", altmcount} is allowed for all the *.o as input for a particular run. [Modulo the hack of ignoring a leading '.' for 64-bit PowerPC, of course.]
If the user changes compilers (or changes CFLAGS by insert/remove "-mfentry") without doing a "make clean", then recordmcount will omit some calls.
Those restrictions are easy to guess, and recovery is easy. Therefore, Ack'ed by: John Reiser <[email protected]>
Steven Rostedt
maintainerRe: [RFC PATCH 1/4] ftrace: Make recordmcount.c handle __fentry__
Quoted 2 lines · John Reiser
If the user changes compilers (or changes CFLAGS by insert/remove "-mfentry") without doing a "make clean", then recordmcount will omit some calls.
The make dependencies of such a change should (hopefully) cause a full recompile of the code. Yeah, I expect that we only have "mcount" or "fentry" as something that can be called. If we had both mcount and fentry, it would fail to link anyway, as we only define mcount or fentry in the assembly, never both.
Quoted 4 lines
Those restrictions are easy to guess, and recovery is easy. Therefore, Ack'ed by: John Reiser <[email protected]>
Thanks!
-- Steve
[tip:perf/core] ftrace: Make recordmcount.c handle __fentry__
In reply to Steven RostedtCommit-ID: 48bb5dc6cd9d30fe0d594947563da1f8bd9abada Gitweb: http://git.kernel.org/tip/48bb5dc6cd9d30fe0d594947563da1f8bd9abada Author: Steven Rostedt <[email protected]> AuthorDate: Wed, 9 Feb 2011 13:13:23 -0500 Committer: Steven Rostedt <[email protected]> CommitDate: Thu, 23 Aug 2012 11:24:43 -0400
ftrace: Make recordmcount.c handle __fentry__
With gcc 4.6.0 the -mfentry feature places the function profiling call at the start of the function. When this is used, the call is to __fentry__ and not mcount.
Change recordmcount.c to record both callers to __fentry__ and mcount.
--- scripts/recordmcount.h | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-)
scripts/recordmcount.h +3 -1
@@ -261,11 +261,13 @@ static unsigned get_mcountsym(Elf_Sym const *const sym0, &sym0[Elf_r_sym (relp)];char const *symname = &str0[w (symp->st_name)];char const *mcount = gpfx =='_' ?"_mcount" :"mcount" ; +char const *fentry ="__fentry__" ;if (symname[0 ] =='.' ) ++symname;/* ppc64 hack */ if (strcmp (mcount, symname) ==0 || - (altmcount &&strcmp (altmcount, symname) ==0 )) + (altmcount &&strcmp (altmcount, symname) ==0 ) || + (strcmp (fentry, symname) ==0 )) mcountsym =Elf_r_sym (relp);return mcountsym;
Steven Rostedt
maintainerRFC PATCH 2/4 ftrace: Add -mfentry to Makefile on function tracer
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
Thanks to Andi Kleen, gcc 4.6.0 now supports -mfentry for x86 (and hopefully soon for other archs). What this does is to have the function profiler start at the beginning of the function instead of after the stack is set up. As plain -pg (mcount) is called after the stack is set up, and in some cases can have issues with the function graph tracer. It also requires frame pointers to be enabled.
The -mfentry now calls __fentry__ at the beginning of the function. This allows for compiling without frame pointers and even has the ability to access parameters if needed.
If the architecture and the compiler both support -mfentry then use that instead.
--- Makefile | 6 +++++- kernel/trace/Kconfig | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-)
Makefile +5 -1
@@ -609,7 +609,11 @@ KBUILD_CFLAGS += $(call cc-option, -femit-struct-debug-baseonly) endif ifdef CONFIG_FUNCTION_TRACER -KBUILD_CFLAGS += -pg +ifdef CONFIG_HAVE_FENTRY +CC_USING_FENTRY := $(call cc-option, -mfentry -DCC_USING_FENTRY) +endif +KBUILD_CFLAGS += -pg $(CC_USING_FENTRY) +KBUILD_AFLAGS += $(CC_USING_FENTRY) ifdef CONFIG_DYNAMIC_FTRACE ifdef CONFIG_HAVE_C_RECORDMCOUNT BUILD_C_RECORDMCOUNT := y
kernel/trace/Kconfig +5 -0
@@ -49,6 +49,11 @@ config HAVE_SYSCALL_TRACEPOINTS help See Documentation/trace/ftrace-design.txt +config HAVE_FENTRY + bool + help + Arch supports the gcc options -pg with -mfentry + config HAVE_C_RECORDMCOUNT bool help
Signature · 1 line
1.7.10.4
[tip:perf/core] ftrace: Add -mfentry to Makefile on function tracer
Commit-ID: a2546fae01124fb8063747439300fcf39bac033a Gitweb: http://git.kernel.org/tip/a2546fae01124fb8063747439300fcf39bac033a Author: Steven Rostedt <[email protected]> AuthorDate: Wed, 9 Feb 2011 13:15:59 -0500 Committer: Steven Rostedt <[email protected]> CommitDate: Thu, 23 Aug 2012 11:25:02 -0400
ftrace: Add -mfentry to Makefile on function tracer
Thanks to Andi Kleen, gcc 4.6.0 now supports -mfentry for x86 (and hopefully soon for other archs). What this does is to have the function profiler start at the beginning of the function instead of after the stack is set up. As plain -pg (mcount) is called after the stack is set up, and in some cases can have issues with the function graph tracer. It also requires frame pointers to be enabled.
The -mfentry now calls __fentry__ at the beginning of the function. This allows for compiling without frame pointers and even has the ability to access parameters if needed.
If the architecture and the compiler both support -mfentry then use that instead.
--- Makefile | 6 +++++- kernel/trace/Kconfig | 5 +++++ 2 files changed, 10 insertions(+), 1 deletions(-)
Makefile +5 -1
@@ -609,7 +609,11 @@ KBUILD_CFLAGS += $(call cc-option, -femit-struct-debug-baseonly) endif ifdef CONFIG_FUNCTION_TRACER -KBUILD_CFLAGS += -pg +ifdef CONFIG_HAVE_FENTRY +CC_USING_FENTRY := $(call cc-option, -mfentry -DCC_USING_FENTRY) +endif +KBUILD_CFLAGS += -pg $(CC_USING_FENTRY) +KBUILD_AFLAGS += $(CC_USING_FENTRY) ifdef CONFIG_DYNAMIC_FTRACE ifdef CONFIG_HAVE_C_RECORDMCOUNT BUILD_C_RECORDMCOUNT := y
kernel/trace/Kconfig +5 -0
@@ -49,6 +49,11 @@ config HAVE_SYSCALL_TRACEPOINTS help See Documentation/trace/ftrace-design.txt +config HAVE_FENTRY + bool + help + Arch supports the gcc options -pg with -mfentry + config HAVE_C_RECORDMCOUNT bool help
Steven Rostedt
maintainerRFC PATCH 3/4 ftrace: Do not test frame pointers if -mfentry is used
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
The function graph has a test to check if the frame pointer is corrupted, which can happen with various options of gcc with mcount. But this is not an issue with -mfentry as -mfentry does not need nor use frame pointers for function graph tracing.
--- kernel/trace/trace_functions_graph.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
kernel/trace/trace_functions_graph.c +4 -1
@@ -143,7 +143,7 @@ ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret,return ; } -#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST +#if defined(CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST ) && !defined(CC_USING_FENTRY )/* * The arch may choose to record the frame pointer used * and check it here to make sure that it is what we expect it
@@ -154,6 +154,9 @@ ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret,* * Currently, x86_32 with optimize for size (-Os) makes the latest * gcc do the above. +* +* Note, -mfentry does not use frame pointers, and this test +* is not needed if CC_USING_FENTRY is set. */ if (unlikely (current->ret_stack[index].fp != frame_pointer)) {ftrace_graph_stop ();
Signature · 1 line
1.7.10.4
Re: [RFC PATCH 3/4] ftrace: Do not test frame pointers if -mfentry is used
Quoted 18 lines · Steven Rostedt
From: Steven Rostedt <[email protected]>
The function graph has a test to check if the frame pointer is corrupted, which can happen with various options of gcc with mcount. But this is not an issue with -mfentry as -mfentry does not need nor use frame pointers for function graph tracing.
Cc Andi Kleen <[email protected]>Signed-off-by Steven Rostedt <[email protected]>--- kernel/trace/trace_functions_graph.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)kernel/trace/trace_functions_graph.c +0
-0
kernel/trace/trace_functions_graph.c ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret, · line 146
Quoted 5 lines
kernel/trace/trace_functions_graph.c +1
-1@@ -143,7 +143,7 @@ ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret,return ; } -#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST +#if defined(CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST ) && !defined(CC_USING_FENTRY )
I think CONFIG_HAVE_FENTRY would better unselect CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST in arch/x86/Kconfig explicitly.
Thank you,
Signature · 4 lines
Masami HIRAMATSU Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: [email protected]
Steven Rostedt
maintainerRe: [RFC PATCH 3/4] ftrace: Do not test frame pointers if -mfentry is used
Quoted 6 lines · Masami Hiramatsu
kernel/trace/trace_functions_graph.c ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret, · line 146
Quoted 3 lines
kernel/trace/trace_functions_graph.c +1
-1-#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST +#if defined(CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST ) && !defined(CC_USING_FENTRY )I think
CONFIG_HAVE_FENTRYwould better unselectCONFIG_HAVE_FUNCTION_GRAPH_FP_TESTinarch/x86/Kconfigexplicitly.
No, CONFIG_HAVE_FENTRY just means fentry is supported, it does not mean that it is being used. It only gets used if CC_USING_FENTRY is set, which is set by the Makefile at time of compile.
If CONFIG_HAVE_FENTRY is defined, a test is done to see if the gcc compiling the kernel supports -mfentry. If it does, then it defines the CC_USING_FENTRY macro, if not, the macro is not defined and the old way is performed.
If the old way is performed, even if CONFIG_HAVE_FENTRY is defined, then we still need the above test. We can not have CONFIG_HAVE_FENTRY unselect CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST.
-- Steve
Re: [RFC PATCH 3/4] ftrace: Do not test frame pointers if -mfentry is used
Quoted 12 lines · Steven Rostedt
Quoted 6 lines · Masami Hiramatsu
kernel/trace/trace_functions_graph.c ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret, · line 146
Quoted 3 lines
kernel/trace/trace_functions_graph.c +1
-1-#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST +#if defined(CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST ) && !defined(CC_USING_FENTRY )I think
CONFIG_HAVE_FENTRYwould better unselectCONFIG_HAVE_FUNCTION_GRAPH_FP_TESTinarch/x86/Kconfigexplicitly.No,
CONFIG_HAVE_FENTRYjust means fentry is supported, it does not mean that it is being used. It only gets used ifCC_USING_FENTRYis set, which is set by theMakefileat time of compile.
Quoted 8 lines
If
CONFIG_HAVE_FENTRYis defined, a test is done to see if the gcc compiling the kernel supports -mfentry. If it does, then it defines theCC_USING_FENTRYmacro, if not, the macro is not defined and the old way is performed.If the old way is performed, even if
CONFIG_HAVE_FENTRYis defined, then we still need the above test. We can not haveCONFIG_HAVE_FENTRYunselectCONFIG_HAVE_FUNCTION_GRAPH_FP_TEST.
Ah, I see. OK, I don't see any other issue.
Thank you,
Signature · 4 lines
Masami HIRAMATSU Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: [email protected]
Re: [RFC PATCH 3/4] ftrace: Do not test frame pointers if -mfentry is used
In reply to Steven RostedtQuoted 4 lines · Steven Rostedt
No,
CONFIG_HAVE_FENTRYjust means fentry is supported, it does not mean that it is being used. It only gets used ifCC_USING_FENTRYis set, which is set by theMakefileat time of compile.
Btw, it might be lovely to consider the concept of "Kconfig variables set by shell-scripts".
We currently have a metric sh*t-ton of Makefile magic for testing various things like this, and integrating it into Kconfig might be a good idea. That way you would be able to use the Kconfig logic on these things.
Kconfig already has the "option env=XYZ" syntax for importing values from the environment variables. Extending it to some kind of "option shell=xyz" would allow for more complex interactions like this (imagine testing compiler options and version dependencies in the Kconfig files instead of the Makefiles)?
Steven Rostedt
maintainerRe: [RFC PATCH 3/4] ftrace: Do not test frame pointers if -mfentry is used
Quoted 14 lines · Linus Torvalds
Quoted 4 lines · Steven Rostedt
No,
CONFIG_HAVE_FENTRYjust means fentry is supported, it does not mean that it is being used. It only gets used ifCC_USING_FENTRYis set, which is set by theMakefileat time of compile.Btw, it might be lovely to consider the concept of "
Kconfigvariables set by shell-scripts".We currently have a metric sh*t-ton of
Makefilemagic for testing various things like this, and integrating it intoKconfigmight be a good idea. That way you would be able to use theKconfiglogic on these things.
Quoted 5 lines
Kconfigalready has the "option env=XYZ" syntax for importing values from the environment variables. Extending it to some kind of "option shell=xyz" would allow for more complex interactions like this (imagine testing compiler options and version dependencies in theKconfigfiles instead of the Makefiles)?
I understand your pain. I think this 'test the environment in the makefile' is a bit of a hack.
I've worked a little with the Kconfig infrastructure, but I wouldn't consider myself an expert. Would Kconfig be able to handle a change in environment? That is, if you change your compiler, would a normal make kick off Kconfig to update the configs for the new environment. Or would the user have to do some kind of 'make oldconfig' before that.
Or is make 'oldconfig' performed at all compiles regardless now?
One nice thing of having all these tests represented in the .config file, is that when a user produces a bug, when they send their config, we would be able to see much more information about their environment.
-- Steve
H. Peter Anvin
reviewerRe: [RFC PATCH 3/4] ftrace: Do not test frame pointers if -mfentry is used
In reply to Linus TorvaldsQuoted 9 lines · Linus Torvalds
Btw, it might be lovely to consider the concept of "
Kconfigvariables set by shell-scripts".We currently have a metric sh*t-ton of
Makefilemagic for testing various things like this, and integrating it intoKconfigmight be a good idea. That way you would be able to use theKconfiglogic on these things.
Quoted 6 lines
Kconfigalready has the "option env=XYZ" syntax for importing values from the environment variables. Extending it to some kind of "option shell=xyz" would allow for more complex interactions like this (imagine testing compiler options and version dependencies in theKconfigfiles instead of the Makefiles)?
This is a Frequently Requested Feature over on the kbuild list... and it almost certainly would speed up the build given how many times the tests are currently run. Furthermore, it would let us base rules on the support existing, which we currently can't.
-hpa
Re: [RFC PATCH 3/4] ftrace: Do not test frame pointers if -mfentry is used
In reply to Linus TorvaldsQuoted 8 lines · Linus Torvalds
Quoted 4 lines · Steven Rostedt
No,
CONFIG_HAVE_FENTRYjust means fentry is supported, it does not mean that it is being used. It only gets used ifCC_USING_FENTRYis set, which is set by theMakefileat time of compile.Btw, it might be lovely to consider the concept of "
Kconfigvariables set by shell-scripts".
I looked into it some time ago because I needed it for something else. But no mergeable patch produced. Will try again.
One issue was that it will break some odd cross compiling or ccache setups where the compiler is not set correctly at config time. But I think it would be worth it.
Quoted 4 lines
We currently have a metric sh*t-ton of
Makefilemagic for testing various things like this, and integrating it intoKconfigmight be a good idea. That way you would be able to use theKconfiglogic on these things.
Also another big win would be to make the empty do nothing build faster, because the decisions would be cached.
I measured recently and we execute 30+ gccs on a empty build.
-Andi
[tip:perf/core] ftrace: Do not test frame pointers if -mfentry is used
In reply to Steven RostedtCommit-ID: 781d06248234e221edb560a18461d65808a8a942 Gitweb: http://git.kernel.org/tip/781d06248234e221edb560a18461d65808a8a942 Author: Steven Rostedt <[email protected]> AuthorDate: Wed, 9 Feb 2011 13:27:22 -0500 Committer: Steven Rostedt <[email protected]> CommitDate: Thu, 23 Aug 2012 11:25:29 -0400
ftrace: Do not test frame pointers if -mfentry is used
The function graph has a test to check if the frame pointer is corrupted, which can happen with various options of gcc with mcount. But this is not an issue with -mfentry as -mfentry does not need nor use frame pointers for function graph tracing.
--- kernel/trace/trace_functions_graph.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-)
kernel/trace/trace_functions_graph.c +4 -1
@@ -143,7 +143,7 @@ ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret,return ; } -#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST +#if defined(CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST ) && !defined(CC_USING_FENTRY )/* * The arch may choose to record the frame pointer used * and check it here to make sure that it is what we expect it
@@ -154,6 +154,9 @@ ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret,* * Currently, x86_32 with optimize for size (-Os) makes the latest * gcc do the above. +* +* Note, -mfentry does not use frame pointers, and this test +* is not needed if CC_USING_FENTRY is set. */ if (unlikely (current->ret_stack[index].fp != frame_pointer)) {ftrace_graph_stop ();
Steven Rostedt
maintainerRFC PATCH 4/4 ftrace/x86: Add support for -mfentry to x86_64
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
If the kernel is compiled with gcc 4.6.0 which supports -mfentry, then use that instead of mcount.
With mcount, frame pointers are forced with the -pg option and we get something like:
<can_vma_merge_before>:
55 push %rbp
48 89 e5 mov %rsp,%rbp
53 push %rbx
41 51 push %r9
e8 fe 6a 39 00 callq ffffffff81483d00 <mcount>
31 c0 xor %eax,%eax
48 89 fb mov %rdi,%rbx
48 89 d7 mov %rdx,%rdi
48 33 73 30 xor 0x30(%rbx),%rsi
48 f7 c6 ff ff ff f7 test $0xfffffffff7ffffff,%rsiWith -mfentry, frame pointers are no longer forced and the call looks like this:
<can_vma_merge_before>:
e8 33 af 37 00 callq ffffffff81461b40 <__fentry__>
53 push %rbx
48 89 fb mov %rdi,%rbx
31 c0 xor %eax,%eax
48 89 d7 mov %rdx,%rdi
41 51 push %r9
48 33 73 30 xor 0x30(%rbx),%rsi
48 f7 c6 ff ff ff f7 test $0xfffffffff7ffffff,%rsiThis adds the ftrace hook at the beginning of the function before a frame is set up, and allows the function callbacks to be able to access parameters. As kprobes now can use function tracing (at least on x86) this speeds up the kprobe hooks that are at the beginning of the function.
--- arch/x86/Kconfig | 1 + arch/x86/include/asm/ftrace.h | 7 ++++++- arch/x86/kernel/entry_64.S | 18 +++++++++++++++++- arch/x86/kernel/x8664_ksyms_64.c | 6 +++++- 4 files changed, 29 insertions(+), 3 deletions(-)
arch/x86/Kconfig +1 -0
@@ -36,6 +36,7 @@ config X86 select HAVE_KRETPROBES select HAVE_OPTPROBES select HAVE_FTRACE_MCOUNT_RECORD + select HAVE_FENTRY if X86_64 select HAVE_C_RECORDMCOUNT select HAVE_DYNAMIC_FTRACE select HAVE_FUNCTION_TRACER
arch/x86/include/asm/ftrace.h +6 -1
@@ -35,7 +35,11 @@#endif #ifdef CONFIG_FUNCTION_TRACER -#define MCOUNT_ADDR ((long)(mcount)) +#ifdef CC_USING_FENTRY +# define MCOUNT_ADDR ((long)(__fentry__)) +#else +# define MCOUNT_ADDR ((long)(mcount)) +#endif #define MCOUNT_INSN_SIZE 5/* sizeof mcount call */ #ifdef CONFIG_DYNAMIC_FTRACE
@@ -46,6 +50,7 @@#ifndef __ASSEMBLY__extern void mcount (void );extern atomic_t modifying_ftrace_code; +extern void __fentry__ (void );static inline unsigned long ftrace_call_adjust (unsigned long addr) {
arch/x86/kernel/entry_64.S +17 -1
@@ -69,9 +69,16 @@ #ifdef CONFIG_FUNCTION_TRACER #ifdef CONFIG_DYNAMIC_FTRACE + +#ifdef CC_USING_FENTRY +ENTRY(__fentry__) + retq +END(__fentry__) +#else ENTRY(mcount) retq END(mcount) +#endif /* skip is set if stack has been adjusted */ .macro ftrace_caller_setup skip=0
@@ -84,7 +91,11 @@ END(mcount) movq RIP(%rsp), %rdi subq $MCOUNT_INSN_SIZE, %rdi /* Load the parent_ip into the second parameter */ +#ifdef CC_USING_FENTRY + movq SS+16(%rsp), %rsi +#else movq 8(%rbp), %rsi +#endif .endm ENTRY(ftrace_caller)
@@ -215,9 +226,14 @@ END(mcount) ENTRY(ftrace_graph_caller) MCOUNT_SAVE_FRAME +#ifdef CC_USING_FENTRY + leaq SS+16(%rsp), %rdi + movq $0, %rdx /* No framepointers needed */ +#else leaq 8(%rbp), %rdi - movq RIP(%rsp), %rsi movq (%rbp), %rdx +#endif + movq RIP(%rsp), %rsi subq $MCOUNT_INSN_SIZE, %rsi call prepare_ftrace_return
arch/x86/kernel/x8664_ksyms_64.c +5 -1
@@ -13,9 +13,13 @@#include <asm/ftrace.h> #ifdef CONFIG_FUNCTION_TRACER -/* mcount is defined in assembly */ +/* mcount and __fentry__ are defined in assembly */ +#ifdef CC_USING_FENTRY +EXPORT_SYMBOL (__fentry__); +#else EXPORT_SYMBOL (mcount);#endif +#endif EXPORT_SYMBOL (__get_user_1);EXPORT_SYMBOL (__get_user_2);
Signature · 1 line
1.7.10.4
Re: [RFC PATCH 4/4] ftrace/x86: Add support for -mfentry to x86_64
Quoted 33 lines · Steven Rostedt
From: Steven Rostedt <[email protected]>
If the kernel is compiled with gcc 4.6.0 which supports -mfentry, then use that instead of mcount.
With mcount, frame pointers are forced with the -pg option and we get something like:
<
can_vma_merge_before>:55 push %rbp 48 89 e5 mov %rsp,%rbp 53 push %rbx 41 51 push %r9 e8 fe 6a 39 00 callq ffffffff81483d00 <mcount> 31 c0 xor %eax,%eax 48 89 fb mov %rdi,%rbx 48 89 d7 mov %rdx,%rdi 48 33 73 30 xor 0x30(%rbx),%rsi 48 f7 c6 ff ff ff f7 test $0xfffffffff7ffffff,%rsiWith -mfentry, frame pointers are no longer forced and the call looks like this:
<
can_vma_merge_before>:e8 33 af 37 00 callq ffffffff81461b40 <__fentry__> 53 push %rbx 48 89 fb mov %rdi,%rbx 31 c0 xor %eax,%eax 48 89 d7 mov %rdx,%rdi 41 51 push %r9 48 33 73 30 xor 0x30(%rbx),%rsi 48 f7 c6 ff ff ff f7 test $0xfffffffff7ffffff,%rsi
Quoted 5 lines
This adds the ftrace hook at the beginning of the function before a frame is set up, and allows the function callbacks to be able to access parameters. As kprobes now can use function tracing (at least on x86) this speeds up the kprobe hooks that are at the beginning of the function.
This looks good for me:)
Thanks!
Quoted 117 lines
Cc Masami Hiramatsu <[email protected]>Cc Andi Kleen <[email protected]>Signed-off-by Steven Rostedt <[email protected]>--- arch/x86/Kconfig | 1 + arch/x86/include/asm/ftrace.h | 7 ++++++- arch/x86/kernel/entry_64.S | 18 +++++++++++++++++- arch/x86/kernel/x8664_ksyms_64.c | 6 +++++- 4 files changed, 29 insertions(+), 3 deletions(-)arch/x86/Kconfig +1
-0@@ -36,6 +36,7 @@ config X86 select HAVE_KRETPROBES select HAVE_OPTPROBES select HAVE_FTRACE_MCOUNT_RECORD + select HAVE_FENTRY if X86_64 select HAVE_C_RECORDMCOUNT select HAVE_DYNAMIC_FTRACE select HAVE_FUNCTION_TRACERarch/x86/include/asm/ftrace.h +6
-1@@ -35,7 +35,11 @@#endif #ifdef CONFIG_FUNCTION_TRACER -#define MCOUNT_ADDR ((long)(mcount)) +#ifdef CC_USING_FENTRY +# define MCOUNT_ADDR ((long)(__fentry__)) +#else +# define MCOUNT_ADDR ((long)(mcount)) +#endif #define MCOUNT_INSN_SIZE 5/* sizeof mcount call */ #ifdef CONFIG_DYNAMIC_FTRACE @@ -46,6 +50,7 @@#ifndef __ASSEMBLY__extern void mcount (void );extern atomic_t modifying_ftrace_code; +extern void __fentry__ (void );static inline unsigned long ftrace_call_adjust (unsigned long addr) {arch/x86/kernel/entry_64.S +17
-1@@ -69,9 +69,16 @@ #ifdef CONFIG_FUNCTION_TRACER #ifdef CONFIG_DYNAMIC_FTRACE + +#ifdef CC_USING_FENTRY +ENTRY(__fentry__) + retq +END(__fentry__) +#else ENTRY(mcount) retq END(mcount) +#endif /* skip is set if stack has been adjusted */ .macro ftrace_caller_setup skip=0@@ -84,7 +91,11 @@ END(mcount) movq RIP(%rsp), %rdi subq $MCOUNT_INSN_SIZE, %rdi /* Load the parent_ip into the second parameter */ +#ifdef CC_USING_FENTRY + movq SS+16(%rsp), %rsi +#else movq 8(%rbp), %rsi +#endif .endm ENTRY(ftrace_caller)@@ -215,9 +226,14 @@ END(mcount) ENTRY(ftrace_graph_caller) MCOUNT_SAVE_FRAME +#ifdef CC_USING_FENTRY + leaq SS+16(%rsp), %rdi + movq $0, %rdx /* No framepointers needed */ +#else leaq 8(%rbp), %rdi - movq RIP(%rsp), %rsi movq (%rbp), %rdx +#endif + movq RIP(%rsp), %rsi subq $MCOUNT_INSN_SIZE, %rsi call prepare_ftrace_returnarch/x86/kernel/x8664_ksyms_64.c +5
-1@@ -13,9 +13,13 @@#include <asm/ftrace.h> #ifdef CONFIG_FUNCTION_TRACER -/* mcount is defined in assembly */ +/* mcount and __fentry__ are defined in assembly */ +#ifdef CC_USING_FENTRY +EXPORT_SYMBOL (__fentry__); +#else EXPORT_SYMBOL (mcount);#endif +#endif EXPORT_SYMBOL (__get_user_1);EXPORT_SYMBOL (__get_user_2);
Signature · 4 lines
Masami HIRAMATSU Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: [email protected]
Steven Rostedt
maintainerRe: [RFC PATCH 4/4] ftrace/x86: Add support for -mfentry to x86_64
In reply to Steven RostedtPeter and Masami
During my final tests, I found that this change breaks the !DYNAMIC_FTRACE config. That is, when we don't do the run-time updates of mcount calls to nops, the compiler will use fentry but the code still uses mcount.
I fixed this in the patch below. But as you two have acked and reviewed it, I can't add your tags if I have changed the code. Can you ack/review it again.
Thanks!
-- Steve
Quoted 39 lines · Steven Rostedt
From: Steven Rostedt <[email protected]>
If the kernel is compiled with gcc 4.6.0 which supports -mfentry, then use that instead of mcount.
With mcount, frame pointers are forced with the -pg option and we get something like:
<
can_vma_merge_before>:55 push %rbp 48 89 e5 mov %rsp,%rbp 53 push %rbx 41 51 push %r9 e8 fe 6a 39 00 callq ffffffff81483d00 <mcount> 31 c0 xor %eax,%eax 48 89 fb mov %rdi,%rbx 48 89 d7 mov %rdx,%rdi 48 33 73 30 xor 0x30(%rbx),%rsi 48 f7 c6 ff ff ff f7 test $0xfffffffff7ffffff,%rsiWith -mfentry, frame pointers are no longer forced and the call looks like this:
<
can_vma_merge_before>:e8 33 af 37 00 callq ffffffff81461b40 <__fentry__> 53 push %rbx 48 89 fb mov %rdi,%rbx 31 c0 xor %eax,%eax 48 89 d7 mov %rdx,%rdi 41 51 push %r9 48 33 73 30 xor 0x30(%rbx),%rsi 48 f7 c6 ff ff ff f7 test $0xfffffffff7ffffff,%rsiThis adds the ftrace hook at the beginning of the function before a frame is set up, and allows the function callbacks to be able to access parameters. As kprobes now can use function tracing (at least on x86) this speeds up the kprobe hooks that are at the beginning of the function.
Quoted 3 lines
Cc Masami Hiramatsu <[email protected]>Cc Andi Kleen <[email protected]>Signed-off-by Steven Rostedt <[email protected]>
(change log kept the same)
arch/x86/Kconfig +1 -0
@@ -36,6 +36,7 @@ config X86 select HAVE_KRETPROBES select HAVE_OPTPROBES select HAVE_FTRACE_MCOUNT_RECORD + select HAVE_FENTRY if X86_64 select HAVE_C_RECORDMCOUNT select HAVE_DYNAMIC_FTRACE select HAVE_FUNCTION_TRACER
arch/x86/include/asm/ftrace.h +6 -1
@@ -35,7 +35,11 @@#endif #ifdef CONFIG_FUNCTION_TRACER -#define MCOUNT_ADDR ((long)(mcount)) +#ifdef CC_USING_FENTRY +# define MCOUNT_ADDR ((long)(__fentry__)) +#else +# define MCOUNT_ADDR ((long)(mcount)) +#endif #define MCOUNT_INSN_SIZE 5/* sizeof mcount call */ #ifdef CONFIG_DYNAMIC_FTRACE
@@ -46,6 +50,7 @@#ifndef __ASSEMBLY__extern void mcount (void );extern atomic_t modifying_ftrace_code; +extern void __fentry__ (void );static inline unsigned long ftrace_call_adjust (unsigned long addr) {
arch/x86/kernel/entry_64.S +27 -5
@@ -68,10 +68,18 @@ .section .entry.text, "ax" #ifdef CONFIG_FUNCTION_TRACER + +#ifdef CC_USING_FENTRY +# define function_hook __fentry__ +#else +# define function_hook mcount +#endif + #ifdef CONFIG_DYNAMIC_FTRACE -ENTRY(mcount) + +ENTRY(function_hook) retq -END(mcount) +END(function_hook) /* skip is set if stack has been adjusted */ .macro ftrace_caller_setup skip=0
@@ -84,7 +92,11 @@ END(mcount) movq RIP(%rsp), %rdi subq $MCOUNT_INSN_SIZE, %rdi /* Load the parent_ip into the second parameter */ +#ifdef CC_USING_FENTRY + movq SS+16(%rsp), %rsi +#else movq 8(%rbp), %rsi +#endif .endm ENTRY(ftrace_caller)
@@ -177,7 +189,8 @@ END(ftrace_regs_caller) #else /* ! CONFIG_DYNAMIC_FTRACE */ -ENTRY(mcount) + +ENTRY(function_hook) cmpl $0, function_trace_stop jne ftrace_stub
@@ -199,7 +212,11 @@ trace: MCOUNT_SAVE_FRAME movq RIP(%rsp), %rdi +#ifdef CC_USING_FENTRY + movq SS+16(%rsp), %rsi +#else movq 8(%rbp), %rsi +#endif subq $MCOUNT_INSN_SIZE, %rdi call *ftrace_trace_function
@@ -207,7 +224,7 @@ trace: MCOUNT_RESTORE_FRAME jmp ftrace_stub -END(mcount) +END(function_hook) #endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* CONFIG_FUNCTION_TRACER */
@@ -215,9 +232,14 @@ END(mcount) ENTRY(ftrace_graph_caller) MCOUNT_SAVE_FRAME +#ifdef CC_USING_FENTRY + leaq SS+16(%rsp), %rdi + movq $0, %rdx /* No framepointers needed */ +#else leaq 8(%rbp), %rdi - movq RIP(%rsp), %rsi movq (%rbp), %rdx +#endif + movq RIP(%rsp), %rsi subq $MCOUNT_INSN_SIZE, %rsi call prepare_ftrace_return
arch/x86/kernel/x8664_ksyms_64.c +5 -1
@@ -13,9 +13,13 @@#include <asm/ftrace.h> #ifdef CONFIG_FUNCTION_TRACER -/* mcount is defined in assembly */ +/* mcount and __fentry__ are defined in assembly */ +#ifdef CC_USING_FENTRY +EXPORT_SYMBOL (__fentry__); +#else EXPORT_SYMBOL (mcount);#endif +#endif EXPORT_SYMBOL (__get_user_1);EXPORT_SYMBOL (__get_user_2);
Steven Rostedt
maintainerRe: [RFC PATCH 4/4] ftrace/x86: Add support for -mfentry to x86_64
Quoted 7 lines · Steven Rostedt
Peter and Masami
During my final tests, I found that this change breaks the !DYNAMIC_FTRACE config. That is, when we don't do the run-time updates of mcount calls to nops, the compiler will use fentry but the code still uses mcount.
Quoted 6 lines
I fixed this in the patch below. But as you two have acked and reviewed it, I can't add your tags if I have changed the code. Can you ack/review it again.
Thanks!
This is the changes that were made against the original patch:
arch/x86/kernel/entry_64.S +15 -9
@@ -68,18 +68,19 @@ .section .entry.text, "ax" #ifdef CONFIG_FUNCTION_TRACER -#ifdef CONFIG_DYNAMIC_FTRACE #ifdef CC_USING_FENTRY -ENTRY(__fentry__) - retq -END(__fentry__) +# define function_hook __fentry__ #else -ENTRY(mcount) - retq -END(mcount) +# define function_hook mcount #endif +#ifdef CONFIG_DYNAMIC_FTRACE + +ENTRY(function_hook) + retq +END(function_hook) + /* skip is set if stack has been adjusted */ .macro ftrace_caller_setup skip=0 MCOUNT_SAVE_FRAME \skip
@@ -188,7 +189,8 @@ END(ftrace_regs_caller) #else /* ! CONFIG_DYNAMIC_FTRACE */ -ENTRY(mcount) + +ENTRY(function_hook) cmpl $0, function_trace_stop jne ftrace_stub
@@ -210,7 +212,11 @@ trace: MCOUNT_SAVE_FRAME movq RIP(%rsp), %rdi +#ifdef CC_USING_FENTRY + movq SS+16(%rsp), %rsi +#else movq 8(%rbp), %rsi +#endif subq $MCOUNT_INSN_SIZE, %rdi call *ftrace_trace_function
@@ -218,7 +224,7 @@ trace: MCOUNT_RESTORE_FRAME jmp ftrace_stub -END(mcount) +END(function_hook) #endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* CONFIG_FUNCTION_TRACER */
Masami Hiramatsu
Reviewed-byRe: Re: [RFC PATCH 4/4] ftrace/x86: Add support for -mfentry to x86_64
In reply to Steven RostedtQuoted 6 lines · Steven Rostedt
Peter and Masami
During my final tests, I found that this change breaks the !DYNAMIC_FTRACE config. That is, when we don't do the run-time updates of mcount calls to nops, the compiler will use fentry but the code still uses mcount.
Ah, right. we have to take care about it.
Quoted 4 lines
I fixed this in the patch below. But as you two have acked and reviewed it, I can't add your tags if I have changed the code. Can you ack/review it again.
This looks good for me.
Quoted 200 lines
Thanks!
-- Steve
Quoted 39 lines · Steven Rostedt
From: Steven Rostedt <[email protected]>
If the kernel is compiled with gcc 4.6.0 which supports -mfentry, then use that instead of mcount.
With mcount, frame pointers are forced with the -pg option and we get something like:
<
can_vma_merge_before>:55 push %rbp 48 89 e5 mov %rsp,%rbp 53 push %rbx 41 51 push %r9 e8 fe 6a 39 00 callq ffffffff81483d00 <mcount> 31 c0 xor %eax,%eax 48 89 fb mov %rdi,%rbx 48 89 d7 mov %rdx,%rdi 48 33 73 30 xor 0x30(%rbx),%rsi 48 f7 c6 ff ff ff f7 test $0xfffffffff7ffffff,%rsiWith -mfentry, frame pointers are no longer forced and the call looks like this:
<
can_vma_merge_before>:e8 33 af 37 00 callq ffffffff81461b40 <__fentry__> 53 push %rbx 48 89 fb mov %rdi,%rbx 31 c0 xor %eax,%eax 48 89 d7 mov %rdx,%rdi 41 51 push %r9 48 33 73 30 xor 0x30(%rbx),%rsi 48 f7 c6 ff ff ff f7 test $0xfffffffff7ffffff,%rsiThis adds the ftrace hook at the beginning of the function before a frame is set up, and allows the function callbacks to be able to access parameters. As kprobes now can use function tracing (at least on x86) this speeds up the kprobe hooks that are at the beginning of the function.
Quoted 3 lines
Cc Masami Hiramatsu <[email protected]>Cc Andi Kleen <[email protected]>Signed-off-by Steven Rostedt <[email protected]>(change log kept the same)
arch/x86/Kconfig +1
-0@@ -36,6 +36,7 @@ config X86 select HAVE_KRETPROBES select HAVE_OPTPROBES select HAVE_FTRACE_MCOUNT_RECORD + select HAVE_FENTRY if X86_64 select HAVE_C_RECORDMCOUNT select HAVE_DYNAMIC_FTRACE select HAVE_FUNCTION_TRACERarch/x86/include/asm/ftrace.h +6
-1@@ -35,7 +35,11 @@#endif #ifdef CONFIG_FUNCTION_TRACER -#define MCOUNT_ADDR ((long)(mcount)) +#ifdef CC_USING_FENTRY +# define MCOUNT_ADDR ((long)(__fentry__)) +#else +# define MCOUNT_ADDR ((long)(mcount)) +#endif #define MCOUNT_INSN_SIZE 5/* sizeof mcount call */ #ifdef CONFIG_DYNAMIC_FTRACE @@ -46,6 +50,7 @@#ifndef __ASSEMBLY__extern void mcount (void );extern atomic_t modifying_ftrace_code; +extern void __fentry__ (void );static inline unsigned long ftrace_call_adjust (unsigned long addr) {arch/x86/kernel/entry_64.S +27
-5@@ -68,10 +68,18 @@ .section .entry.text, "ax" #ifdef CONFIG_FUNCTION_TRACER + +#ifdef CC_USING_FENTRY +# define function_hook __fentry__ +#else +# define function_hook mcount +#endif + #ifdef CONFIG_DYNAMIC_FTRACE -ENTRY(mcount) + +ENTRY(function_hook) retq -END(mcount) +END(function_hook) /* skip is set if stack has been adjusted */ .macro ftrace_caller_setup skip=0@@ -84,7 +92,11 @@ END(mcount) movq RIP(%rsp), %rdi subq $MCOUNT_INSN_SIZE, %rdi /* Load the parent_ip into the second parameter */ +#ifdef CC_USING_FENTRY + movq SS+16(%rsp), %rsi +#else movq 8(%rbp), %rsi +#endif .endm ENTRY(ftrace_caller)@@ -177,7 +189,8 @@ END(ftrace_regs_caller) #else /* ! CONFIG_DYNAMIC_FTRACE */ -ENTRY(mcount) + +ENTRY(function_hook) cmpl $0, function_trace_stop jne ftrace_stub@@ -199,7 +212,11 @@ trace: MCOUNT_SAVE_FRAME movq RIP(%rsp), %rdi +#ifdef CC_USING_FENTRY + movq SS+16(%rsp), %rsi +#else movq 8(%rbp), %rsi +#endif subq $MCOUNT_INSN_SIZE, %rdi call *ftrace_trace_function@@ -207,7 +224,7 @@ trace: MCOUNT_RESTORE_FRAME jmp ftrace_stub -END(mcount) +END(function_hook) #endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* CONFIG_FUNCTION_TRACER */@@ -215,9 +232,14 @@ END(mcount) ENTRY(ftrace_graph_caller) MCOUNT_SAVE_FRAME +#ifdef CC_USING_FENTRY + leaq SS+16(%rsp), %rdi + movq $0, %rdx /* No framepointers needed */ +#else leaq 8(%rbp), %rdi - movq RIP(%rsp), %rsi movq (%rbp), %rdx +#endif + movq RIP(%rsp), %rsi subq $MCOUNT_INSN_SIZE, %rsi call prepare_ftrace_returnarch/x86/kernel/x8664_ksyms_64.c +5
-2@@ -13,9 +13,13 @@#include <asm/ftrace.h> #ifdef CONFIG_FUNCTION_TRACER -/* mcount is defined in assembly */ +/* mcount and __fentry__ are defined in assembly */ +#ifdef CC_USING_FENTRY +EXPORT_SYMBOL (__fentry__); +#else EXPORT_SYMBOL (mcount);#endif +#endif EXPORT_SYMBOL (__get_user_1);EXPORT_SYMBOL (__get_user_2); --To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Signature · 4 lines
Masami HIRAMATSU Software Platform Research Dept. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: [email protected]
[tip:perf/core] ftrace/x86: Add support for -mfentry to x86_64
In reply to Steven RostedtCommit-ID: d57c5d51a30152f3175d2344cb6395f08bf8ee0c Gitweb: http://git.kernel.org/tip/d57c5d51a30152f3175d2344cb6395f08bf8ee0c Author: Steven Rostedt <[email protected]> AuthorDate: Wed, 9 Feb 2011 13:32:18 -0500 Committer: Steven Rostedt <[email protected]> CommitDate: Thu, 23 Aug 2012 11:26:36 -0400
ftrace/x86: Add support for -mfentry to x86_64
If the kernel is compiled with gcc 4.6.0 which supports -mfentry, then use that instead of mcount.
With mcount, frame pointers are forced with the -pg option and we get something like:
<can_vma_merge_before>:
55 push %rbp
48 89 e5 mov %rsp,%rbp
53 push %rbx
41 51 push %r9
e8 fe 6a 39 00 callq ffffffff81483d00 <mcount>
31 c0 xor %eax,%eax
48 89 fb mov %rdi,%rbx
48 89 d7 mov %rdx,%rdi
48 33 73 30 xor 0x30(%rbx),%rsi
48 f7 c6 ff ff ff f7 test $0xfffffffff7ffffff,%rsiWith -mfentry, frame pointers are no longer forced and the call looks like this:
<can_vma_merge_before>:
e8 33 af 37 00 callq ffffffff81461b40 <__fentry__>
53 push %rbx
48 89 fb mov %rdi,%rbx
31 c0 xor %eax,%eax
48 89 d7 mov %rdx,%rdi
41 51 push %r9
48 33 73 30 xor 0x30(%rbx),%rsi
48 f7 c6 ff ff ff f7 test $0xfffffffff7ffffff,%rsiThis adds the ftrace hook at the beginning of the function before a frame is set up, and allows the function callbacks to be able to access parameters. As kprobes now can use function tracing (at least on x86) this speeds up the kprobe hooks that are at the beginning of the function.
--- arch/x86/Kconfig | 1 + arch/x86/include/asm/ftrace.h | 7 ++++++- arch/x86/kernel/entry_64.S | 32 +++++++++++++++++++++++++++----- arch/x86/kernel/x8664_ksyms_64.c | 6 +++++- 4 files changed, 39 insertions(+), 7 deletions(-)
arch/x86/Kconfig +1 -0
@@ -36,6 +36,7 @@ config X86 select HAVE_KRETPROBES select HAVE_OPTPROBES select HAVE_FTRACE_MCOUNT_RECORD + select HAVE_FENTRY if X86_64 select HAVE_C_RECORDMCOUNT select HAVE_DYNAMIC_FTRACE select HAVE_FUNCTION_TRACER
arch/x86/include/asm/ftrace.h +6 -1
@@ -35,7 +35,11 @@#endif #ifdef CONFIG_FUNCTION_TRACER -#define MCOUNT_ADDR ((long)(mcount)) +#ifdef CC_USING_FENTRY +# define MCOUNT_ADDR ((long)(__fentry__)) +#else +# define MCOUNT_ADDR ((long)(mcount)) +#endif #define MCOUNT_INSN_SIZE 5/* sizeof mcount call */ #ifdef CONFIG_DYNAMIC_FTRACE
@@ -46,6 +50,7 @@#ifndef __ASSEMBLY__extern void mcount (void );extern atomic_t modifying_ftrace_code; +extern void __fentry__ (void );static inline unsigned long ftrace_call_adjust (unsigned long addr) {
arch/x86/kernel/entry_64.S +27 -5
@@ -68,10 +68,18 @@ .section .entry.text, "ax" #ifdef CONFIG_FUNCTION_TRACER + +#ifdef CC_USING_FENTRY +# define function_hook __fentry__ +#else +# define function_hook mcount +#endif + #ifdef CONFIG_DYNAMIC_FTRACE -ENTRY(mcount) + +ENTRY(function_hook) retq -END(mcount) +END(function_hook) /* skip is set if stack has been adjusted */ .macro ftrace_caller_setup skip=0
@@ -84,7 +92,11 @@ END(mcount) movq RIP(%rsp), %rdi subq $MCOUNT_INSN_SIZE, %rdi /* Load the parent_ip into the second parameter */ +#ifdef CC_USING_FENTRY + movq SS+16(%rsp), %rsi +#else movq 8(%rbp), %rsi +#endif .endm ENTRY(ftrace_caller)
@@ -177,7 +189,8 @@ END(ftrace_regs_caller) #else /* ! CONFIG_DYNAMIC_FTRACE */ -ENTRY(mcount) + +ENTRY(function_hook) cmpl $0, function_trace_stop jne ftrace_stub
@@ -199,7 +212,11 @@ trace: MCOUNT_SAVE_FRAME movq RIP(%rsp), %rdi +#ifdef CC_USING_FENTRY + movq SS+16(%rsp), %rsi +#else movq 8(%rbp), %rsi +#endif subq $MCOUNT_INSN_SIZE, %rdi call *ftrace_trace_function
@@ -207,7 +224,7 @@ trace: MCOUNT_RESTORE_FRAME jmp ftrace_stub -END(mcount) +END(function_hook) #endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* CONFIG_FUNCTION_TRACER */
@@ -215,9 +232,14 @@ END(mcount) ENTRY(ftrace_graph_caller) MCOUNT_SAVE_FRAME +#ifdef CC_USING_FENTRY + leaq SS+16(%rsp), %rdi + movq $0, %rdx /* No framepointers needed */ +#else leaq 8(%rbp), %rdi - movq RIP(%rsp), %rsi movq (%rbp), %rdx +#endif + movq RIP(%rsp), %rsi subq $MCOUNT_INSN_SIZE, %rsi call prepare_ftrace_return
arch/x86/kernel/x8664_ksyms_64.c +5 -1
@@ -13,9 +13,13 @@#include <asm/ftrace.h> #ifdef CONFIG_FUNCTION_TRACER -/* mcount is defined in assembly */ +/* mcount and __fentry__ are defined in assembly */ +#ifdef CC_USING_FENTRY +EXPORT_SYMBOL (__fentry__); +#else EXPORT_SYMBOL (mcount);#endif +#endif EXPORT_SYMBOL (__get_user_1);EXPORT_SYMBOL (__get_user_2);
Quoted 19 lines · Steven Rostedt
This is an RFC patch set that makes gcc use the -mfentry option with -pg. This will set the ftrace 'hook' to the beginning of the function and also remove the requirement that -pg enables frame pointers.
This has a couple of benefits (and probably more).
1) removal of the frame pointer requirement makes for smaller and faster code.
2) Having the function trace hook at the beginning of the function instead of after the frame is set up, gives the function tracing callbacks access to the parameters. This means that kprobes can take advantage of this. When a kprobe is set on top of a ftrace hook (nop), it will automatically use the function tracing callback. This makes it into an 'optimized' probe as there's no need to hit a breakpoint and trigger the probe that way. The function tracing code can do the work for it. Note, optimized probes are only allowed with !PREEMPT, but a ftrace optimize probe is allowed in any context (another benefit).
Quoted 2 lines
This only implements fentry for
x86_64.
-hpa
Signature · 2 lines
H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf.
Ingo Molnar
Acked-byQuoted 20 lines · H. Peter Anvin
Quoted 19 lines · Steven Rostedt
This is an RFC patch set that makes gcc use the -mfentry option with -pg. This will set the ftrace 'hook' to the beginning of the function and also remove the requirement that -pg enables frame pointers.
This has a couple of benefits (and probably more).
1) removal of the frame pointer requirement makes for smaller and faster code.
2) Having the function trace hook at the beginning of the function instead of after the frame is set up, gives the function tracing callbacks access to the parameters. This means that kprobes can take advantage of this. When a kprobe is set on top of a ftrace hook (nop), it will automatically use the function tracing callback. This makes it into an 'optimized' probe as there's no need to hit a breakpoint and trigger the probe that way. The function tracing code can do the work for it. Note, optimized probes are only allowed with !PREEMPT, but a ftrace optimize probe is allowed in any context (another benefit).
Quoted 4 lines
Quoted 2 lines
This only implements fentry for
x86_64.Acked-by H. Peter Anvin <[email protected]>
Nice feature!
Thanks,
Ingo