tracing: Fix irqoff tracers on failure of acquiring calltime

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>

+10 -13
+10 -13
kernel/trace/trace_irqsoff.c
··· 184 unsigned long flags; 185 unsigned int trace_ctx; 186 u64 *calltime; 187 - int ret; 188 189 if (ftrace_graph_ignore_func(gops, trace)) 190 return 0; ··· 202 return 0; 203 204 calltime = fgraph_reserve_data(gops->idx, sizeof(*calltime)); 205 - if (!calltime) 206 - return 0; 207 - 208 - *calltime = trace_clock_local(); 209 - 210 - trace_ctx = tracing_gen_ctx_flags(flags); 211 - ret = __trace_graph_entry(tr, trace, trace_ctx); 212 local_dec(&data->disabled); 213 214 return ret; ··· 231 232 rettime = trace_clock_local(); 233 calltime = fgraph_retrieve_data(gops->idx, &size); 234 - if (!calltime) 235 - return; 236 - 237 - trace_ctx = tracing_gen_ctx_flags(flags); 238 - __trace_graph_return(tr, trace, trace_ctx, *calltime, rettime); 239 local_dec(&data->disabled); 240 } 241
··· 184 unsigned long flags; 185 unsigned int trace_ctx; 186 u64 *calltime; 187 + int ret = 0; 188 189 if (ftrace_graph_ignore_func(gops, trace)) 190 return 0; ··· 202 return 0; 203 204 calltime = fgraph_reserve_data(gops->idx, sizeof(*calltime)); 205 + if (calltime) { 206 + *calltime = trace_clock_local(); 207 + trace_ctx = tracing_gen_ctx_flags(flags); 208 + ret = __trace_graph_entry(tr, trace, trace_ctx); 209 + } 210 local_dec(&data->disabled); 211 212 return ret; ··· 233 234 rettime = trace_clock_local(); 235 calltime = fgraph_retrieve_data(gops->idx, &size); 236 + if (calltime) { 237 + trace_ctx = tracing_gen_ctx_flags(flags); 238 + __trace_graph_return(tr, trace, trace_ctx, *calltime, rettime); 239 + } 240 local_dec(&data->disabled); 241 } 242