linux/kernel/trace
Steven Rostedt f4ff9f646a fgraph: Do not call handlers direct when not using ftrace_ops
The function graph tracer was modified to us the ftrace_ops of the
function tracer. This simplified the code as well as allowed more features
of the function graph tracer.

Not all architectures were converted over as it required the
implementation of HAVE_DYNAMIC_FTRACE_WITH_ARGS to implement. For those
architectures, it still did it the old way where the function graph tracer
handle was called by the function tracer trampoline. The handler then had
to check the hash to see if the registered handlers wanted to be called by
that function or not.

In order to speed up the function graph tracer that used ftrace_ops, if
only one callback was registered with function graph, it would call its
function directly via a static call.

Now, if the architecture does not support the use of using ftrace_ops and
still has the ftrace function trampoline calling the function graph
handler, then by doing a direct call it removes the check against the
handler's hash (list of functions it wants callbacks to), and it may call
that handler for functions that the handler did not request calls for.

On 32bit x86, which does not support the ftrace_ops use with function
graph tracer, it shows the issue:

 ~# trace-cmd start -p function -l schedule
 ~# trace-cmd show
 # tracer: function_graph
 #
 # CPU  DURATION                  FUNCTION CALLS
 # |     |   |                     |   |   |   |
  2) * 11898.94 us |  schedule();
  3) # 1783.041 us |  schedule();
  1)               |  schedule() {
  ------------------------------------------
  1)   bash-8369    =>  kworker-7669
  ------------------------------------------
  1)               |        schedule() {
  ------------------------------------------
  1)  kworker-7669  =>   bash-8369
  ------------------------------------------
  1) + 97.004 us   |  }
  1)               |  schedule() {
 [..]

Now by starting the function tracer is another instance:

 ~# trace-cmd start -B foo -p function

This causes the function graph tracer to trace all functions (because the
function trace calls the function graph tracer for each on, and the
function graph trace is doing a direct call):

 ~# trace-cmd show
 # tracer: function_graph
 #
 # CPU  DURATION                  FUNCTION CALLS
 # |     |   |                     |   |   |   |
  1)   1.669 us    |          } /* preempt_count_sub */
  1) + 10.443 us   |        } /* _raw_spin_unlock_irqrestore */
  1)               |        tick_program_event() {
  1)               |          clockevents_program_event() {
  1)   1.044 us    |            ktime_get();
  1)   6.481 us    |            lapic_next_event();
  1) + 10.114 us   |          }
  1) + 11.790 us   |        }
  1) ! 181.223 us  |      } /* hrtimer_interrupt */
  1) ! 184.624 us  |    } /* __sysvec_apic_timer_interrupt */
  1)               |    irq_exit_rcu() {
  1)   0.678 us    |      preempt_count_sub();

When it should still only be tracing the schedule() function.

To fix this, add a macro FGRAPH_NO_DIRECT to be set to 0 when the
architecture does not support function graph use of ftrace_ops, and set to
1 otherwise. Then use this macro to know to allow function graph tracer to
call the handlers directly or not.

