Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

tracing: Have function graph tracer option funcgraph-irqs be per instance

Currently the option to trace interrupts in the function graph tracer is
global when the interface is per-instance. Changing the value in one
instance will affect the results of another instance that is also running
the function graph tracer. This can lead to confusing results.

Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Link: https://patch.msgid.link/20251114192318.613867934@kernel.org
Fixes: c132be2c4fcc1 ("function_graph: Have the instances use their own ftrace_ops for filtering")
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

+31 -10
+31 -10
kernel/trace/trace_functions_graph.c
··· 16 16 #include "trace.h" 17 17 #include "trace_output.h" 18 18 19 - /* When set, irq functions will be ignored */ 19 + /* When set, irq functions might be ignored */ 20 20 static int ftrace_graph_skip_irqs; 21 21 22 22 struct fgraph_cpu_data { ··· 190 190 } 191 191 #endif 192 192 193 - static inline int ftrace_graph_ignore_irqs(void) 193 + static inline int ftrace_graph_ignore_irqs(struct trace_array *tr) 194 194 { 195 195 if (!ftrace_graph_skip_irqs || trace_recursion_test(TRACE_IRQ_BIT)) 196 + return 0; 197 + 198 + if (tracer_flags_is_set(tr, TRACE_GRAPH_PRINT_IRQS)) 196 199 return 0; 197 200 198 201 return in_hardirq(); ··· 241 238 if (ftrace_graph_ignore_func(gops, trace)) 242 239 return 0; 243 240 244 - if (ftrace_graph_ignore_irqs()) 241 + if (ftrace_graph_ignore_irqs(tr)) 245 242 return 0; 246 243 247 244 if (fgraph_sleep_time) { ··· 454 451 else 455 452 tr->gops->retfunc = trace_graph_return; 456 453 454 + if (!tracer_flags_is_set(tr, TRACE_GRAPH_PRINT_IRQS)) 455 + ftrace_graph_skip_irqs++; 456 + 457 457 /* Make gops functions visible before we start tracing */ 458 458 smp_mb(); 459 459 ··· 473 467 static int ftrace_graph_trace_args(struct trace_array *tr, int set) 474 468 { 475 469 trace_func_graph_ent_t entry; 476 - 477 - /* Do nothing if the current tracer is not this tracer */ 478 - if (tr->current_trace != &graph_trace) 479 - return 0; 480 470 481 471 if (set) 482 472 entry = trace_graph_entry_args; ··· 494 492 495 493 static void graph_trace_reset(struct trace_array *tr) 496 494 { 495 + if (!tracer_flags_is_set(tr, TRACE_GRAPH_PRINT_IRQS)) 496 + ftrace_graph_skip_irqs--; 497 + if (WARN_ON_ONCE(ftrace_graph_skip_irqs < 0)) 498 + ftrace_graph_skip_irqs = 0; 499 + 497 500 tracing_stop_cmdline_record(); 498 501 unregister_ftrace_graph(tr->gops); 499 502 } ··· 1624 1617 static int 1625 1618 func_graph_set_flag(struct trace_array *tr, u32 old_flags, u32 bit, int set) 1626 1619 { 1627 - if (bit == TRACE_GRAPH_PRINT_IRQS) 1628 - ftrace_graph_skip_irqs = !set; 1629 - 1630 1620 if (bit == TRACE_GRAPH_SLEEP_TIME) 1631 1621 ftrace_graph_sleep_time_control(set); 1632 1622 1633 1623 if (bit == TRACE_GRAPH_GRAPH_TIME) 1634 1624 ftrace_graph_graph_time_control(set); 1625 + 1626 + /* Do nothing if the current tracer is not this tracer */ 1627 + if (tr->current_trace != &graph_trace) 1628 + return 0; 1629 + 1630 + /* Do nothing if already set. */ 1631 + if (!!set == !!(tr->current_trace_flags->val & bit)) 1632 + return 0; 1633 + 1634 + if (bit == TRACE_GRAPH_PRINT_IRQS) { 1635 + if (set) 1636 + ftrace_graph_skip_irqs--; 1637 + else 1638 + ftrace_graph_skip_irqs++; 1639 + if (WARN_ON_ONCE(ftrace_graph_skip_irqs < 0)) 1640 + ftrace_graph_skip_irqs = 0; 1641 + } 1635 1642 1636 1643 if (bit == TRACE_GRAPH_ARGS) 1637 1644 return ftrace_graph_trace_args(tr, set);