On Sat, 14 Feb 2026 18:36:24 +0800
Donglin Peng <[email protected]> wrote:
> Hi Steve and Masami,
>
> I recently had an idea while using the function graph tracer.
> Currently, it supports basic
> filtering via set_ftrace_pid(PID-based) and
> set_graph_function(function name-based).
> However, this filtering mechanism feels somewhat limited. Given that
> we already have
> features like funcgraph-args, I wonder if we could enhance filtering by
> allowing
> conditional tracking based on function parameters — similar to how
> trace events support
> filters/triggers.
Agreed. I think it is a good idea.
>
> To simplify implementation, I propose extending a new trigger type
> (e.g., "funcgraph").
OK, and I think the question is what do we want to filter. As you know,
the kernel function call-graph is a very context depending. I think we
may be better to start with specifying the pid filter via the tringger
instead of enabling/disabling it on all cpus.
echo "funcgraph:setpid:common_pid" >> events/fprobes/func_foo/trigger
Then, we can also specify a specific task's pid too via sched_switch
events etc. Also we can add "clearpid". Maybe we also need a special
PID (e.g. -1) for trace no process instead of using tracing_on.
Thank you,
> In ftrace_graph_ignore_func, we could look up the corresponding trace_fprobe
> and
> trace_event_file based on trace->func, then decide whether to trace
> the function using
> a helper like the following:
>
> static bool ftrace_graph_filter(struct trace_fprobe *tf, struct
> ftrace_regs *fregs,
> struct trace_event_file *trace_file)
> {
> struct fentry_trace_entry_head *entry;
> struct trace_event_buffer fbuffer;
> struct event_trigger_data *data;
> int dsize;
>
> dsize = __get_data_size(&tf->tp, fregs, NULL);
> entry = trace_event_buffer_reserve(&fbuffer, trace_file,
> sizeof(*entry) + tf->tp.size + dsize);
> if (!entry)
> return false;
>
> entry = ring_buffer_event_data(fbuffer.event);
> store_trace_args(&entry[1], &tf->tp, fregs, NULL, sizeof(*entry), dsize);
>
> list_for_each_entry_rcu(data, &trace_file->triggers, list) {
> if (data->cmd_ops->trigger_type == TRIGGER_TYPE_FUNCGRAPH) {
> struct event_filter *filter = rcu_dereference_sched(data->filter);
> if (filter && filter_match_preds(filter, entry))
> return true; // Allow tracing
> }
> }
> return false; // Skip tracing
> }
>
> Does this approach make sense? Any suggestions or concerns?
>
> Thanks,
> Donglin
--
Masami Hiramatsu (Google) <[email protected]>