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]>

Reply via email to