All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHES 0/2] perf tools: Add cached probe type detection for evsel
@ 2026-06-16  1:31 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
  2026-06-16  1:31 ` [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  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, 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 2-bit field that fits in existing struct
padding.

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.

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    | 44 ++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/evsel.h    |  5 +++++
 3 files changed, 50 insertions(+), 1 deletion(-)

Developed with AI assistance (Claude), 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  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
  2026-06-16  1:31 ` [PATCH 2/2] perf trace: Guard __probe_ip suppression with evsel__is_probe() Arnaldo Carvalho de Melo
  1 sibling, 0 replies; 4+ 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] 4+ messages in thread

* [PATCH 2/2] perf trace: Guard __probe_ip suppression with evsel__is_probe()
  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
@ 2026-06-16  1:31 ` Arnaldo Carvalho de Melo
  2026-06-16  1:54   ` sashiko-bot
  1 sibling, 1 reply; 4+ 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, 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.

Cc: 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 2/2] perf trace: Guard __probe_ip suppression with evsel__is_probe()
  2026-06-16  1:31 ` [PATCH 2/2] perf trace: Guard __probe_ip suppression with evsel__is_probe() Arnaldo Carvalho de Melo
@ 2026-06-16  1:54   ` sashiko-bot
  0 siblings, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-06-16  1:54 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] The `evsel__is_probe()` check evaluates to false for Ftrace dynamic probes, breaking the intended suppression of the `__probe_ip` field.
--

commit 0e15cda4a40a59d474ee0a3a5cdae64267b1f3b2
Author: Arnaldo Carvalho de Melo <acme@redhat.com>

perf trace: Guard __probe_ip suppression with evsel__is_probe()

This commit adds an evsel__is_probe() check to trace__fprintf_tp_fields()
to skip the string comparison of __probe_ip for non-probe events.

> diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
> index a8492da23a9cc..57f3f14c5d435 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")) {

[Severity: High]
Does this check accidentally disable the suppression entirely for Ftrace
dynamic probes?

Since trace__fprintf_tp_fields() processes fields specifically for tracepoint
events (where evsel__tp_format() succeeds), the event has type
PERF_TYPE_TRACEPOINT. For these events, the PMU name is "tracepoint".

However, evsel__is_probe() resolves the probe type by checking if the PMU
name is "kprobe" or "uprobe". If it evaluates to false here because the PMU
is "tracepoint", the condition short-circuits and the __probe_ip field is
no longer suppressed.

Will this cause __probe_ip to be erroneously printed for all dynamic probes
instead of being suppressed by default as intended?

>  			if (!verbose)
>  				continue;
>

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260616013157.38960-1-acme@kernel.org?part=2

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-06-16  1:54 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
2026-06-16  1:31 ` [PATCH 2/2] perf trace: Guard __probe_ip suppression with evsel__is_probe() Arnaldo Carvalho de Melo
2026-06-16  1:54   ` sashiko-bot

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.