]> www.infradead.org Git - users/hch/misc.git/commitdiff
tracing: Fix irqoff tracers on failure of acquiring calltime
authorSteven Rostedt <rostedt@goodmis.org>
Wed, 8 Oct 2025 15:49:43 +0000 (11:49 -0400)
committerSteven Rostedt (Google) <rostedt@goodmis.org>
Wed, 8 Oct 2025 16:10:44 +0000 (12:10 -0400)
The functions irqsoff_graph_entry() and irqsoff_graph_return() both call
func_prolog_dec() that will test if the data->disable is already set and
if not, increment it and return. If it was set, it returns false and the
caller exits.

The caller of this function must decrement the disable counter, but misses
doing so if the calltime fails to be acquired.

Instead of exiting out when calltime is NULL, change the logic to do the
work if it is not NULL and still do the clean up at the end of the
function if it is NULL.

Cc: stable@vger.kernel.org
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Link: https://lore.kernel.org/20251008114943.6f60f30f@gandalf.local.home
Fixes: a485ea9e3ef3 ("tracing: Fix irqsoff and wakeup latency tracers when using function graph")
Reported-by: Sasha Levin <sashal@kernel.org>
Closes: https://lore.kernel.org/linux-trace-kernel/20251006175848.1906912-2-sashal@kernel.org/
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
kernel/trace/trace_irqsoff.c

index 5496758b6c760f3af1ba6f2427d377ed4b21d086..4c45c49b06c8d7874a3d726d4cce4423853a0c70 100644 (file)
@@ -184,7 +184,7 @@ static int irqsoff_graph_entry(struct ftrace_graph_ent *trace,
        unsigned long flags;
        unsigned int trace_ctx;
        u64 *calltime;
-       int ret;
+       int ret = 0;
 
        if (ftrace_graph_ignore_func(gops, trace))
                return 0;
@@ -202,13 +202,11 @@ static int irqsoff_graph_entry(struct ftrace_graph_ent *trace,
                return 0;
 
        calltime = fgraph_reserve_data(gops->idx, sizeof(*calltime));
-       if (!calltime)
-               return 0;
-
-       *calltime = trace_clock_local();
-
-       trace_ctx = tracing_gen_ctx_flags(flags);
-       ret = __trace_graph_entry(tr, trace, trace_ctx);
+       if (calltime) {
+               *calltime = trace_clock_local();
+               trace_ctx = tracing_gen_ctx_flags(flags);
+               ret = __trace_graph_entry(tr, trace, trace_ctx);
+       }
        local_dec(&data->disabled);
 
        return ret;
@@ -233,11 +231,10 @@ static void irqsoff_graph_return(struct ftrace_graph_ret *trace,
 
        rettime = trace_clock_local();
        calltime = fgraph_retrieve_data(gops->idx, &size);
-       if (!calltime)
-               return;
-
-       trace_ctx = tracing_gen_ctx_flags(flags);
-       __trace_graph_return(tr, trace, trace_ctx, *calltime, rettime);
+       if (calltime) {
+               trace_ctx = tracing_gen_ctx_flags(flags);
+               __trace_graph_return(tr, trace, trace_ctx, *calltime, rettime);
+       }
        local_dec(&data->disabled);
 }