From nobody Sun Feb 8 18:52:51 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 954F55336D for ; Thu, 23 Jan 2025 02:42:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737600178; cv=none; b=TCdamMRR0REPh1HjSlb2rVQYdI8dOxdG0VGiz16QYN/jaTjbmu1tJFuONEBgYC8AG38zJHwJ/WEjAo4NDHr6mTekv10eDpYrL/gOADg6Mpi95xhxr20fZMf+C/xjYna6i05X+drXS6cgCqxg5T0o4w97WIgN3eXiKwh7JQE7sE4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737600178; c=relaxed/simple; bh=A7SCXhYtrZWi5r3AFWh3b4Z1LQuJK0K/OFEO5apQ0ac=; h=Date:From:To:Subject:Message-ID:MIME-Version:Content-Type; b=UZGN+TIOuYy3iUl1qDag7VhWeJfU6PoRlyISCaoxm5YjgitOnGo4n2RRY2aMHhQrrWhD/xfz02z/y1vztuUcbBJWwLFXw6ETNIlMUVzdb4+MBxwEp/vr/USFNjaLFBAqOGa8tenELNuv9yMRna49pVeJEErTfcdytCpYuTZhiHo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 768C7C4CED2; Thu, 23 Jan 2025 02:42:57 +0000 (UTC) Date: Wed, 22 Jan 2025 21:43:03 -0500 From: Steven Rostedt To: LKML , Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers Subject: [for-next][PATCH] fgraph: Remove calltime and rettime from generic operations Message-ID: <20250122214303.5af78176@gandalf.local.home> X-Mailer: Claws Mail 3.20.0git84 (GTK+ 2.24.33; x86_64-pc-linux-gnu) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Cleanup to function graph infrastructure for 6.14: - Remove calltime and rettime from the generic infrastructure The calltime and rettime fields used in the structures of the generic code that implements the function graph infrastructure is only used by the function graph tracer. When the function graph tracer was the only user of the function graph infrastructure this made sense. But today there are other users (fprobes and BPF) that do not need these fields and they are just wasted memory. Now that the function graph tracer (and the irqsoff and wakeup latency tracers) get the calltime and rettime in their own functions, these fields can be removed, and the tracers that use them can use their own generic functions. git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git ftrace/for-next Head SHA1: 66611c0475709607f398e2a5d691b1fc72fe9dfc Steven Rostedt (1): fgraph: Remove calltime and rettime from generic operations ---- include/linux/ftrace.h | 2 -- kernel/trace/fgraph.c | 1 - kernel/trace/trace.h | 4 +++- kernel/trace/trace_entries.h | 8 ++++---- kernel/trace/trace_functions_graph.c | 33 +++++++++++++++++++-------------- kernel/trace/trace_irqsoff.c | 5 +++-- kernel/trace/trace_sched_wakeup.c | 6 ++++-- 7 files changed, 33 insertions(+), 26 deletions(-) --------------------------- commit 66611c0475709607f398e2a5d691b1fc72fe9dfc Author: Steven Rostedt Date: Tue Jan 21 19:44:36 2025 -0500 fgraph: Remove calltime and rettime from generic operations =20 The function graph infrastructure is now generic so that kretprobes, fprobes and BPF can use it. But there is still some leftover logic that only the function graph tracer itself uses. This is the calculation of = the calltime and return time of the functions. The calculation of the callt= ime has been moved into the function graph tracer and those users that need= it so that it doesn't cause overhead to the other users. But the return function timestamp was still called. =20 Instead of just moving the taking of the timestamp into the function gr= aph trace remove the calltime and rettime completely from the ftrace_graph_= ret structure. Instead, move it into the function graph return entry event structure and this also moves all the calltime and rettime logic out of the generic fgraph.c code and into the tracing code that uses it. =20 This has been reported to decrease the overhead by ~27%. =20 Link: https://lore.kernel.org/all/Z3aSuql3fnXMVMoM@krava/ Link: https://lore.kernel.org/all/173665959558.1629214.1672413659721181= 0729.stgit@devnote2/ =20 Cc: Mark Rutland Cc: Mathieu Desnoyers Link: https://lore.kernel.org/20250121194436.15bdf71a@gandalf.local.home Reported-by: Jiri Olsa Reviewed-by: Masami Hiramatsu (Google) Signed-off-by: Steven Rostedt (Google) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 07092dfb21a4..fbabc3d848b3 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -1151,8 +1151,6 @@ struct ftrace_graph_ret { int depth; /* Number of functions that overran the depth limit for current task */ unsigned int overrun; - unsigned long long calltime; - unsigned long long rettime; } __packed; =20 struct fgraph_ops; diff --git a/kernel/trace/fgraph.c b/kernel/trace/fgraph.c index 9e6b5a71555b..5dddfc2149f6 100644 --- a/kernel/trace/fgraph.c +++ b/kernel/trace/fgraph.c @@ -826,7 +826,6 @@ __ftrace_return_to_handler(struct ftrace_regs *fregs, u= nsigned long frame_pointe return (unsigned long)panic; } =20 - trace.rettime =3D trace_clock_local(); if (fregs) ftrace_regs_set_instruction_pointer(fregs, ret); =20 diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 04058a9889b7..2742d14df383 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -912,7 +912,9 @@ extern int __trace_graph_retaddr_entry(struct trace_arr= ay *tr, unsigned long retaddr); extern void __trace_graph_return(struct trace_array *tr, struct ftrace_graph_ret *trace, - unsigned int trace_ctx); + unsigned int trace_ctx, + u64 calltime, u64 rettime); + extern void init_array_fgraph_ops(struct trace_array *tr, struct ftrace_op= s *ops); extern int allocate_fgraph_ops(struct trace_array *tr, struct ftrace_ops *= ops); extern void free_fgraph_ops(struct trace_array *tr); diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h index 82fd174ebbe0..fbfb396905a6 100644 --- a/kernel/trace/trace_entries.h +++ b/kernel/trace/trace_entries.h @@ -124,8 +124,8 @@ FTRACE_ENTRY_PACKED(funcgraph_exit, ftrace_graph_ret_en= try, __field_packed( unsigned long, ret, retval ) __field_packed( int, ret, depth ) __field_packed( unsigned int, ret, overrun ) - __field_packed( unsigned long long, ret, calltime) - __field_packed( unsigned long long, ret, rettime ) + __field(unsigned long long, calltime ) + __field(unsigned long long, rettime ) ), =20 F_printk("<-- %ps (%d) (start: %llx end: %llx) over: %d retval: %lx", @@ -146,8 +146,8 @@ FTRACE_ENTRY_PACKED(funcgraph_exit, ftrace_graph_ret_en= try, __field_packed( unsigned long, ret, func ) __field_packed( int, ret, depth ) __field_packed( unsigned int, ret, overrun ) - __field_packed( unsigned long long, ret, calltime) - __field_packed( unsigned long long, ret, rettime ) + __field(unsigned long long, calltime ) + __field(unsigned long long, rettime ) ), =20 F_printk("<-- %ps (%d) (start: %llx end: %llx) over: %d", diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_func= tions_graph.c index dc62eb93837a..54d850997c0a 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -266,12 +266,10 @@ __trace_graph_function(struct trace_array *tr, struct ftrace_graph_ret ret =3D { .func =3D ip, .depth =3D 0, - .calltime =3D time, - .rettime =3D time, }; =20 __trace_graph_entry(tr, &ent, trace_ctx); - __trace_graph_return(tr, &ret, trace_ctx); + __trace_graph_return(tr, &ret, trace_ctx, time, time); } =20 void @@ -283,8 +281,9 @@ trace_graph_function(struct trace_array *tr, } =20 void __trace_graph_return(struct trace_array *tr, - struct ftrace_graph_ret *trace, - unsigned int trace_ctx) + struct ftrace_graph_ret *trace, + unsigned int trace_ctx, + u64 calltime, u64 rettime) { struct ring_buffer_event *event; struct trace_buffer *buffer =3D tr->array_buffer.buffer; @@ -296,6 +295,8 @@ void __trace_graph_return(struct trace_array *tr, return; entry =3D ring_buffer_event_data(event); entry->ret =3D *trace; + entry->calltime =3D calltime; + entry->rettime =3D rettime; trace_buffer_unlock_commit_nostack(buffer, event); } =20 @@ -317,10 +318,13 @@ void trace_graph_return(struct ftrace_graph_ret *trac= e, struct trace_array_cpu *data; struct fgraph_times *ftimes; unsigned int trace_ctx; + u64 calltime, rettime; long disabled; int size; int cpu; =20 + rettime =3D trace_clock_local(); + ftrace_graph_addr_finish(gops, trace); =20 if (*task_var & TRACE_GRAPH_NOTRACE) { @@ -334,7 +338,7 @@ void trace_graph_return(struct ftrace_graph_ret *trace, =20 handle_nosleeptime(trace, ftimes, size); =20 - trace->calltime =3D ftimes->calltime; + calltime =3D ftimes->calltime; =20 preempt_disable_notrace(); cpu =3D raw_smp_processor_id(); @@ -342,7 +346,7 @@ void trace_graph_return(struct ftrace_graph_ret *trace, disabled =3D atomic_read(&data->disabled); if (likely(!disabled)) { trace_ctx =3D tracing_gen_ctx(); - __trace_graph_return(tr, trace, trace_ctx); + __trace_graph_return(tr, trace, trace_ctx, calltime, rettime); } preempt_enable_notrace(); } @@ -367,10 +371,8 @@ static void trace_graph_thresh_return(struct ftrace_gr= aph_ret *trace, =20 handle_nosleeptime(trace, ftimes, size); =20 - trace->calltime =3D ftimes->calltime; - if (tracing_thresh && - (trace->rettime - ftimes->calltime < tracing_thresh)) + (trace_clock_local() - ftimes->calltime < tracing_thresh)) return; else trace_graph_return(trace, gops, fregs); @@ -856,7 +858,7 @@ print_graph_entry_leaf(struct trace_iterator *iter, =20 graph_ret =3D &ret_entry->ret; call =3D &entry->graph_ent; - duration =3D graph_ret->rettime - graph_ret->calltime; + duration =3D ret_entry->rettime - ret_entry->calltime; =20 func =3D call->func + iter->tr->text_delta; =20 @@ -1137,11 +1139,14 @@ print_graph_entry(struct ftrace_graph_ent_entry *fi= eld, struct trace_seq *s, } =20 static enum print_line_t -print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s, +print_graph_return(struct ftrace_graph_ret_entry *retentry, struct trace_s= eq *s, struct trace_entry *ent, struct trace_iterator *iter, u32 flags) { - unsigned long long duration =3D trace->rettime - trace->calltime; + struct ftrace_graph_ret *trace =3D &retentry->ret; + u64 calltime =3D retentry->calltime; + u64 rettime =3D retentry->rettime; + unsigned long long duration =3D rettime - calltime; struct fgraph_data *data =3D iter->private; struct trace_array *tr =3D iter->tr; unsigned long func; @@ -1342,7 +1347,7 @@ print_graph_function_flags(struct trace_iterator *ite= r, u32 flags) case TRACE_GRAPH_RET: { struct ftrace_graph_ret_entry *field; trace_assign_type(field, entry); - return print_graph_return(&field->ret, s, entry, iter, flags); + return print_graph_return(field, s, entry, iter, flags); } case TRACE_STACK: case TRACE_FN: diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index 08786c59d397..7294ad676379 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -223,6 +223,7 @@ static void irqsoff_graph_return(struct ftrace_graph_re= t *trace, unsigned long flags; unsigned int trace_ctx; u64 *calltime; + u64 rettime; int size; =20 ftrace_graph_addr_finish(gops, trace); @@ -230,13 +231,13 @@ static void irqsoff_graph_return(struct ftrace_graph_= ret *trace, if (!func_prolog_dec(tr, &data, &flags)) return; =20 + rettime =3D trace_clock_local(); calltime =3D fgraph_retrieve_data(gops->idx, &size); if (!calltime) return; - trace->calltime =3D *calltime; =20 trace_ctx =3D tracing_gen_ctx_flags(flags); - __trace_graph_return(tr, trace, trace_ctx); + __trace_graph_return(tr, trace, trace_ctx, *calltime, rettime); atomic_dec(&data->disabled); } =20 diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_w= akeup.c index f372252dc8bb..af30586f1aea 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -158,6 +158,7 @@ static void wakeup_graph_return(struct ftrace_graph_ret= *trace, struct trace_array_cpu *data; unsigned int trace_ctx; u64 *calltime; + u64 rettime; int size; =20 ftrace_graph_addr_finish(gops, trace); @@ -165,12 +166,13 @@ static void wakeup_graph_return(struct ftrace_graph_r= et *trace, if (!func_prolog_preempt_disable(tr, &data, &trace_ctx)) return; =20 + rettime =3D trace_clock_local(); + calltime =3D fgraph_retrieve_data(gops->idx, &size); if (!calltime) return; - trace->calltime =3D *calltime; =20 - __trace_graph_return(tr, trace, trace_ctx); + __trace_graph_return(tr, trace, trace_ctx, *calltime, rettime); atomic_dec(&data->disabled); =20 preempt_enable_notrace();