* [PATCHES v2 0/2] perf tools: Add cached probe type detection for evsel
@ 2026-06-16 15:44 Arnaldo Carvalho de Melo
2026-06-16 15:44 ` [PATCH 1/2] perf evsel: Add lazy-initialized probe type detection helpers Arnaldo Carvalho de Melo
2026-06-16 15:44 ` [PATCH 2/2] perf trace: Guard __probe_ip suppression with evsel__is_probe() Arnaldo Carvalho de Melo
0 siblings, 2 replies; 4+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-16 15:44 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, linux-kernel, linux-perf-users,
Arnaldo Carvalho de Melo, Aaron Tomlin
Hi,
Checking whether an evsel is a kprobe or uprobe currently requires
walking the PMU list via evsel__find_pmu() on every call. This is
wasteful when the same evsel is checked repeatedly in hot paths like
trace__fprintf_tp_fields().
Patch 1 adds evsel__is_kprobe(), evsel__is_uprobe(), and
evsel__is_probe() helpers that resolve the probe type on first call
and cache the result in a 3-bit field that fits in existing struct
padding.
Detection covers both PMU-based probes (kprobe/uprobe PMU, detected
by PMU name) and ftrace-based dynamic probes (kprobes/uprobes/fprobes
created via tracefs, which report as PMU "tracepoint"). Ftrace probes
are detected by the __probe_ip field that the kernel adds to all
dynamic probe formats — this is authoritative regardless of the
group/system name the user chose.
Patch 2 is the first user: it guards the __probe_ip field name
comparison in perf trace with evsel__is_probe(), so the strcmp is
skipped entirely for the common case of non-probe tracepoint events.
Build-tested with gcc and clang.
Changes in v2 (patch 1 only):
- Detect ftrace-based dynamic probes (kprobes/uprobes/fprobes created
via tracefs) that report PMU "tracepoint" instead of "kprobe"/
"uprobe". Check for the __probe_ip field presence in the tracepoint
format. Without this, evsel__is_probe() returned false for ftrace
probes, breaking __probe_ip suppression in perf trace for probes
created via 'perf probe' (sashiko-bot).
- Widen probe_type bitfield from 2 to 3 bits for PROBE__FTRACE.
Arnaldo Carvalho de Melo (2):
perf evsel: Add lazy-initialized probe type detection helpers
perf trace: Guard __probe_ip suppression with evsel__is_probe()
tools/perf/builtin-trace.c | 2 +-
tools/perf/util/evsel.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++
tools/perf/util/evsel.h | 5 +++++
3 files changed, 59 insertions(+), 1 deletion(-)
Cc: Aaron Tomlin <atomlin@atomlin.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Developed with AI assistance (Claude/sashiko), tagged in commits.
Thanks,
- Arnaldo
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] perf evsel: Add lazy-initialized probe type detection helpers
2026-06-16 15:44 [PATCHES v2 0/2] perf tools: Add cached probe type detection for evsel Arnaldo Carvalho de Melo
@ 2026-06-16 15:44 ` Arnaldo Carvalho de Melo
2026-06-16 16:03 ` sashiko-bot
2026-06-16 15:44 ` [PATCH 2/2] perf trace: Guard __probe_ip suppression with evsel__is_probe() Arnaldo Carvalho de Melo
1 sibling, 1 reply; 4+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-16 15:44 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, linux-kernel, linux-perf-users,
Arnaldo Carvalho de Melo, Claude Opus 4.6
From: Arnaldo Carvalho de Melo <acme@redhat.com>
Several places in perf need to check whether an evsel is a kprobe or
uprobe, which requires looking up the PMU by name via evsel__find_pmu().
This lookup walks the PMU list each time, which is wasteful when the
same evsel is checked repeatedly.
Add evsel__is_kprobe(), evsel__is_uprobe(), and evsel__is_probe() that
resolve the probe type on first call via evsel__pmu_name() and cache
the result in a 3-bit field (probe_type) in struct evsel. The field
fits in existing padding after the bool fields, so struct size does not
grow.
The enum uses PROBE__UNKNOWN (0) as the uninitialized sentinel —
explicitly set in evsel__init() — so the lookup happens on first use.
PROBE__NOPE (1) caches "not a probe" to avoid repeated negative lookups.
PMU-based probes (kprobe/uprobe PMU) are detected by PMU name.
Ftrace-based dynamic probes (created via tracefs, reported as PMU
"tracepoint") are detected by the __probe_ip field that the kernel
adds to all dynamic probe formats. This covers kprobes, uprobes, and
fprobes regardless of their group/system name.
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/evsel.c | 53 +++++++++++++++++++++++++++++++++++++++++
tools/perf/util/evsel.h | 5 ++++
2 files changed, 58 insertions(+)
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 05fa0010c858a51e..ea9fa04429f08a9e 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -254,6 +254,58 @@ const char *evsel__pmu_name(const struct evsel *evsel)
return event_type(evsel->core.attr.type);
}
+enum evsel_probe_type {
+ PROBE__UNKNOWN = 0,
+ PROBE__NOPE = 1,
+ PROBE__KPROBE = 2,
+ PROBE__UPROBE = 3,
+ /*
+ * Ftrace-based dynamic probes (kprobes/uprobes/fprobes created via
+ * tracefs) report PMU "tracepoint", not "kprobe"/"uprobe". Detect
+ * them by the __probe_ip field that the kernel adds to all dynamic
+ * probe formats.
+ */
+ PROBE__FTRACE = 4,
+};
+
+static void evsel__resolve_probe_type(struct evsel *evsel)
+{
+ const char *name = evsel__pmu_name(evsel);
+
+ if (!strcmp(name, "kprobe"))
+ evsel->probe_type = PROBE__KPROBE;
+ else if (!strcmp(name, "uprobe"))
+ evsel->probe_type = PROBE__UPROBE;
+ else if (!strcmp(name, "tracepoint") && evsel__field(evsel, "__probe_ip"))
+ evsel->probe_type = PROBE__FTRACE;
+ else
+ evsel->probe_type = PROBE__NOPE;
+}
+
+bool evsel__is_probe(struct evsel *evsel)
+{
+ if (evsel->probe_type == PROBE__UNKNOWN)
+ evsel__resolve_probe_type(evsel);
+
+ return evsel->probe_type > PROBE__NOPE;
+}
+
+bool evsel__is_kprobe(struct evsel *evsel)
+{
+ if (evsel->probe_type == PROBE__UNKNOWN)
+ evsel__resolve_probe_type(evsel);
+
+ return evsel->probe_type == PROBE__KPROBE;
+}
+
+bool evsel__is_uprobe(struct evsel *evsel)
+{
+ if (evsel->probe_type == PROBE__UNKNOWN)
+ evsel__resolve_probe_type(evsel);
+
+ return evsel->probe_type == PROBE__UPROBE;
+}
+
#define FD(e, x, y) (*(int *)xyarray__entry(e->core.fd, x, y))
int __evsel__sample_size(u64 sample_type)
@@ -413,6 +465,7 @@ void evsel__init(struct evsel *evsel,
evsel->supported = true;
evsel->alternate_hw_config = PERF_COUNT_HW_MAX;
evsel->script_output_type = -1; // FIXME: OUTPUT_TYPE_UNSET, see builtin-script.c
+ evsel->probe_type = PROBE__UNKNOWN;
}
struct evsel *evsel__new_idx(struct perf_event_attr *attr, int idx)
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 8009be22cc3f1055..300c64d1e0c15e7d 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -126,6 +126,7 @@ struct evsel {
bool needs_uniquify;
bool fallenback_eacces;
bool fallenback_eopnotsupp;
+ u8 probe_type:3;
struct hashmap *per_pkg_mask;
int err;
int script_output_type;
@@ -259,6 +260,10 @@ struct perf_pmu *evsel__find_pmu(const struct evsel *evsel);
const char *evsel__pmu_name(const struct evsel *evsel);
bool evsel__is_aux_event(const struct evsel *evsel);
+bool evsel__is_probe(struct evsel *evsel);
+bool evsel__is_kprobe(struct evsel *evsel);
+bool evsel__is_uprobe(struct evsel *evsel);
+
struct evsel *evsel__new_idx(struct perf_event_attr *attr, int idx);
static inline struct evsel *evsel__new(struct perf_event_attr *attr)
--
2.54.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] perf trace: Guard __probe_ip suppression with evsel__is_probe()
2026-06-16 15:44 [PATCHES v2 0/2] perf tools: Add cached probe type detection for evsel Arnaldo Carvalho de Melo
2026-06-16 15:44 ` [PATCH 1/2] perf evsel: Add lazy-initialized probe type detection helpers Arnaldo Carvalho de Melo
@ 2026-06-16 15:44 ` Arnaldo Carvalho de Melo
1 sibling, 0 replies; 4+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-16 15:44 UTC (permalink / raw)
To: Namhyung Kim
Cc: Ingo Molnar, Thomas Gleixner, James Clark, Jiri Olsa, Ian Rogers,
Adrian Hunter, Clark Williams, linux-kernel, linux-perf-users,
Arnaldo Carvalho de Melo, Aaron Tomlin, Claude
From: Arnaldo Carvalho de Melo <acme@redhat.com>
trace__fprintf_tp_fields() compares every field name against
"__probe_ip" for all tracepoint events, but this field is only
implicitly added by the Ftrace subsystem to bare dynamic probes.
Add an evsel__is_probe() check before the strcmp so the string
comparison is skipped entirely for non-probe events.
Reviewed-by: Aaron Tomlin <atomlin@atomlin.com>
Assisted-by: Claude <noreply@anthropic.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/builtin-trace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index a8492da23a9cc178..57f3f14c5d435805 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -3267,7 +3267,7 @@ static size_t trace__fprintf_tp_fields(struct trace *trace, struct perf_sample *
* If verbose mode is enabled, ensure it is formatted as a
* hexadecimal memory address rather than a signed integer.
*/
- if (!strcmp(field->name, "__probe_ip")) {
+ if (evsel__is_probe(evsel) && !strcmp(field->name, "__probe_ip")) {
if (!verbose)
continue;
--
2.54.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 1/2] perf evsel: Add lazy-initialized probe type detection helpers
2026-06-16 15:44 ` [PATCH 1/2] perf evsel: Add lazy-initialized probe type detection helpers Arnaldo Carvalho de Melo
@ 2026-06-16 16:03 ` sashiko-bot
0 siblings, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-06-16 16:03 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo; +Cc: linux-perf-users
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Calling `evsel__field()` unconditionally without a `HAVE_LIBTRACEEVENT` feature guard or fallback stub causes linker errors when libtraceevent is omitted.
--
commit 1f0d622399b5f71c138cdc45ef059e320a38fea7
Author: Arnaldo Carvalho de Melo <acme@redhat.com>
perf evsel: Add lazy-initialized probe type detection helpers
This commit adds helpers to lazily detect and cache whether an evsel is a
kprobe, uprobe, or ftrace-based dynamic probe. It introduces a 3-bit
probe_type field in struct evsel to avoid repeated PMU lookups.
> diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
> --- a/tools/perf/util/evsel.c
> +++ b/tools/perf/util/evsel.c
[ ... ]
> +static void evsel__resolve_probe_type(struct evsel *evsel)
> +{
> + const char *name = evsel__pmu_name(evsel);
> +
> + if (!strcmp(name, "kprobe"))
> + evsel->probe_type = PROBE__KPROBE;
> + else if (!strcmp(name, "uprobe"))
> + evsel->probe_type = PROBE__UPROBE;
> + else if (!strcmp(name, "tracepoint") && evsel__field(evsel, "__probe_ip"))
[Severity: High]
Will this cause a linker error when compiling without libtraceevent?
This unconditionally calls evsel__field. The actual implementation of
evsel__field is strictly wrapped in HAVE_LIBTRACEEVENT guards. Without a
fallback stub in tools/perf/util/evsel.h that returns NULL for the
!HAVE_LIBTRACEEVENT case, omitting libtraceevent could cause an undefined
reference error during linking since evsel__is_probe prevents dead-code
elimination of this function.
> + evsel->probe_type = PROBE__FTRACE;
> + else
> + evsel->probe_type = PROBE__NOPE;
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260616154446.7206-1-acme@kernel.org?part=1
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-06-16 16:03 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-16 15:44 [PATCHES v2 0/2] perf tools: Add cached probe type detection for evsel Arnaldo Carvalho de Melo
2026-06-16 15:44 ` [PATCH 1/2] perf evsel: Add lazy-initialized probe type detection helpers Arnaldo Carvalho de Melo
2026-06-16 16:03 ` sashiko-bot
2026-06-16 15:44 ` [PATCH 2/2] perf trace: Guard __probe_ip suppression with evsel__is_probe() Arnaldo Carvalho de Melo
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.