From: Masami Hiramatsu (Google) <mhiramat@xxxxxxxxxx> Since the ftrace_graph_ret::rettime is only referred in the function_graph tracer, the trace_clock_local() call in fgraph is just an overhead for other fgraph users. Move the trace_clock_local() for recording return time to function_graph tracer and the rettime field is just zeroed in the fgraph side. That rettime field is updated by one of the function_graph tracer and cached for other function_graph tracer instances. According to Jiri's report[1], removing this function will gain fprobe performance ~27%. [1] https://lore.kernel.org/all/Z3aSuql3fnXMVMoM@krava/ Reported-by: Jiri Olsa <olsajiri@xxxxxxxxx> Signed-off-by: Masami Hiramatsu (Google) <mhiramat@xxxxxxxxxx> --- include/linux/ftrace.h | 11 +++++++++++ kernel/trace/fgraph.c | 2 +- kernel/trace/trace_functions_graph.c | 2 ++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 07092dfb21a4..a2fb7360d6e2 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -1155,6 +1155,17 @@ struct ftrace_graph_ret { unsigned long long rettime; } __packed; +static inline void ftrace_graph_ret_record_time(struct ftrace_graph_ret *trace) +{ + if (!trace->rettime) + trace->rettime = trace_clock_local(); +} + +static inline void ftrace_graph_ret_init_time(struct ftrace_graph_ret *trace) +{ + trace->rettime = 0; +} + struct fgraph_ops; /* Type of the callback handlers for tracing function graph*/ diff --git a/kernel/trace/fgraph.c b/kernel/trace/fgraph.c index c928527251e3..bc1e5f0493b6 100644 --- a/kernel/trace/fgraph.c +++ b/kernel/trace/fgraph.c @@ -826,7 +826,7 @@ __ftrace_return_to_handler(struct ftrace_regs *fregs, unsigned long frame_pointe return (unsigned long)panic; } - trace.rettime = trace_clock_local(); + ftrace_graph_ret_init_time(&trace); if (fregs) ftrace_regs_set_instruction_pointer(fregs, ret); diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index d0e4f412c298..7e4d91d42d8e 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -327,6 +327,7 @@ void trace_graph_return(struct ftrace_graph_ret *trace, int size; int cpu; + ftrace_graph_ret_record_time(trace); ftrace_graph_addr_finish(gops, trace); if (*task_var & TRACE_GRAPH_NOTRACE) { @@ -361,6 +362,7 @@ static void trace_graph_thresh_return(struct ftrace_graph_ret *trace, struct fgraph_times *ftimes; int size; + ftrace_graph_ret_record_time(trace); ftrace_graph_addr_finish(gops, trace); if (trace_recursion_test(TRACE_GRAPH_NOTRACE_BIT)) {