From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Namhyung Kim <namhyung@kernel.org>
Cc: Ingo Molnar <mingo@kernel.org>,
Thomas Gleixner <tglx@linutronix.de>,
James Clark <james.clark@linaro.org>,
Jiri Olsa <jolsa@kernel.org>, Ian Rogers <irogers@google.com>,
Adrian Hunter <adrian.hunter@intel.com>,
Clark Williams <williams@redhat.com>,
linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org,
Arnaldo Carvalho de Melo <acme@redhat.com>,
"Claude Opus 4.6" <noreply@anthropic.com>
Subject: [PATCH 1/2] perf evsel: Add lazy-initialized probe type detection helpers
Date: Tue, 16 Jun 2026 15:25:45 -0300 [thread overview]
Message-ID: <20260616182546.8892-2-acme@kernel.org> (raw)
In-Reply-To: <20260616182546.8892-1-acme@kernel.org>
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
next prev parent reply other threads:[~2026-06-16 18:25 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
2026-06-16 18:40 ` [PATCH 1/2] perf evsel: Add lazy-initialized probe type detection helpers 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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260616182546.8892-2-acme@kernel.org \
--to=acme@kernel.org \
--cc=acme@redhat.com \
--cc=adrian.hunter@intel.com \
--cc=irogers@google.com \
--cc=james.clark@linaro.org \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=namhyung@kernel.org \
--cc=noreply@anthropic.com \
--cc=tglx@linutronix.de \
--cc=williams@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.