Cc: stable@vger.kernel.org
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Link: https://patch.msgid.link/20260218104244.5f14dade@gandalf.local.home
Fixes: cc60ee813b ("function_graph: Use static_call and branch to optimize entry function")
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
2026-02-19 15:21:22 -05:00
..
rv verification/rvgen: Remove unused variable declaration from containers 2026-01-12 07:43:51 +01:00
blktrace.c tracing updates for 7.0: 2026-02-13 19:25:16 -08:00
bpf_trace.c tracing updates for 7.0: 2026-02-13 19:25:16 -08:00
bpf_trace.h tracing/treewide: Remove second parameter of __assign_str() 2024-05-22 20:14:47 -04:00
error_report-traces.c
fgraph.c fgraph: Do not call handlers direct when not using ftrace_ops 2026-02-19 15:21:22 -05:00
fprobe.c tracing fixes for v6.19: 2025-12-06 13:49:40 -08:00
ftrace.c tracing updates for 7.0: 2026-02-13 19:25:16 -08:00
ftrace_internal.h function_graph: Make fgraph_update_pid_func() a stub for !DYNAMIC_FTRACE 2024-06-10 18:08:23 -04:00
Kconfig tracing updates for 7.0: 2026-02-13 19:25:16 -08:00
kprobe_event_gen_test.c
Makefile tracing: Move pid filtering into trace_pid.c 2026-02-08 21:01:13 -05:00
pid_list.c trace/pid_list: optimize pid_list->lock contention 2025-11-13 15:15:54 -05:00
pid_list.h trace/pid_list: optimize pid_list->lock contention 2025-11-13 15:15:54 -05:00
power-traces.c PM: cpufreq: powernv/tracing: Move powernv_throttle trace event 2025-07-21 16:40:56 -04:00
preemptirq_delay_test.c kernel: trace: preemptirq_delay_test: use offstack cpu mask 2025-07-08 18:17:38 -04:00
rethook.c rethook: honor CONFIG_FTRACE_VALIDATE_RCU_IS_WATCHING in rethook_try_get() 2024-05-01 23:18:48 +09:00
ring_buffer.c tracing: ring-buffer: Fix to check event length before using 2026-02-19 15:21:12 -05:00
ring_buffer_benchmark.c tracing: Fix typo in ring_buffer_benchmark.c 2025-12-05 15:43:40 -05:00
rpm-traces.c
synth_event_gen_test.c tracing / synthetic: Disable events after testing in synth_event_gen_test_init() 2023-12-21 10:04:45 -05:00
trace.c mm.git review status for linus..mm-nonmm-stable 2026-02-12 12:13:01 -08:00
trace.h tracing updates for 7.0: 2026-02-13 19:25:16 -08:00
trace_benchmark.c tracing: Improve benchmark test performance by using do_div() 2024-05-13 20:00:57 -04:00
trace_benchmark.h
trace_boot.c tracing: Allow creating instances with specified system events 2023-12-18 23:14:16 -05:00
trace_branch.c tracing: branch: Use trace_tracing_is_on_cpu() instead of "disabled" field 2025-05-09 15:19:10 -04:00
trace_btf.c tracing/probes: Fix to search structure fields correctly 2024-02-17 21:25:42 +09:00
trace_btf.h
trace_clock.c tracing: Use atomic64_inc_return() in trace_clock_counter() 2024-10-09 19:59:49 -04:00
trace_dynevent.c tracing: Report wrong dynamic event command 2025-11-10 19:26:14 -05:00
trace_dynevent.h tracing: probes: Fix a possible race in trace_probe_log APIs 2025-05-13 22:23:34 +09:00
trace_entries.h tracing: Fix ftrace event field alignments 2026-02-05 09:47:11 -05:00
trace_eprobe.c Probes for v6.19 2025-12-05 10:55:47 -08:00
trace_event_perf.c perf: Remove unnecessary parameter of security check 2025-02-26 14:13:58 -05:00
trace_events.c tracing: Make tracing_disabled global for tracing system 2026-02-08 21:01:11 -05:00
trace_events_filter.c tracing: Replace use of system_wq with system_dfl_wq 2026-01-26 17:44:05 -05:00
trace_events_filter_test.h
trace_events_hist.c tracing: Move tracing_set_filter_buffering() into trace_events_hist.c 2026-02-08 21:01:11 -05:00
trace_events_inject.c tracing: Have format file honor EVENT_FILE_FL_FREED 2024-08-07 18:12:46 -04:00
trace_events_synth.c tracing: Remove notrace from trace_event_raw_event_synth() 2026-01-28 21:01:09 -05:00
trace_events_trigger.c tracing: Have all triggers expect a file parameter 2026-02-08 21:00:57 -05:00
trace_events_user.c tracing: Fix multiple typos in trace_events_user.c 2025-12-05 15:43:41 -05:00
trace_export.c tracing: Fix ftrace event field alignments 2026-02-05 09:47:11 -05:00
trace_fprobe.c tracing updates for v6.19: 2025-12-05 09:51:37 -08:00
trace_functions.c tracing: Have function tracer define options per instance 2025-11-12 09:59:54 -05:00
trace_functions_graph.c function_graph: Fix args pointer mismatch in print_graph_retval() 2026-01-23 13:34:38 -05:00
trace_hwlat.c tracing: Fix false sharing in hwlat get_sample() 2026-02-10 03:36:39 -05:00
trace_irqsoff.c tracing: Allow tracer to add more than 32 options 2025-11-04 21:44:00 +09:00
trace_kdb.c tracing: Allow tracer to add more than 32 options 2025-11-04 21:44:00 +09:00
trace_kprobe.c tracing: Make tracing_disabled global for tracing system 2026-02-08 21:01:11 -05:00
trace_kprobe_selftest.c
trace_kprobe_selftest.h
trace_mmiotrace.c tracing/mmiotrace: Remove reference to unused per CPU data pointer 2025-05-08 09:36:09 -04:00
trace_nop.c
trace_osnoise.c tracing: Fix multiple typos in trace_osnoise.c 2025-12-05 15:43:41 -05:00
trace_output.c tracing: Add bitmask-list option for human-readable bitmask display 2026-01-26 17:00:50 -05:00
trace_output.h tracing: Allow tracer to add more than 32 options 2025-11-04 21:44:00 +09:00
trace_pid.c tracing: Move pid filtering into trace_pid.c 2026-02-08 21:01:13 -05:00
trace_preemptirq.c tracing: Fix archs that still call tracepoints without RCU watching 2024-12-05 09:28:58 -05:00
trace_printk.c tracing updates for 7.0: 2026-02-13 19:25:16 -08:00
trace_probe.c tracing fixes for v6.19: 2025-12-06 13:49:40 -08:00
trace_probe.h tracing: probes: Use __free() for trace_probe_log 2025-11-01 01:10:28 +09:00
trace_probe_kernel.h
trace_probe_tmpl.h tracing/fprobe: Enable fprobe events with CONFIG_DYNAMIC_FTRACE_WITH_ARGS 2024-12-26 10:50:04 -05:00
trace_recursion_record.c
trace_sched_switch.c tracing: Ensure optimized hashing works 2025-09-30 17:27:58 -04:00
trace_sched_wakeup.c tracing: Allow tracer to add more than 32 options 2025-11-04 21:44:00 +09:00
trace_selftest.c tracing: Rename trace_array field max_buffer to snapshot_buffer 2026-02-08 21:01:13 -05:00
trace_selftest_dynamic.c
trace_seq.c tracing: Add bitmask-list option for human-readable bitmask display 2026-01-26 17:00:50 -05:00
trace_stack.c tracing updates for v6.16: 2025-05-29 21:04:36 -07:00
trace_stat.c tracing: Switch trace_stat.c code over to use guard() 2024-12-26 10:38:37 -05:00
trace_stat.h
trace_synth.h
trace_syscalls.c tracing: Hide __NR_utimensat and _NR_mq_timedsend when not defined 2025-11-10 14:23:53 -05:00
trace_uprobe.c tracing: uprobe: eprobes: Allocate traceprobe_parse_context per probe 2025-11-01 01:10:29 +09:00
tracing_map.c tracing: Use vmalloc_array() to improve code 2025-09-23 09:31:58 -04:00
tracing_map.h