* [PATCH 1/2] perf evsel: Add lazy-initialized probe type detection helpers
2026-06-16 1:31 [PATCHES 0/2] perf tools: Add cached probe type detection for evsel Arnaldo Carvalho de Melo
@ 2026-06-16 1:31 ` Arnaldo Carvalho de Melo
0 siblings, 0 replies; 8+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-16 1:31 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 2-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.
Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/evsel.c | 44 +++++++++++++++++++++++++++++++++++++++++
tools/perf/util/evsel.h | 5 +++++
2 files changed, 49 insertions(+)
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 05fa0010c858a51e..223571091f09f9ee 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -254,6 +254,49 @@ 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,
+};
+
+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
+ 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 +456,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..bf75381526147f92 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:2;
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] 8+ 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
0 siblings, 1 reply; 8+ 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] 8+ 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; 8+ 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] 8+ messages in thread
* [PATCHES v3 0/2] perf tools: Add cached probe type detection for evsel
@ 2026-06-16 18:25 Arnaldo Carvalho de Melo
2026-06-16 18:25 ` [PATCH 1/2] perf evsel: Add lazy-initialized probe type detection helpers Arnaldo Carvalho de Melo
2026-06-16 18:25 ` [PATCH 2/2] perf trace: Guard __probe_ip suppression with evsel__is_probe() Arnaldo Carvalho de Melo
0 siblings, 2 replies; 8+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-16 18:25 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.
Patch 3 adds inline stubs for evsel__field() and evsel__common_field()
when libtraceevent is absent. These were previously declared
unconditionally but defined only inside #ifdef HAVE_LIBTRACEEVENT,
which was harmless until patch 1 added a call from always-compiled
code in evsel.c.
Build-tested with gcc and clang.
Changes in v3:
- Add patch 3: no-libtraceevent stubs for evsel__field() and
evsel__common_field(). Without this, NO_LIBTRACEEVENT=1 builds
fail to link because evsel__resolve_probe_type() calls
evsel__field() unconditionally (sashiko-bot).
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 (3):
perf evsel: Add lazy-initialized probe type detection helpers
perf trace: Guard __probe_ip suppression with evsel__is_probe()
perf evsel: Add no-libtraceevent stubs for evsel__field() and evsel__common_field()
tools/perf/builtin-trace.c | 2 +-
tools/perf/util/evsel.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++
tools/perf/util/evsel.h | 19 +++++++++++++++++
3 files changed, 73 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.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/2] perf evsel: Add lazy-initialized probe type detection helpers
2026-06-16 18:25 [PATCHES v3 0/2] perf tools: Add cached probe type detection for evsel Arnaldo Carvalho de Melo
@ 2026-06-16 18:25 ` Arnaldo Carvalho de Melo
2026-06-16 18:40 ` sashiko-bot
2026-06-16 18:25 ` [PATCH 2/2] perf trace: Guard __probe_ip suppression with evsel__is_probe() Arnaldo Carvalho de Melo
1 sibling, 1 reply; 8+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-16 18:25 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 | 19 +++++++++++++++
2 files changed, 72 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..163fc2b6a7eacca4 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)
@@ -397,8 +402,22 @@ struct tep_format_field;
u64 format_field__intval(struct tep_format_field *field, struct perf_sample *sample, bool needs_swap);
+#ifdef HAVE_LIBTRACEEVENT
struct tep_format_field *evsel__field(struct evsel *evsel, const char *name);
struct tep_format_field *evsel__common_field(struct evsel *evsel, const char *name);
+#else
+static inline struct tep_format_field *
+evsel__field(struct evsel *evsel __maybe_unused, const char *name __maybe_unused)
+{
+ return NULL;
+}
+
+static inline struct tep_format_field *
+evsel__common_field(struct evsel *evsel __maybe_unused, const char *name __maybe_unused)
+{
+ return NULL;
+}
+#endif
bool __evsel__match(const struct evsel *evsel, u32 type, u64 config);
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/2] perf trace: Guard __probe_ip suppression with evsel__is_probe()
2026-06-16 18:25 [PATCHES v3 0/2] perf tools: Add cached probe type detection for evsel Arnaldo Carvalho de Melo
2026-06-16 18:25 ` [PATCH 1/2] perf evsel: Add lazy-initialized probe type detection helpers Arnaldo Carvalho de Melo
@ 2026-06-16 18:25 ` Arnaldo Carvalho de Melo
1 sibling, 0 replies; 8+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-16 18:25 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] 8+ messages in thread
* Re: [PATCH 1/2] perf evsel: Add lazy-initialized probe type detection helpers
2026-06-16 18:25 ` [PATCH 1/2] perf evsel: Add lazy-initialized probe type detection helpers Arnaldo Carvalho de Melo
@ 2026-06-16 18:40 ` sashiko-bot
2026-06-16 18:47 ` Arnaldo Carvalho de Melo
0 siblings, 1 reply; 8+ messages in thread
From: sashiko-bot @ 2026-06-16 18:40 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:
- [Medium] Ftrace-based return probes (kretprobe, uretprobe, fexit) are incorrectly classified as PROBE__NOPE because they lack the __probe_ip field.
--
commit fc58c48524e7c99a712f8fb111c94abfbbeb4b6d
Author: Arnaldo Carvalho de Melo <acme@redhat.com>
perf evsel: Add lazy-initialized probe type detection helpers
This commit introduces lazy-initialized probe type detection helpers for
perf evsel. It caches the probe type lookup in a 3-bit field within struct
evsel to avoid repeated PMU list walks via evsel__find_pmu().
> diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
> index 05fa0010c858a..ea9fa04429f08 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"))
[Severity: Medium]
The commit message mentions this covers kprobes, uprobes, and fprobes
regardless of their group or system name by checking the __probe_ip field.
Will this successfully detect ftrace-based return probes?
It looks like return probes like kretprobe, uretprobe, and fexit do not
contain a __probe_ip field, but instead define __probe_func and
__probe_ret_ip.
If evsel__field() returns NULL for return probes, won't they incorrectly
fall through to the else branch and be classified as PROBE__NOPE?
> + evsel->probe_type = PROBE__FTRACE;
> + else
> + evsel->probe_type = PROBE__NOPE;
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260616182546.8892-1-acme@kernel.org?part=1
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] perf evsel: Add lazy-initialized probe type detection helpers
2026-06-16 18:40 ` sashiko-bot
@ 2026-06-16 18:47 ` Arnaldo Carvalho de Melo
0 siblings, 0 replies; 8+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-06-16 18:47 UTC (permalink / raw)
To: sashiko-reviews; +Cc: linux-perf-users
On Tue, Jun 16, 2026 at 06:40:05PM +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Medium] Ftrace-based return probes (kretprobe, uretprobe, fexit) are incorrectly classified as PROBE__NOPE because they lack the __probe_ip field.
> --
>
> commit fc58c48524e7c99a712f8fb111c94abfbbeb4b6d
> Author: Arnaldo Carvalho de Melo <acme@redhat.com>
>
> perf evsel: Add lazy-initialized probe type detection helpers
>
> This commit introduces lazy-initialized probe type detection helpers for
> perf evsel. It caches the probe type lookup in a 3-bit field within struct
> evsel to avoid repeated PMU list walks via evsel__find_pmu().
>
> > diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
> > index 05fa0010c858a..ea9fa04429f08 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"))
>
> [Severity: Medium]
> The commit message mentions this covers kprobes, uprobes, and fprobes
> regardless of their group or system name by checking the __probe_ip field.
> Will this successfully detect ftrace-based return probes?
>
> It looks like return probes like kretprobe, uretprobe, and fexit do not
> contain a __probe_ip field, but instead define __probe_func and
> __probe_ret_ip.
>
> If evsel__field() returns NULL for return probes, won't they incorrectly
> fall through to the else branch and be classified as PROBE__NOPE?
Sure, and this is an interesting observation, we need to cover
__probe_ret_ip in the same fashion as __probe_ip, probably __probe_func
as well, but this should be done in an upcoming patch series.
I'll make sure to save this in a TODO file for later work.
- Arnaldo
> > + evsel->probe_type = PROBE__FTRACE;
> > + else
> > + evsel->probe_type = PROBE__NOPE;
> > +}
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260616182546.8892-1-acme@kernel.org?part=1
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-06-16 18:47 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-16 18:25 [PATCHES v3 0/2] perf tools: Add cached probe type detection for evsel Arnaldo Carvalho de Melo
2026-06-16 18:25 ` [PATCH 1/2] perf evsel: Add lazy-initialized probe type detection helpers Arnaldo Carvalho de Melo
2026-06-16 18:40 ` sashiko-bot
2026-06-16 18:47 ` Arnaldo Carvalho de Melo
2026-06-16 18:25 ` [PATCH 2/2] perf trace: Guard __probe_ip suppression with evsel__is_probe() Arnaldo Carvalho de Melo
-- strict thread matches above, loose matches on Subject: below --
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 1:31 [PATCHES 0/2] perf tools: Add cached probe type detection for evsel Arnaldo Carvalho de Melo
2026-06-16 1:31 ` [PATCH 1/2] perf evsel: Add lazy-initialized probe type detection helpers Arnaldo Carvalho de Melo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox