[PATCH v14 17/32] perf trace: Don't pass evsel with sample

From: Ian Rogers

Date: Wed May 20 2026 - 15:23:06 EST


As struct perf_sample now directly contains its own resolved evsel pointer,
passing the evsel separately is redundant and clutters the interface.

Remove the redundant evsel parameter from trace-specific handlers and
structures, ensuring the tool always directly accesses the evsel bound to the
sample. This simplifies the API signatures and eliminates the risk of passing
an inconsistent evsel.

Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx>
Acked-by: Namhyung Kim <namhyung@xxxxxxxxxx>
---
tools/perf/builtin-trace.c | 52 ++++++++++++++++++++------------------
1 file changed, 28 insertions(+), 24 deletions(-)

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 4bc30ad8fb07..d4fafae853d4 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2608,7 +2608,7 @@ static struct syscall *trace__find_syscall(struct trace *trace, int e_machine, i
return sc;
}

-typedef int (*tracepoint_handler)(struct trace *trace, struct evsel *evsel,
+typedef int (*tracepoint_handler)(struct trace *trace,
union perf_event *event,
struct perf_sample *sample);

@@ -2805,10 +2805,11 @@ static void *syscall__augmented_args(struct syscall *sc, struct perf_sample *sam
return NULL;
}

-static int trace__sys_enter(struct trace *trace, struct evsel *evsel,
+static int trace__sys_enter(struct trace *trace,
union perf_event *event __maybe_unused,
struct perf_sample *sample)
{
+ struct evsel *evsel = sample->evsel;
char *msg;
void *args;
int printed = 0;
@@ -2954,10 +2955,11 @@ static int trace__fprintf_callchain(struct trace *trace, struct perf_sample *sam
return sample__fprintf_callchain(sample, 38, print_opts, get_tls_callchain_cursor(), symbol_conf.bt_stop_list, trace->output);
}

-static int trace__sys_exit(struct trace *trace, struct evsel *evsel,
+static int trace__sys_exit(struct trace *trace,
union perf_event *event __maybe_unused,
struct perf_sample *sample)
{
+ struct evsel *evsel = sample->evsel;
long ret;
u64 duration = 0;
bool duration_calculated = false;
@@ -3094,7 +3096,7 @@ errno_print: {
return err;
}

-static int trace__vfs_getname(struct trace *trace, struct evsel *evsel __maybe_unused,
+static int trace__vfs_getname(struct trace *trace,
union perf_event *event __maybe_unused,
struct perf_sample *sample)
{
@@ -3155,7 +3157,7 @@ static int trace__vfs_getname(struct trace *trace, struct evsel *evsel __maybe_u
return 0;
}

-static int trace__sched_stat_runtime(struct trace *trace, struct evsel *evsel,
+static int trace__sched_stat_runtime(struct trace *trace,
union perf_event *event __maybe_unused,
struct perf_sample *sample)
{
@@ -3177,7 +3179,7 @@ static int trace__sched_stat_runtime(struct trace *trace, struct evsel *evsel,

out_dump:
fprintf(trace->output, "%s: comm=%s,pid=%u,runtime=%" PRIu64 ",vruntime=%" PRIu64 ")\n",
- evsel->name,
+ sample->evsel->name,
perf_sample__strval(sample, "comm"),
(pid_t)perf_sample__intval(sample, "pid"),
runtime,
@@ -3288,10 +3290,11 @@ static size_t trace__fprintf_tp_fields(struct trace *trace, struct perf_sample *
return fprintf(trace->output, "%.*s", (int)printed, bf);
}

-static int trace__event_handler(struct trace *trace, struct evsel *evsel,
+static int trace__event_handler(struct trace *trace,
union perf_event *event __maybe_unused,
struct perf_sample *sample)
{
+ struct evsel *evsel = sample->evsel;
struct thread *thread;
int callchain_ret = 0;

@@ -3400,7 +3403,6 @@ static void print_location(FILE *f, struct perf_sample *sample,
}

static int trace__pgfault(struct trace *trace,
- struct evsel *evsel,
union perf_event *event __maybe_unused,
struct perf_sample *sample)
{
@@ -3429,7 +3431,7 @@ static int trace__pgfault(struct trace *trace,
if (ttrace == NULL)
goto out_put;

- if (evsel->core.attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ) {
+ if (sample->evsel->core.attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ) {
ttrace->pfmaj++;
trace->pfmaj++;
} else {
@@ -3446,7 +3448,7 @@ static int trace__pgfault(struct trace *trace,
sample->cpu, trace->output);

fprintf(trace->output, "%sfault [",
- evsel->core.attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ ?
+ sample->evsel->core.attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ ?
"maj" : "min");

print_location(trace->output, sample, &al, false, true);
@@ -3471,7 +3473,8 @@ static int trace__pgfault(struct trace *trace,
if (callchain_ret > 0)
trace__fprintf_callchain(trace, sample);
else if (callchain_ret < 0)
- pr_err("Problem processing %s callchain, skipping...\n", evsel__name(evsel));
+ pr_err("Problem processing %s callchain, skipping...\n",
+ evsel__name(sample->evsel));

++trace->nr_events_printed;
out:
@@ -3483,7 +3486,6 @@ static int trace__pgfault(struct trace *trace,
}

static void trace__set_base_time(struct trace *trace,
- struct evsel *evsel,
struct perf_sample *sample)
{
/*
@@ -3495,7 +3497,7 @@ static void trace__set_base_time(struct trace *trace,
* appears in our event stream (vfs_getname comes to mind).
*/
if (trace->base_time == 0 && !trace->full_time &&
- (evsel->core.attr.sample_type & PERF_SAMPLE_TIME))
+ (sample->evsel->core.attr.sample_type & PERF_SAMPLE_TIME))
trace->base_time = sample->time;
}

@@ -3515,11 +3517,11 @@ static int trace__process_sample(const struct perf_tool *tool,
if (thread && thread__is_filtered(thread))
goto out;

- trace__set_base_time(trace, evsel, sample);
+ trace__set_base_time(trace, sample);

if (handler) {
++trace->nr_events;
- handler(trace, evsel, event, sample);
+ handler(trace, event, sample);
}
out:
thread__put(thread);
@@ -3661,32 +3663,34 @@ static void evlist__free_syscall_tp_fields(struct evlist *evlist)
static void trace__handle_event(struct trace *trace, union perf_event *event, struct perf_sample *sample)
{
const u32 type = event->header.type;
- struct evsel *evsel;

if (type != PERF_RECORD_SAMPLE) {
trace__process_event(trace, trace->host, event, sample);
return;
}

- evsel = evlist__id2evsel(trace->evlist, sample->id);
- if (evsel == NULL) {
+ if (sample->evsel == NULL)
+ sample->evsel = evlist__id2evsel(trace->evlist, sample->id);
+
+ if (sample->evsel == NULL) {
fprintf(trace->output, "Unknown tp ID %" PRIu64 ", skipping...\n", sample->id);
return;
}

- if (evswitch__discard(&trace->evswitch, evsel))
+ if (evswitch__discard(&trace->evswitch, sample->evsel))
return;

- trace__set_base_time(trace, evsel, sample);
+ trace__set_base_time(trace, sample);

- if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT &&
+ if (sample->evsel->core.attr.type == PERF_TYPE_TRACEPOINT &&
sample->raw_data == NULL) {
fprintf(trace->output, "%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n",
- evsel__name(evsel), sample->tid,
+ evsel__name(sample->evsel), sample->tid,
sample->cpu, sample->raw_size);
} else {
- tracepoint_handler handler = evsel->handler;
- handler(trace, evsel, event, sample);
+ tracepoint_handler handler = sample->evsel->handler;
+
+ handler(trace, event, sample);
}

if (trace->nr_events_printed >= trace->max_events && trace->max_events != ULONG_MAX)
--
2.54.0.746.g67dd491aae-goog