* [PATCH v5 v5 0/3] tracing/fprobe: Support comma-separated symbols and :entry/:exit
@ 2026-01-18 1:18 Seokwoo Chung (Ryan)
2026-01-18 1:18 ` [PATCH v5 v5 1/3] docs: tracing/fprobe: Document list filters " Seokwoo Chung (Ryan)
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Seokwoo Chung (Ryan) @ 2026-01-18 1:18 UTC (permalink / raw)
To: rostedt, mhiramat, corbet, shuah
Cc: mathieu.desnoyers, linux-kernel, linux-trace-kernel, linux-doc,
linux-kselftest, Seokwoo Chung (Ryan)
This series extends fprobe dynamic events to accept a comma-separated list of
symbols and explicit/suffixes.
Currently, fprobe only supports a single symbol (or wildcard) per event. This
series allow users to specify a comma-separated list of symbols, including
exclusions, and to select entry/exit explicitly using /
Examples:
- f:[GRP/][EVENT] func1,func2,func3
- f:[GRP/][EVENT] func1,!func2,func3 (exclude with '!')
Logic changes:
- Refactor parsing logic into parse_fprobe_spec()
- Support comma-separated lists and '!' exclusions
- Add / suffixes for explicit entry/exit selection
- Preserve legacy single-symbol behavior (single symbols still accept %return)
- Disable BTF-based signature lookup when list/wildcard is used, since one
function signature cannot apply to multiple functions
- Reject mixed legacy/new syntax where applicable (e.g. list + %return)
- Update tracefs/README and fprobe documentation
- Add ftrace selftests covering accepted list syntax cases
*Patch order is adjusted: code first, then docs, then selftest
Changes in v5:
- Reordered patches (code->docs->selftests) as suggested
- Addressed review feedback on README help text to show both legacy and list
syntaxes
- Added missing traceprobe error IDs used by the new validation and fixed
parsing/bracing issues found by automated builds
- Removed the dedicated list_mode field and infer list behavior from presence of
filter/nofilter and keep struct trace_probe as the last member
- Link to v4: https://lore.kernel.org/linux-trace-kernel/20251127151218.4763b25c751bb2aac4b1ee36@kernel.org/
I am not fully confident the runtime testing coverage that I did is sufficient
across configs/architectures, so additional verification would be appreciated.
Best regards,
Ryan Chung
Seokwoo Chung (Ryan) (3):
docs: tracing/fprobe: Document list filters and :entry/:exit
tracing/fprobe: Support comma-separated symbols and :entry/:exit
selftests/ftrace: Add accept cases for fprobe list syntax
Documentation/trace/fprobetrace.rst | 17 +-
kernel/trace/trace.c | 3 +-
kernel/trace/trace_fprobe.c | 209 ++++++++++++++----
.../ftrace/test.d/dynevent/fprobe_list.tc | 92 ++++++++
4 files changed, 269 insertions(+), 52 deletions(-)
create mode 100644 tools/testing/selftests/ftrace/test.d/dynevent/fprobe_list.tc
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH v5 v5 1/3] docs: tracing/fprobe: Document list filters and :entry/:exit 2026-01-18 1:18 [PATCH v5 v5 0/3] tracing/fprobe: Support comma-separated symbols and :entry/:exit Seokwoo Chung (Ryan) @ 2026-01-18 1:18 ` Seokwoo Chung (Ryan) 2026-01-20 20:53 ` Steven Rostedt 2026-01-18 1:18 ` [PATCH v5 v5 2/3] tracing/fprobe: Support comma-separated symbols " Seokwoo Chung (Ryan) 2026-01-18 1:18 ` [PATCH v5 v5 3/3] selftests/ftrace: Add accept cases for fprobe list syntax Seokwoo Chung (Ryan) 2 siblings, 1 reply; 10+ messages in thread From: Seokwoo Chung (Ryan) @ 2026-01-18 1:18 UTC (permalink / raw) To: rostedt, mhiramat, corbet, shuah Cc: mathieu.desnoyers, linux-kernel, linux-trace-kernel, linux-doc, linux-kselftest, Seokwoo Chung (Ryan) Update fprobe event documentation to describe comma-separated symbol lists, exclusions, and explicit suffixes. Signed-off-by: Seokwoo Chung (Ryan) <seokwoo.chung130@gmail.com> --- Documentation/trace/fprobetrace.rst | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/Documentation/trace/fprobetrace.rst b/Documentation/trace/fprobetrace.rst index b4c2ca3d02c1..bbcfd57f0005 100644 --- a/Documentation/trace/fprobetrace.rst +++ b/Documentation/trace/fprobetrace.rst @@ -25,14 +25,18 @@ Synopsis of fprobe-events ------------------------- :: - f[:[GRP1/][EVENT1]] SYM [FETCHARGS] : Probe on function entry - f[MAXACTIVE][:[GRP1/][EVENT1]] SYM%return [FETCHARGS] : Probe on function exit + f[:[GRP1/][EVENT1]] SYM[%return] [FETCHARGS] : Single function + f[:[GRP1/][EVENT1]] SYM[,[!]SYM[,...]][:entry|:exit] [FETCHARGS] :Multiple + function t[:[GRP2/][EVENT2]] TRACEPOINT [FETCHARGS] : Probe on tracepoint GRP1 : Group name for fprobe. If omitted, use "fprobes" for it. GRP2 : Group name for tprobe. If omitted, use "tracepoints" for it. EVENT1 : Event name for fprobe. If omitted, the event name is - "SYM__entry" or "SYM__exit". + - For a single literal symbol, the event name is + "SYM__entry" or "SYM__exit". + - For a *list or any wildcard*, an explicit [GRP1/][EVENT1] is + required; otherwise the parser rejects it. EVENT2 : Event name for tprobe. If omitted, the event name is the same as "TRACEPOINT", but if the "TRACEPOINT" starts with a digit character, "_TRACEPOINT" is used. @@ -40,6 +44,13 @@ Synopsis of fprobe-events can be probed simultaneously, or 0 for the default value as defined in Documentation/trace/fprobe.rst + SYM : Function name or comma-separated list of symbols. + - SYM prefixed with "!" are exclusions. + - ":entry" suffix means it probes entry of given symbols + (default) + - ":exit" suffix means it probes exit of given symbols. + - "%return" suffix means it probes exit of SYM (single + symbol). FETCHARGS : Arguments. Each probe can have up to 128 args. ARG : Fetch "ARG" function argument using BTF (only for function entry or tracepoint.) (\*1) -- 2.43.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v5 v5 1/3] docs: tracing/fprobe: Document list filters and :entry/:exit 2026-01-18 1:18 ` [PATCH v5 v5 1/3] docs: tracing/fprobe: Document list filters " Seokwoo Chung (Ryan) @ 2026-01-20 20:53 ` Steven Rostedt 2026-01-25 20:23 ` Seokwoo Chung 0 siblings, 1 reply; 10+ messages in thread From: Steven Rostedt @ 2026-01-20 20:53 UTC (permalink / raw) To: Seokwoo Chung (Ryan) Cc: mhiramat, corbet, shuah, mathieu.desnoyers, linux-kernel, linux-trace-kernel, linux-doc, linux-kselftest On Sat, 17 Jan 2026 20:18:13 -0500 "Seokwoo Chung (Ryan)" <seokwoo.chung130@gmail.com> wrote: > Update fprobe event documentation to describe comma-separated symbol lists, > exclusions, and explicit suffixes. Usually, the documentation updates comes *after* the changes. -- Steve > > Signed-off-by: Seokwoo Chung (Ryan) <seokwoo.chung130@gmail.com> > --- > Documentation/trace/fprobetrace.rst | 17 ++++++++++++++--- > 1 file changed, 14 insertions(+), 3 deletions(-) > > diff --git a/Documentation/trace/fprobetrace.rst b/Documentation/trace/fprobetrace.rst > index b4c2ca3d02c1..bbcfd57f0005 100644 > --- a/Documentation/trace/fprobetrace.rst > +++ b/Documentation/trace/fprobetrace.rst > @@ -25,14 +25,18 @@ Synopsis of fprobe-events > ------------------------- > :: > > - f[:[GRP1/][EVENT1]] SYM [FETCHARGS] : Probe on function entry > - f[MAXACTIVE][:[GRP1/][EVENT1]] SYM%return [FETCHARGS] : Probe on function exit > + f[:[GRP1/][EVENT1]] SYM[%return] [FETCHARGS] : Single function > + f[:[GRP1/][EVENT1]] SYM[,[!]SYM[,...]][:entry|:exit] [FETCHARGS] :Multiple > + function > t[:[GRP2/][EVENT2]] TRACEPOINT [FETCHARGS] : Probe on tracepoint > > GRP1 : Group name for fprobe. If omitted, use "fprobes" for it. > GRP2 : Group name for tprobe. If omitted, use "tracepoints" for it. > EVENT1 : Event name for fprobe. If omitted, the event name is > - "SYM__entry" or "SYM__exit". > + - For a single literal symbol, the event name is > + "SYM__entry" or "SYM__exit". > + - For a *list or any wildcard*, an explicit [GRP1/][EVENT1] is > + required; otherwise the parser rejects it. > EVENT2 : Event name for tprobe. If omitted, the event name is > the same as "TRACEPOINT", but if the "TRACEPOINT" starts > with a digit character, "_TRACEPOINT" is used. > @@ -40,6 +44,13 @@ Synopsis of fprobe-events > can be probed simultaneously, or 0 for the default value > as defined in Documentation/trace/fprobe.rst > > + SYM : Function name or comma-separated list of symbols. > + - SYM prefixed with "!" are exclusions. > + - ":entry" suffix means it probes entry of given symbols > + (default) > + - ":exit" suffix means it probes exit of given symbols. > + - "%return" suffix means it probes exit of SYM (single > + symbol). > FETCHARGS : Arguments. Each probe can have up to 128 args. > ARG : Fetch "ARG" function argument using BTF (only for function > entry or tracepoint.) (\*1) ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v5 v5 1/3] docs: tracing/fprobe: Document list filters and :entry/:exit 2026-01-20 20:53 ` Steven Rostedt @ 2026-01-25 20:23 ` Seokwoo Chung 2026-01-29 0:35 ` Masami Hiramatsu 0 siblings, 1 reply; 10+ messages in thread From: Seokwoo Chung @ 2026-01-25 20:23 UTC (permalink / raw) To: Steven Rostedt Cc: mhiramat, corbet, shuah, mathieu.desnoyers, linux-kernel, linux-trace-kernel, linux-doc, linux-kselftest On Tue, Jan 20, 2026 at 03:53:40PM -0500, Steven Rostedt wrote: > On Sat, 17 Jan 2026 20:18:13 -0500 > "Seokwoo Chung (Ryan)" <seokwoo.chung130@gmail.com> wrote: > > > Update fprobe event documentation to describe comma-separated symbol lists, > > exclusions, and explicit suffixes. > > Usually, the documentation updates comes *after* the changes. > > -- Steve > Thanks for the comment. As you noticed, I sent another patch since I forgot to put log. That said, please let me know if you want me to continue on this series. My apologies on the ordering. I noted after Masami mentioned but I misordered when sending. Thank you. Best regards, Ryan Chung > > > > Signed-off-by: Seokwoo Chung (Ryan) <seokwoo.chung130@gmail.com> > > --- > > Documentation/trace/fprobetrace.rst | 17 ++++++++++++++--- > > 1 file changed, 14 insertions(+), 3 deletions(-) > > > > diff --git a/Documentation/trace/fprobetrace.rst b/Documentation/trace/fprobetrace.rst > > index b4c2ca3d02c1..bbcfd57f0005 100644 > > --- a/Documentation/trace/fprobetrace.rst > > +++ b/Documentation/trace/fprobetrace.rst > > @@ -25,14 +25,18 @@ Synopsis of fprobe-events > > ------------------------- > > :: > > > > - f[:[GRP1/][EVENT1]] SYM [FETCHARGS] : Probe on function entry > > - f[MAXACTIVE][:[GRP1/][EVENT1]] SYM%return [FETCHARGS] : Probe on function exit > > + f[:[GRP1/][EVENT1]] SYM[%return] [FETCHARGS] : Single function > > + f[:[GRP1/][EVENT1]] SYM[,[!]SYM[,...]][:entry|:exit] [FETCHARGS] :Multiple > > + function > > t[:[GRP2/][EVENT2]] TRACEPOINT [FETCHARGS] : Probe on tracepoint > > > > GRP1 : Group name for fprobe. If omitted, use "fprobes" for it. > > GRP2 : Group name for tprobe. If omitted, use "tracepoints" for it. > > EVENT1 : Event name for fprobe. If omitted, the event name is > > - "SYM__entry" or "SYM__exit". > > + - For a single literal symbol, the event name is > > + "SYM__entry" or "SYM__exit". > > + - For a *list or any wildcard*, an explicit [GRP1/][EVENT1] is > > + required; otherwise the parser rejects it. > > EVENT2 : Event name for tprobe. If omitted, the event name is > > the same as "TRACEPOINT", but if the "TRACEPOINT" starts > > with a digit character, "_TRACEPOINT" is used. > > @@ -40,6 +44,13 @@ Synopsis of fprobe-events > > can be probed simultaneously, or 0 for the default value > > as defined in Documentation/trace/fprobe.rst > > > > + SYM : Function name or comma-separated list of symbols. > > + - SYM prefixed with "!" are exclusions. > > + - ":entry" suffix means it probes entry of given symbols > > + (default) > > + - ":exit" suffix means it probes exit of given symbols. > > + - "%return" suffix means it probes exit of SYM (single > > + symbol). > > FETCHARGS : Arguments. Each probe can have up to 128 args. > > ARG : Fetch "ARG" function argument using BTF (only for function > > entry or tracepoint.) (\*1) > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v5 v5 1/3] docs: tracing/fprobe: Document list filters and :entry/:exit 2026-01-25 20:23 ` Seokwoo Chung @ 2026-01-29 0:35 ` Masami Hiramatsu 2026-01-31 16:16 ` Seokwoo Chung 0 siblings, 1 reply; 10+ messages in thread From: Masami Hiramatsu @ 2026-01-29 0:35 UTC (permalink / raw) To: Seokwoo Chung Cc: Steven Rostedt, mhiramat, corbet, shuah, mathieu.desnoyers, linux-kernel, linux-trace-kernel, linux-doc, linux-kselftest Hi Ryan, On Sun, 25 Jan 2026 15:23:17 -0500 Seokwoo Chung <seokwoo.chung130@gmail.com> wrote: > On Tue, Jan 20, 2026 at 03:53:40PM -0500, Steven Rostedt wrote: > > On Sat, 17 Jan 2026 20:18:13 -0500 > > "Seokwoo Chung (Ryan)" <seokwoo.chung130@gmail.com> wrote: > > > > > Update fprobe event documentation to describe comma-separated symbol lists, > > > exclusions, and explicit suffixes. > > > > Usually, the documentation updates comes *after* the changes. > > > > -- Steve > > > Thanks for the comment. As you noticed, I sent another patch since I forgot to > put log. That said, please let me know if you want me to continue on this > series. My apologies on the ordering. I noted after Masami mentioned but I > misordered when sending. Thank you. Sorry for replying so late, Can you fix the kernel test robot's error? I think it is almost done. Thank you, > > Best regards, > Ryan Chung > > > > > > Signed-off-by: Seokwoo Chung (Ryan) <seokwoo.chung130@gmail.com> > > > --- > > > Documentation/trace/fprobetrace.rst | 17 ++++++++++++++--- > > > 1 file changed, 14 insertions(+), 3 deletions(-) > > > > > > diff --git a/Documentation/trace/fprobetrace.rst b/Documentation/trace/fprobetrace.rst > > > index b4c2ca3d02c1..bbcfd57f0005 100644 > > > --- a/Documentation/trace/fprobetrace.rst > > > +++ b/Documentation/trace/fprobetrace.rst > > > @@ -25,14 +25,18 @@ Synopsis of fprobe-events > > > ------------------------- > > > :: > > > > > > - f[:[GRP1/][EVENT1]] SYM [FETCHARGS] : Probe on function entry > > > - f[MAXACTIVE][:[GRP1/][EVENT1]] SYM%return [FETCHARGS] : Probe on function exit > > > + f[:[GRP1/][EVENT1]] SYM[%return] [FETCHARGS] : Single function > > > + f[:[GRP1/][EVENT1]] SYM[,[!]SYM[,...]][:entry|:exit] [FETCHARGS] :Multiple > > > + function > > > t[:[GRP2/][EVENT2]] TRACEPOINT [FETCHARGS] : Probe on tracepoint > > > > > > GRP1 : Group name for fprobe. If omitted, use "fprobes" for it. > > > GRP2 : Group name for tprobe. If omitted, use "tracepoints" for it. > > > EVENT1 : Event name for fprobe. If omitted, the event name is > > > - "SYM__entry" or "SYM__exit". > > > + - For a single literal symbol, the event name is > > > + "SYM__entry" or "SYM__exit". > > > + - For a *list or any wildcard*, an explicit [GRP1/][EVENT1] is > > > + required; otherwise the parser rejects it. > > > EVENT2 : Event name for tprobe. If omitted, the event name is > > > the same as "TRACEPOINT", but if the "TRACEPOINT" starts > > > with a digit character, "_TRACEPOINT" is used. > > > @@ -40,6 +44,13 @@ Synopsis of fprobe-events > > > can be probed simultaneously, or 0 for the default value > > > as defined in Documentation/trace/fprobe.rst > > > > > > + SYM : Function name or comma-separated list of symbols. > > > + - SYM prefixed with "!" are exclusions. > > > + - ":entry" suffix means it probes entry of given symbols > > > + (default) > > > + - ":exit" suffix means it probes exit of given symbols. > > > + - "%return" suffix means it probes exit of SYM (single > > > + symbol). > > > FETCHARGS : Arguments. Each probe can have up to 128 args. > > > ARG : Fetch "ARG" function argument using BTF (only for function > > > entry or tracepoint.) (\*1) > > -- Masami Hiramatsu (Google) <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v5 v5 1/3] docs: tracing/fprobe: Document list filters and :entry/:exit 2026-01-29 0:35 ` Masami Hiramatsu @ 2026-01-31 16:16 ` Seokwoo Chung 0 siblings, 0 replies; 10+ messages in thread From: Seokwoo Chung @ 2026-01-31 16:16 UTC (permalink / raw) To: Masami Hiramatsu Cc: Steven Rostedt, corbet, shuah, mathieu.desnoyers, linux-kernel, linux-trace-kernel, linux-doc, linux-kselftest On Thu, Jan 29, 2026 at 09:35:08AM +0900, Masami Hiramatsu wrote: > Hi Ryan, > > On Sun, 25 Jan 2026 15:23:17 -0500 > Seokwoo Chung <seokwoo.chung130@gmail.com> wrote: > > > On Tue, Jan 20, 2026 at 03:53:40PM -0500, Steven Rostedt wrote: > > > On Sat, 17 Jan 2026 20:18:13 -0500 > > > "Seokwoo Chung (Ryan)" <seokwoo.chung130@gmail.com> wrote: > > > > > > > Update fprobe event documentation to describe comma-separated symbol lists, > > > > exclusions, and explicit suffixes. > > > > > > Usually, the documentation updates comes *after* the changes. > > > > > > -- Steve > > > > > Thanks for the comment. As you noticed, I sent another patch since I forgot to > > put log. That said, please let me know if you want me to continue on this > > series. My apologies on the ordering. I noted after Masami mentioned but I > > misordered when sending. Thank you. > > Sorry for replying so late, > Can you fix the kernel test robot's error? I think it is almost done. > > Thank you, > Hi. Thanks for the reply. I will fix and send the next version. > > > > Best regards, > > Ryan Chung > > > > > > > > Signed-off-by: Seokwoo Chung (Ryan) <seokwoo.chung130@gmail.com> > > > > --- > > > > Documentation/trace/fprobetrace.rst | 17 ++++++++++++++--- > > > > 1 file changed, 14 insertions(+), 3 deletions(-) > > > > > > > > diff --git a/Documentation/trace/fprobetrace.rst b/Documentation/trace/fprobetrace.rst > > > > index b4c2ca3d02c1..bbcfd57f0005 100644 > > > > --- a/Documentation/trace/fprobetrace.rst > > > > +++ b/Documentation/trace/fprobetrace.rst > > > > @@ -25,14 +25,18 @@ Synopsis of fprobe-events > > > > ------------------------- > > > > :: > > > > > > > > - f[:[GRP1/][EVENT1]] SYM [FETCHARGS] : Probe on function entry > > > > - f[MAXACTIVE][:[GRP1/][EVENT1]] SYM%return [FETCHARGS] : Probe on function exit > > > > + f[:[GRP1/][EVENT1]] SYM[%return] [FETCHARGS] : Single function > > > > + f[:[GRP1/][EVENT1]] SYM[,[!]SYM[,...]][:entry|:exit] [FETCHARGS] :Multiple > > > > + function > > > > t[:[GRP2/][EVENT2]] TRACEPOINT [FETCHARGS] : Probe on tracepoint > > > > > > > > GRP1 : Group name for fprobe. If omitted, use "fprobes" for it. > > > > GRP2 : Group name for tprobe. If omitted, use "tracepoints" for it. > > > > EVENT1 : Event name for fprobe. If omitted, the event name is > > > > - "SYM__entry" or "SYM__exit". > > > > + - For a single literal symbol, the event name is > > > > + "SYM__entry" or "SYM__exit". > > > > + - For a *list or any wildcard*, an explicit [GRP1/][EVENT1] is > > > > + required; otherwise the parser rejects it. > > > > EVENT2 : Event name for tprobe. If omitted, the event name is > > > > the same as "TRACEPOINT", but if the "TRACEPOINT" starts > > > > with a digit character, "_TRACEPOINT" is used. > > > > @@ -40,6 +44,13 @@ Synopsis of fprobe-events > > > > can be probed simultaneously, or 0 for the default value > > > > as defined in Documentation/trace/fprobe.rst > > > > > > > > + SYM : Function name or comma-separated list of symbols. > > > > + - SYM prefixed with "!" are exclusions. > > > > + - ":entry" suffix means it probes entry of given symbols > > > > + (default) > > > > + - ":exit" suffix means it probes exit of given symbols. > > > > + - "%return" suffix means it probes exit of SYM (single > > > > + symbol). > > > > FETCHARGS : Arguments. Each probe can have up to 128 args. > > > > ARG : Fetch "ARG" function argument using BTF (only for function > > > > entry or tracepoint.) (\*1) > > > > > > -- > Masami Hiramatsu (Google) <mhiramat@kernel.org> Best regards, Ryan Chung ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v5 v5 2/3] tracing/fprobe: Support comma-separated symbols and :entry/:exit 2026-01-18 1:18 [PATCH v5 v5 0/3] tracing/fprobe: Support comma-separated symbols and :entry/:exit Seokwoo Chung (Ryan) 2026-01-18 1:18 ` [PATCH v5 v5 1/3] docs: tracing/fprobe: Document list filters " Seokwoo Chung (Ryan) @ 2026-01-18 1:18 ` Seokwoo Chung (Ryan) 2026-01-18 6:36 ` kernel test robot 2026-01-29 4:24 ` Masami Hiramatsu 2026-01-18 1:18 ` [PATCH v5 v5 3/3] selftests/ftrace: Add accept cases for fprobe list syntax Seokwoo Chung (Ryan) 2 siblings, 2 replies; 10+ messages in thread From: Seokwoo Chung (Ryan) @ 2026-01-18 1:18 UTC (permalink / raw) To: rostedt, mhiramat, corbet, shuah Cc: mathieu.desnoyers, linux-kernel, linux-trace-kernel, linux-doc, linux-kselftest, Seokwoo Chung (Ryan) - Update DEFINE_FREE to use standard __free() - Extend fprobe to support multiple symbols per event. Add parsing logic for lists, ! exclusions, and explicit suffixes. Update tracefs/README to reflect the new syntax Signed-off-by: Seokwoo Chung (Ryan) <seokwoo.chung130@gmail.com> --- kernel/trace/trace.c | 3 +- kernel/trace/trace_fprobe.c | 209 +++++++++++++++++++++++++++--------- 2 files changed, 163 insertions(+), 49 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index baec63134ab6..10cdcc7b194e 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -5578,7 +5578,8 @@ static const char readme_msg[] = "\t r[maxactive][:[<group>/][<event>]] <place> [<args>]\n" #endif #ifdef CONFIG_FPROBE_EVENTS - "\t f[:[<group>/][<event>]] <func-name>[%return] [<args>]\n" + "\t f[:[<group>/][<event>]] <func-name>[:entry|:exit] [<args>]\n" + "\t (single symbols still accept %return)\n" "\t t[:[<group>/][<event>]] <tracepoint> [<args>]\n" #endif #ifdef CONFIG_HIST_TRIGGERS diff --git a/kernel/trace/trace_fprobe.c b/kernel/trace/trace_fprobe.c index 262c0556e4af..5a2a41eea603 100644 --- a/kernel/trace/trace_fprobe.c +++ b/kernel/trace/trace_fprobe.c @@ -187,11 +187,14 @@ DEFINE_FREE(tuser_put, struct tracepoint_user *, */ struct trace_fprobe { struct dyn_event devent; + char *filter; struct fprobe fp; + bool list_mode; + char *nofilter; const char *symbol; + struct trace_probe tp; bool tprobe; struct tracepoint_user *tuser; - struct trace_probe tp; }; static bool is_trace_fprobe(struct dyn_event *ev) @@ -559,6 +562,8 @@ static void free_trace_fprobe(struct trace_fprobe *tf) trace_probe_cleanup(&tf->tp); if (tf->tuser) tracepoint_user_put(tf->tuser); + kfree(tf->filter); + kfree(tf->nofilter); kfree(tf->symbol); kfree(tf); } @@ -838,7 +843,12 @@ static int __register_trace_fprobe(struct trace_fprobe *tf) if (trace_fprobe_is_tracepoint(tf)) return __regsiter_tracepoint_fprobe(tf); - /* TODO: handle filter, nofilter or symbol list */ + /* Registration path: + * - list_mode: pass filter/nofilter + * - single: pass symbol only (legacy) + */ + if (tf->list_mode) + return register_fprobe(&tf->fp, tf->filter, tf->nofilter); return register_fprobe(&tf->fp, tf->symbol, NULL); } @@ -1154,60 +1164,119 @@ static struct notifier_block tprobe_event_module_nb = { }; #endif /* CONFIG_MODULES */ -static int parse_symbol_and_return(int argc, const char *argv[], - char **symbol, bool *is_return, - bool is_tracepoint) +static bool has_wildcard(const char *s) { - char *tmp = strchr(argv[1], '%'); - int i; + return s && (strchr(s, '*') || strchr(s, '?')); +} - if (tmp) { - int len = tmp - argv[1]; +static int parse_fprobe_spec(const char *in, bool is_tracepoint, + char **base, bool *is_return, bool *list_mode, + char **filter, char **nofilter) +{ + char *work __free(kfree) = NULL; + char *b __free(kfree) = NULL; + char *f __free(kfree) = NULL; + char *nf __free(kfree) = NULL; + bool legacy_ret = false; + bool list = false; + const char *p; + int ret = 0; - if (!is_tracepoint && !strcmp(tmp, "%return")) { - *is_return = true; - } else { - trace_probe_log_err(len, BAD_ADDR_SUFFIX); - return -EINVAL; - } - *symbol = kmemdup_nul(argv[1], len, GFP_KERNEL); - } else - *symbol = kstrdup(argv[1], GFP_KERNEL); - if (!*symbol) - return -ENOMEM; + if (!in || !base || !is_return || !list_mode || !filter || !nofilter) + return -EINVAL; - if (*is_return) - return 0; + *base = NULL; *filter = NULL; *nofilter = NULL; + *is_return = false; *list_mode = false; if (is_tracepoint) { - tmp = *symbol; - while (*tmp && (isalnum(*tmp) || *tmp == '_')) - tmp++; - if (*tmp) { - /* find a wrong character. */ - trace_probe_log_err(tmp - *symbol, BAD_TP_NAME); - kfree(*symbol); - *symbol = NULL; + if (strchr(in, ',') || strchr(in, ':')) return -EINVAL; - } + if (strstr(in, "%return")) + return -EINVAL; + for (p = in; *p; p++) + if (!isalnum(*p) && *p != '_') + return -EINVAL; + b = kstrdup(in, GFP_KERNEL); + if (!b) + return -ENOMEM; + *base = no_free_ptr(b); + return 0; } - /* If there is $retval, this should be a return fprobe. */ - for (i = 2; i < argc; i++) { - tmp = strstr(argv[i], "$retval"); - if (tmp && !isalnum(tmp[7]) && tmp[7] != '_') { - if (is_tracepoint) { - trace_probe_log_set_index(i); - trace_probe_log_err(tmp - argv[i], RETVAL_ON_PROBE); - kfree(*symbol); - *symbol = NULL; + work = kstrdup(in, GFP_KERNEL); + if (!work) + return -ENOMEM; + + p = strstr(work, "%return"); + if (p && p[7] == '\0') { + *is_return = true; + legacy_ret = true; + *(char *)p = '\0'; + } else { + /* + * If "symbol:entry" or "symbol:exit" is given, it is new + * style probe. + */ + p = strrchr(work, ':'); + if (p) { + if (!strcmp(p, ":exit")) { + *is_return = true; + *(char *)p = '\0'; + } else if (!strcmp(p, ":entry")) { + *(char *)p = '\0'; + } else { return -EINVAL; } - *is_return = true; - break; } } - return 0; + + list = !!strchr(work, ','); + + if (list && legacy_ret) { + return -EINVAL; + } + + if (legacy_ret) + *is_return = true; + + b = kstrdup(work, GFP_KERNEL); + if (!b) + return -ENOMEM; + + if (list) { + char *tmp = b, *tok; + size_t fsz, nfsz; + + fsz = nfsz = strlen(b) + 1; + + f = kzalloc(fsz, GFP_KERNEL); + nf = kzalloc(nfsz, GFP_KERNEL); + if (!f || !nf) + return -ENOMEM; + + while ((tok = strsep(&tmp, ",")) != NULL) { + char *dst; + bool neg = (*tok == '!'); + + if (*tok == '\0') { + trace_probe_log_err(tmp - b - 1, BAD_TP_NAME); + return -EINVAL; + + if (neg) + tok++; + dst = neg ? nf : f; + if (dst[0] != '\0') + strcat(dst, ","); + strcat(dst, tok); + } + *list_mode = true; + } + + *base = no_free_ptr(b); + *filter = no_free_ptr(f); + *nofilter = no_free_ptr(nf); + + return ret; } static int trace_fprobe_create_internal(int argc, const char *argv[], @@ -1241,6 +1310,8 @@ static int trace_fprobe_create_internal(int argc, const char *argv[], const char *event = NULL, *group = FPROBE_EVENT_SYSTEM; struct module *mod __free(module_put) = NULL; const char **new_argv __free(kfree) = NULL; + char *parsed_nofilter __free(kfree) = NULL; + char *parsed_filter __free(kfree) = NULL; char *symbol __free(kfree) = NULL; char *ebuf __free(kfree) = NULL; char *gbuf __free(kfree) = NULL; @@ -1249,6 +1320,7 @@ static int trace_fprobe_create_internal(int argc, const char *argv[], char *dbuf __free(kfree) = NULL; int i, new_argc = 0, ret = 0; bool is_tracepoint = false; + bool list_mode = false; bool is_return = false; if ((argv[0][0] != 'f' && argv[0][0] != 't') || argc < 2) @@ -1270,11 +1342,26 @@ static int trace_fprobe_create_internal(int argc, const char *argv[], trace_probe_log_set_index(1); - /* a symbol(or tracepoint) must be specified */ - ret = parse_symbol_and_return(argc, argv, &symbol, &is_return, is_tracepoint); + /* Parse spec early (single vs list, suffix, base symbol) */ + ret = parse_fprobe_spec(argv[1], is_tracepoint, &symbol, &is_return, + &list_mode, &parsed_filter, &parsed_nofilter); if (ret < 0) return -EINVAL; + for (i = 2; i < argc; i++) { + char *tmp = strstr(argv[i], "$retval"); + + if (tmp && !isalnum(tmp[7]) && tmp[7] != '_') { + if (is_tracepoint) { + trace_probe_log_set_index(i); + trace_probe_log_err(tmp - argv[i], RETVAL_ON_PROBE); + return -EINVAL; + } + is_return = true; + break; + } + } + trace_probe_log_set_index(0); if (event) { gbuf = kmalloc(MAX_EVENT_NAME_LEN, GFP_KERNEL); @@ -1287,6 +1374,15 @@ static int trace_fprobe_create_internal(int argc, const char *argv[], } if (!event) { + /* + * Event name rules: + * - For list/wildcard: require explicit [GROUP/]EVENT + * - For single literal: autogenerate symbol__entry/symbol__exit + */ + if (list_mode || has_wildcard(symbol)) { + trace_probe_log_err(0, NO_GROUP_NAME); + return -EINVAL; + } ebuf = kmalloc(MAX_EVENT_NAME_LEN, GFP_KERNEL); if (!ebuf) return -ENOMEM; @@ -1322,7 +1418,8 @@ static int trace_fprobe_create_internal(int argc, const char *argv[], NULL, NULL, NULL, sbuf); } } - if (!ctx->funcname) + + if (!list_mode && !has_wildcard(symbol) && !is_tracepoint) ctx->funcname = symbol; abuf = kmalloc(MAX_BTF_ARGS_LEN, GFP_KERNEL); @@ -1356,6 +1453,21 @@ static int trace_fprobe_create_internal(int argc, const char *argv[], return ret; } + /* carry list parsing result into tf */ + if (!is_tracepoint) { + tf->list_mode = list_mode; + if (parsed_filter) { + tf->filter = kstrdup(parsed_filter, GFP_KERNEL); + if (!tf->filter) + return -ENOMEM; + } + if (parsed_nofilter) { + tf->nofilter = kstrdup(parsed_nofilter, GFP_KERNEL); + if (!tf->nofilter) + return -ENOMEM; + } + } + /* parse arguments */ for (i = 0; i < argc; i++) { trace_probe_log_set_index(i + 2); @@ -1442,8 +1554,9 @@ static int trace_fprobe_show(struct seq_file *m, struct dyn_event *ev) seq_printf(m, ":%s/%s", trace_probe_group_name(&tf->tp), trace_probe_name(&tf->tp)); - seq_printf(m, " %s%s", trace_fprobe_symbol(tf), - trace_fprobe_is_return(tf) ? "%return" : ""); + seq_printf(m, " %s", trace_fprobe_symbol(tf)); + if (!trace_fprobe_is_tracepoint(tf) && trace_fprobe_is_return(tf)) + seq_puts(m, ":exit"); for (i = 0; i < tf->tp.nr_args; i++) seq_printf(m, " %s=%s", tf->tp.args[i].name, tf->tp.args[i].comm); -- 2.43.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v5 v5 2/3] tracing/fprobe: Support comma-separated symbols and :entry/:exit 2026-01-18 1:18 ` [PATCH v5 v5 2/3] tracing/fprobe: Support comma-separated symbols " Seokwoo Chung (Ryan) @ 2026-01-18 6:36 ` kernel test robot 2026-01-29 4:24 ` Masami Hiramatsu 1 sibling, 0 replies; 10+ messages in thread From: kernel test robot @ 2026-01-18 6:36 UTC (permalink / raw) To: Seokwoo Chung (Ryan), rostedt, mhiramat, corbet, shuah Cc: oe-kbuild-all, mathieu.desnoyers, linux-kernel, linux-trace-kernel, linux-doc, linux-kselftest, Seokwoo Chung (Ryan) Hi Seokwoo, kernel test robot noticed the following build errors: [auto build test ERROR on trace/for-next] [also build test ERROR on linus/master v6.19-rc5 next-20260116] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Seokwoo-Chung-Ryan/docs-tracing-fprobe-Document-list-filters-and-entry-exit/20260118-092055 base: https://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace for-next patch link: https://lore.kernel.org/r/20260118011815.56516-3-seokwoo.chung130%40gmail.com patch subject: [PATCH v5 v5 2/3] tracing/fprobe: Support comma-separated symbols and :entry/:exit config: x86_64-randconfig-012-20260118 (https://download.01.org/0day-ci/archive/20260118/202601181443.vv7qeHyx-lkp@intel.com/config) compiler: gcc-14 (Debian 14.2.0-19) 14.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260118/202601181443.vv7qeHyx-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202601181443.vv7qeHyx-lkp@intel.com/ All errors (new ones prefixed by >>): kernel/trace/trace_fprobe.c: In function 'parse_fprobe_spec': kernel/trace/trace_fprobe.c:1282:12: error: invalid storage class for function 'trace_fprobe_create_internal' 1282 | static int trace_fprobe_create_internal(int argc, const char *argv[], | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ kernel/trace/trace_fprobe.c:1513:12: error: invalid storage class for function 'trace_fprobe_create_cb' 1513 | static int trace_fprobe_create_cb(int argc, const char *argv[]) | ^~~~~~~~~~~~~~~~~~~~~~ kernel/trace/trace_fprobe.c:1530:12: error: invalid storage class for function 'trace_fprobe_create' 1530 | static int trace_fprobe_create(const char *raw_command) | ^~~~~~~~~~~~~~~~~~~ kernel/trace/trace_fprobe.c:1535:12: error: invalid storage class for function 'trace_fprobe_release' 1535 | static int trace_fprobe_release(struct dyn_event *ev) | ^~~~~~~~~~~~~~~~~~~~ kernel/trace/trace_fprobe.c:1545:12: error: invalid storage class for function 'trace_fprobe_show' 1545 | static int trace_fprobe_show(struct seq_file *m, struct dyn_event *ev) | ^~~~~~~~~~~~~~~~~ kernel/trace/trace_fprobe.c:1572:12: error: invalid storage class for function 'enable_trace_fprobe' 1572 | static int enable_trace_fprobe(struct trace_event_call *call, | ^~~~~~~~~~~~~~~~~~~ kernel/trace/trace_fprobe.c:1608:12: error: invalid storage class for function 'disable_trace_fprobe' 1608 | static int disable_trace_fprobe(struct trace_event_call *call, | ^~~~~~~~~~~~~~~~~~~~ kernel/trace/trace_fprobe.c:1653:12: error: invalid storage class for function 'fprobe_register' 1653 | static int fprobe_register(struct trace_event_call *event, | ^~~~~~~~~~~~~~~ kernel/trace/trace_fprobe.c:1683:19: error: invalid storage class for function 'init_fprobe_trace_early' 1683 | static __init int init_fprobe_trace_early(void) | ^~~~~~~~~~~~~~~~~~~~~~~ In file included from include/linux/fprobe.h:6, from kernel/trace/trace_fprobe.c:8: >> include/linux/compiler.h:284:51: error: initializer element is not constant 284 | __UNIQUE_ID(__PASTE(addressable_, sym)) = (void *)(uintptr_t)&sym; | ^ include/linux/compiler.h:287:9: note: in expansion of macro '___ADDRESSABLE' 287 | ___ADDRESSABLE(sym, __section(".discard.addressable")) | ^~~~~~~~~~~~~~ include/linux/init.h:251:9: note: in expansion of macro '__ADDRESSABLE' 251 | __ADDRESSABLE(fn) | ^~~~~~~~~~~~~ include/linux/init.h:256:9: note: in expansion of macro '__define_initcall_stub' 256 | __define_initcall_stub(__stub, fn) \ | ^~~~~~~~~~~~~~~~~~~~~~ include/linux/init.h:269:9: note: in expansion of macro '____define_initcall' 269 | ____define_initcall(fn, \ | ^~~~~~~~~~~~~~~~~~~ include/linux/init.h:275:9: note: in expansion of macro '__unique_initcall' 275 | __unique_initcall(fn, id, __sec, __initcall_id(fn)) | ^~~~~~~~~~~~~~~~~ include/linux/init.h:277:35: note: in expansion of macro '___define_initcall' 277 | #define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id) | ^~~~~~~~~~~~~~~~~~ include/linux/init.h:295:41: note: in expansion of macro '__define_initcall' 295 | #define core_initcall(fn) __define_initcall(fn, 1) | ^~~~~~~~~~~~~~~~~ kernel/trace/trace_fprobe.c:1702:1: note: in expansion of macro 'core_initcall' 1702 | core_initcall(init_fprobe_trace_early); | ^~~~~~~~~~~~~ kernel/trace/trace_fprobe.c:1702:1: error: expected declaration or statement at end of input kernel/trace/trace_fprobe.c: At top level: kernel/trace/trace_fprobe.c:28:12: warning: 'trace_fprobe_create' used but never defined 28 | static int trace_fprobe_create(const char *raw_command); | ^~~~~~~~~~~~~~~~~~~ kernel/trace/trace_fprobe.c:29:12: warning: 'trace_fprobe_show' used but never defined 29 | static int trace_fprobe_show(struct seq_file *m, struct dyn_event *ev); | ^~~~~~~~~~~~~~~~~ kernel/trace/trace_fprobe.c:30:12: warning: 'trace_fprobe_release' used but never defined 30 | static int trace_fprobe_release(struct dyn_event *ev); | ^~~~~~~~~~~~~~~~~~~~ kernel/trace/trace_fprobe.c:741:12: warning: 'fprobe_register' used but never defined 741 | static int fprobe_register(struct trace_event_call *event, | ^~~~~~~~~~~~~~~ kernel/trace/trace_fprobe.c:1653:12: warning: 'fprobe_register' defined but not used [-Wunused-function] 1653 | static int fprobe_register(struct trace_event_call *event, | ^~~~~~~~~~~~~~~ kernel/trace/trace_fprobe.c:1545:12: warning: 'trace_fprobe_show' defined but not used [-Wunused-function] 1545 | static int trace_fprobe_show(struct seq_file *m, struct dyn_event *ev) | ^~~~~~~~~~~~~~~~~ kernel/trace/trace_fprobe.c:1535:12: warning: 'trace_fprobe_release' defined but not used [-Wunused-function] 1535 | static int trace_fprobe_release(struct dyn_event *ev) | ^~~~~~~~~~~~~~~~~~~~ kernel/trace/trace_fprobe.c:1530:12: warning: 'trace_fprobe_create' defined but not used [-Wunused-function] 1530 | static int trace_fprobe_create(const char *raw_command) | ^~~~~~~~~~~~~~~~~~~ vim +284 include/linux/compiler.h 0ef8047b737d74 Juergen Gross 2024-11-29 275 7290d58095712a Ard Biesheuvel 2018-08-21 276 /* 7290d58095712a Ard Biesheuvel 2018-08-21 277 * Force the compiler to emit 'sym' as a symbol, so that we can reference 7290d58095712a Ard Biesheuvel 2018-08-21 278 * it from inline assembler. Necessary in case 'sym' could be inlined 7290d58095712a Ard Biesheuvel 2018-08-21 279 * otherwise, or eliminated entirely due to lack of references that are 7290d58095712a Ard Biesheuvel 2018-08-21 280 * visible to the compiler. 7290d58095712a Ard Biesheuvel 2018-08-21 281 */ 92efda8eb15295 Sami Tolvanen 2022-09-08 282 #define ___ADDRESSABLE(sym, __attrs) \ 92efda8eb15295 Sami Tolvanen 2022-09-08 283 static void * __used __attrs \ 9f14f1f91883aa Josh Poimboeuf 2025-09-17 @284 __UNIQUE_ID(__PASTE(addressable_, sym)) = (void *)(uintptr_t)&sym; 0ef8047b737d74 Juergen Gross 2024-11-29 285 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v5 v5 2/3] tracing/fprobe: Support comma-separated symbols and :entry/:exit 2026-01-18 1:18 ` [PATCH v5 v5 2/3] tracing/fprobe: Support comma-separated symbols " Seokwoo Chung (Ryan) 2026-01-18 6:36 ` kernel test robot @ 2026-01-29 4:24 ` Masami Hiramatsu 1 sibling, 0 replies; 10+ messages in thread From: Masami Hiramatsu @ 2026-01-29 4:24 UTC (permalink / raw) To: Seokwoo Chung (Ryan) Cc: rostedt, corbet, shuah, mathieu.desnoyers, linux-kernel, linux-trace-kernel, linux-doc, linux-kselftest On Sat, 17 Jan 2026 20:18:14 -0500 "Seokwoo Chung (Ryan)" <seokwoo.chung130@gmail.com> wrote: > - Update DEFINE_FREE to use standard __free() > - Extend fprobe to support multiple symbols per event. Add parsing logic for > lists, ! exclusions, and explicit suffixes. Update tracefs/README to reflect > the new syntax > > Signed-off-by: Seokwoo Chung (Ryan) <seokwoo.chung130@gmail.com> > --- > kernel/trace/trace.c | 3 +- > kernel/trace/trace_fprobe.c | 209 +++++++++++++++++++++++++++--------- > 2 files changed, 163 insertions(+), 49 deletions(-) > > diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c > index baec63134ab6..10cdcc7b194e 100644 > --- a/kernel/trace/trace.c > +++ b/kernel/trace/trace.c > @@ -5578,7 +5578,8 @@ static const char readme_msg[] = > "\t r[maxactive][:[<group>/][<event>]] <place> [<args>]\n" > #endif > #ifdef CONFIG_FPROBE_EVENTS > - "\t f[:[<group>/][<event>]] <func-name>[%return] [<args>]\n" > + "\t f[:[<group>/][<event>]] <func-name>[:entry|:exit] [<args>]\n" > + "\t (single symbols still accept %return)\n" > "\t t[:[<group>/][<event>]] <tracepoint> [<args>]\n" > #endif > #ifdef CONFIG_HIST_TRIGGERS > diff --git a/kernel/trace/trace_fprobe.c b/kernel/trace/trace_fprobe.c > index 262c0556e4af..5a2a41eea603 100644 > --- a/kernel/trace/trace_fprobe.c > +++ b/kernel/trace/trace_fprobe.c > @@ -187,11 +187,14 @@ DEFINE_FREE(tuser_put, struct tracepoint_user *, > */ > struct trace_fprobe { > struct dyn_event devent; > + char *filter; > struct fprobe fp; > + bool list_mode; > + char *nofilter; > const char *symbol; > + struct trace_probe tp; > bool tprobe; > struct tracepoint_user *tuser; > - struct trace_probe tp; > }; > > static bool is_trace_fprobe(struct dyn_event *ev) > @@ -559,6 +562,8 @@ static void free_trace_fprobe(struct trace_fprobe *tf) > trace_probe_cleanup(&tf->tp); > if (tf->tuser) > tracepoint_user_put(tf->tuser); > + kfree(tf->filter); > + kfree(tf->nofilter); > kfree(tf->symbol); > kfree(tf); > } > @@ -838,7 +843,12 @@ static int __register_trace_fprobe(struct trace_fprobe *tf) > if (trace_fprobe_is_tracepoint(tf)) > return __regsiter_tracepoint_fprobe(tf); > > - /* TODO: handle filter, nofilter or symbol list */ > + /* Registration path: > + * - list_mode: pass filter/nofilter > + * - single: pass symbol only (legacy) > + */ > + if (tf->list_mode) > + return register_fprobe(&tf->fp, tf->filter, tf->nofilter); > return register_fprobe(&tf->fp, tf->symbol, NULL); > } > > @@ -1154,60 +1164,119 @@ static struct notifier_block tprobe_event_module_nb = { > }; > #endif /* CONFIG_MODULES */ > > -static int parse_symbol_and_return(int argc, const char *argv[], > - char **symbol, bool *is_return, > - bool is_tracepoint) > +static bool has_wildcard(const char *s) > { > - char *tmp = strchr(argv[1], '%'); > - int i; > + return s && (strchr(s, '*') || strchr(s, '?')); > +} > > - if (tmp) { > - int len = tmp - argv[1]; > +static int parse_fprobe_spec(const char *in, bool is_tracepoint, > + char **base, bool *is_return, bool *list_mode, > + char **filter, char **nofilter) > +{ > + char *work __free(kfree) = NULL; > + char *b __free(kfree) = NULL; > + char *f __free(kfree) = NULL; > + char *nf __free(kfree) = NULL; > + bool legacy_ret = false; > + bool list = false; > + const char *p; > + int ret = 0; > > - if (!is_tracepoint && !strcmp(tmp, "%return")) { > - *is_return = true; > - } else { > - trace_probe_log_err(len, BAD_ADDR_SUFFIX); > - return -EINVAL; > - } > - *symbol = kmemdup_nul(argv[1], len, GFP_KERNEL); > - } else > - *symbol = kstrdup(argv[1], GFP_KERNEL); > - if (!*symbol) > - return -ENOMEM; > + if (!in || !base || !is_return || !list_mode || !filter || !nofilter) > + return -EINVAL; > > - if (*is_return) > - return 0; > + *base = NULL; *filter = NULL; *nofilter = NULL; > + *is_return = false; *list_mode = false; > > if (is_tracepoint) { > - tmp = *symbol; > - while (*tmp && (isalnum(*tmp) || *tmp == '_')) > - tmp++; > - if (*tmp) { > - /* find a wrong character. */ > - trace_probe_log_err(tmp - *symbol, BAD_TP_NAME); > - kfree(*symbol); > - *symbol = NULL; > + if (strchr(in, ',') || strchr(in, ':')) > return -EINVAL; > - } > + if (strstr(in, "%return")) > + return -EINVAL; These checks look redundant. because below ensures there is no ',', '/' and '%'. > + for (p = in; *p; p++) > + if (!isalnum(*p) && *p != '_') > + return -EINVAL; Please report parse error via trace_probe_log_err() function so that user can check what was wrong via tracefs/error_log file. E.g. trace_probe_log_err(p - in, BAD_TP_NAME); > + b = kstrdup(in, GFP_KERNEL); > + if (!b) > + return -ENOMEM; Note: ENOMEM does not need to report via error_log. > + *base = no_free_ptr(b); > + return 0; > } > > - /* If there is $retval, this should be a return fprobe. */ > - for (i = 2; i < argc; i++) { > - tmp = strstr(argv[i], "$retval"); > - if (tmp && !isalnum(tmp[7]) && tmp[7] != '_') { > - if (is_tracepoint) { > - trace_probe_log_set_index(i); > - trace_probe_log_err(tmp - argv[i], RETVAL_ON_PROBE); > - kfree(*symbol); > - *symbol = NULL; > + work = kstrdup(in, GFP_KERNEL); > + if (!work) > + return -ENOMEM; > + > + p = strstr(work, "%return"); > + if (p && p[7] == '\0') { > + *is_return = true; > + legacy_ret = true; > + *(char *)p = '\0'; > + } else { > + /* > + * If "symbol:entry" or "symbol:exit" is given, it is new > + * style probe. > + */ > + p = strrchr(work, ':'); > + if (p) { > + if (!strcmp(p, ":exit")) { > + *is_return = true; > + *(char *)p = '\0'; > + } else if (!strcmp(p, ":entry")) { > + *(char *)p = '\0'; > + } else { > return -EINVAL; > } > - *is_return = true; > - break; > } > } > - return 0; > + > + list = !!strchr(work, ','); > + > + if (list && legacy_ret) { > + return -EINVAL; > + } You don't need braces for the above block. > + > + if (legacy_ret) > + *is_return = true; > + > + b = kstrdup(work, GFP_KERNEL); > + if (!b) > + return -ENOMEM; > + > + if (list) { Could you make this block as an independent function? > + char *tmp = b, *tok; > + size_t fsz, nfsz; > + > + fsz = nfsz = strlen(b) + 1; > + > + f = kzalloc(fsz, GFP_KERNEL); > + nf = kzalloc(nfsz, GFP_KERNEL); > + if (!f || !nf) > + return -ENOMEM; > + > + while ((tok = strsep(&tmp, ",")) != NULL) { > + char *dst; > + bool neg = (*tok == '!'); > + > + if (*tok == '\0') { > + trace_probe_log_err(tmp - b - 1, BAD_TP_NAME); > + return -EINVAL; You missed close brace '}' here. And that makes the build failure. Can you fix it and run all tests under tools/testing/selftests/ftrace/ with your change? Thank you, > + > + if (neg) > + tok++; > + dst = neg ? nf : f; > + if (dst[0] != '\0') > + strcat(dst, ","); > + strcat(dst, tok); > + } > + *list_mode = true; > + } > + > + *base = no_free_ptr(b); > + *filter = no_free_ptr(f); > + *nofilter = no_free_ptr(nf); > + > + return ret; > } > > static int trace_fprobe_create_internal(int argc, const char *argv[], > @@ -1241,6 +1310,8 @@ static int trace_fprobe_create_internal(int argc, const char *argv[], > const char *event = NULL, *group = FPROBE_EVENT_SYSTEM; > struct module *mod __free(module_put) = NULL; > const char **new_argv __free(kfree) = NULL; > + char *parsed_nofilter __free(kfree) = NULL; > + char *parsed_filter __free(kfree) = NULL; > char *symbol __free(kfree) = NULL; > char *ebuf __free(kfree) = NULL; > char *gbuf __free(kfree) = NULL; > @@ -1249,6 +1320,7 @@ static int trace_fprobe_create_internal(int argc, const char *argv[], > char *dbuf __free(kfree) = NULL; > int i, new_argc = 0, ret = 0; > bool is_tracepoint = false; > + bool list_mode = false; > bool is_return = false; > > if ((argv[0][0] != 'f' && argv[0][0] != 't') || argc < 2) > @@ -1270,11 +1342,26 @@ static int trace_fprobe_create_internal(int argc, const char *argv[], > > trace_probe_log_set_index(1); > > - /* a symbol(or tracepoint) must be specified */ > - ret = parse_symbol_and_return(argc, argv, &symbol, &is_return, is_tracepoint); > + /* Parse spec early (single vs list, suffix, base symbol) */ > + ret = parse_fprobe_spec(argv[1], is_tracepoint, &symbol, &is_return, > + &list_mode, &parsed_filter, &parsed_nofilter); > if (ret < 0) > return -EINVAL; > > + for (i = 2; i < argc; i++) { > + char *tmp = strstr(argv[i], "$retval"); > + > + if (tmp && !isalnum(tmp[7]) && tmp[7] != '_') { > + if (is_tracepoint) { > + trace_probe_log_set_index(i); > + trace_probe_log_err(tmp - argv[i], RETVAL_ON_PROBE); > + return -EINVAL; > + } > + is_return = true; > + break; > + } > + } > + > trace_probe_log_set_index(0); > if (event) { > gbuf = kmalloc(MAX_EVENT_NAME_LEN, GFP_KERNEL); > @@ -1287,6 +1374,15 @@ static int trace_fprobe_create_internal(int argc, const char *argv[], > } > > if (!event) { > + /* > + * Event name rules: > + * - For list/wildcard: require explicit [GROUP/]EVENT > + * - For single literal: autogenerate symbol__entry/symbol__exit > + */ > + if (list_mode || has_wildcard(symbol)) { > + trace_probe_log_err(0, NO_GROUP_NAME); > + return -EINVAL; > + } > ebuf = kmalloc(MAX_EVENT_NAME_LEN, GFP_KERNEL); > if (!ebuf) > return -ENOMEM; > @@ -1322,7 +1418,8 @@ static int trace_fprobe_create_internal(int argc, const char *argv[], > NULL, NULL, NULL, sbuf); > } > } > - if (!ctx->funcname) > + > + if (!list_mode && !has_wildcard(symbol) && !is_tracepoint) > ctx->funcname = symbol; > > abuf = kmalloc(MAX_BTF_ARGS_LEN, GFP_KERNEL); > @@ -1356,6 +1453,21 @@ static int trace_fprobe_create_internal(int argc, const char *argv[], > return ret; > } > > + /* carry list parsing result into tf */ > + if (!is_tracepoint) { > + tf->list_mode = list_mode; > + if (parsed_filter) { > + tf->filter = kstrdup(parsed_filter, GFP_KERNEL); > + if (!tf->filter) > + return -ENOMEM; > + } > + if (parsed_nofilter) { > + tf->nofilter = kstrdup(parsed_nofilter, GFP_KERNEL); > + if (!tf->nofilter) > + return -ENOMEM; > + } > + } > + > /* parse arguments */ > for (i = 0; i < argc; i++) { > trace_probe_log_set_index(i + 2); > @@ -1442,8 +1554,9 @@ static int trace_fprobe_show(struct seq_file *m, struct dyn_event *ev) > seq_printf(m, ":%s/%s", trace_probe_group_name(&tf->tp), > trace_probe_name(&tf->tp)); > > - seq_printf(m, " %s%s", trace_fprobe_symbol(tf), > - trace_fprobe_is_return(tf) ? "%return" : ""); > + seq_printf(m, " %s", trace_fprobe_symbol(tf)); > + if (!trace_fprobe_is_tracepoint(tf) && trace_fprobe_is_return(tf)) > + seq_puts(m, ":exit"); > > for (i = 0; i < tf->tp.nr_args; i++) > seq_printf(m, " %s=%s", tf->tp.args[i].name, tf->tp.args[i].comm); > -- > 2.43.0 > -- Masami Hiramatsu (Google) <mhiramat@kernel.org> ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v5 v5 3/3] selftests/ftrace: Add accept cases for fprobe list syntax 2026-01-18 1:18 [PATCH v5 v5 0/3] tracing/fprobe: Support comma-separated symbols and :entry/:exit Seokwoo Chung (Ryan) 2026-01-18 1:18 ` [PATCH v5 v5 1/3] docs: tracing/fprobe: Document list filters " Seokwoo Chung (Ryan) 2026-01-18 1:18 ` [PATCH v5 v5 2/3] tracing/fprobe: Support comma-separated symbols " Seokwoo Chung (Ryan) @ 2026-01-18 1:18 ` Seokwoo Chung (Ryan) 2 siblings, 0 replies; 10+ messages in thread From: Seokwoo Chung (Ryan) @ 2026-01-18 1:18 UTC (permalink / raw) To: rostedt, mhiramat, corbet, shuah Cc: mathieu.desnoyers, linux-kernel, linux-trace-kernel, linux-doc, linux-kselftest, Seokwoo Chung (Ryan) Add selftest for comma-separated symbol lists, exclusion (!), and explicit :entry/:exit suffixes. Verify that excluded symbols are not attached and that enabled_functions shows the correct probes. Signed-off-by: Seokwoo Chung (Ryan) <seokwoo.chung130@gmail.com> --- .../ftrace/test.d/dynevent/fprobe_list.tc | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 tools/testing/selftests/ftrace/test.d/dynevent/fprobe_list.tc diff --git a/tools/testing/selftests/ftrace/test.d/dynevent/fprobe_list.tc b/tools/testing/selftests/ftrace/test.d/dynevent/fprobe_list.tc new file mode 100644 index 000000000000..45e57c6f487d --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/dynevent/fprobe_list.tc @@ -0,0 +1,92 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Fprobe event list syntax and :entry/:exit suffixes +# requires: dynamic_events "f[:[<group>/][<event>]] <func-name>[:entry|:exit] [<args>]":README + +# Setup symbols to test. These are common kernel functions. +PLACE=vfs_read +PLACE2=vfs_write +PLACE3=vfs_open + +echo 0 > events/enable +echo > dynamic_events + +# Get baseline count of enabled functions (should be 0 if clean, but be safe) +if [ -f enabled_functions ]; then + ocnt=`cat enabled_functions | wc -l` +else + ocnt=0 +fi + +# Test 1: List default (entry) with exclusion +# Target: Trace vfs_read and vfs_open, but EXCLUDE vfs_write +echo "f:test/list_entry $PLACE,!$PLACE2,$PLACE3" >> dynamic_events +grep -q "test/list_entry" dynamic_events +test -d events/test/list_entry + +echo 1 > events/test/list_entry/enable + +grep -q "$PLACE" enabled_functions +grep -q "$PLACE3" enabled_functions +! grep -q "$PLACE2" enabled_functions + +# Check count (Baseline + 2 new functions) +cnt=`cat enabled_functions | wc -l` +if [ $cnt -ne $((ocnt + 2)) ]; then + exit_fail +fi + +# Cleanup Test 1 +echo 0 > events/test/list_entry/enable +echo "-:test/list_entry" >> dynamic_events +! grep -q "test/list_entry" dynamic_events + +# Count should return to baseline +cnt=`cat enabled_functions | wc -l` +if [ $cnt -ne $ocnt ]; then + exit_fail +fi + +# Test 2: List with explicit :entry suffix +# (Should behave exactly like Test 1) +echo "f:test/list_entry_exp $PLACE,!$PLACE2,$PLACE3:entry" >> dynamic_events +grep -q "test/list_entry_exp" dynamic_events +test -d events/test/list_entry_exp + +echo 1 > events/test/list_entry_exp/enable + +grep -q "$PLACE" enabled_functions +grep -q "$PLACE3" enabled_functions +! grep -q "$PLACE2" enabled_functions + +cnt=`cat enabled_functions | wc -l` +if [ $cnt -ne $((ocnt + 2)) ]; then + exit_fail +fi + +# Cleanup Test 2 +echo 0 > events/test/list_entry_exp/enable +echo "-:test/list_entry_exp" >> dynamic_events + +# Test 3: List with :exit suffix +echo "f:test/list_exit $PLACE,!$PLACE2,$PLACE3:exit" >> dynamic_events +grep -q "test/list_exit" dynamic_events +test -d events/test/list_exit + +echo 1 > events/test/list_exit/enable + +# Even for return probes, enabled_functions lists the attached symbols +grep -q "$PLACE" enabled_functions +grep -q "$PLACE3" enabled_functions +! grep -q "$PLACE2" enabled_functions + +cnt=`cat enabled_functions | wc -l` +if [ $cnt -ne $((ocnt + 2)) ]; then + exit_fail +fi + +# Cleanup Test 3 +echo 0 > events/test/list_exit/enable +echo "-:test/list_exit" >> dynamic_events + +clear_trace -- 2.43.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-01-31 16:16 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-01-18 1:18 [PATCH v5 v5 0/3] tracing/fprobe: Support comma-separated symbols and :entry/:exit Seokwoo Chung (Ryan) 2026-01-18 1:18 ` [PATCH v5 v5 1/3] docs: tracing/fprobe: Document list filters " Seokwoo Chung (Ryan) 2026-01-20 20:53 ` Steven Rostedt 2026-01-25 20:23 ` Seokwoo Chung 2026-01-29 0:35 ` Masami Hiramatsu 2026-01-31 16:16 ` Seokwoo Chung 2026-01-18 1:18 ` [PATCH v5 v5 2/3] tracing/fprobe: Support comma-separated symbols " Seokwoo Chung (Ryan) 2026-01-18 6:36 ` kernel test robot 2026-01-29 4:24 ` Masami Hiramatsu 2026-01-18 1:18 ` [PATCH v5 v5 3/3] selftests/ftrace: Add accept cases for fprobe list syntax Seokwoo Chung (Ryan)
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox