[PATCH v14 12/32] perf inject: Don't pass evsel with sample

From: Ian Rogers

Date: Wed May 20 2026 - 18:16:03 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 inject-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-inject.c | 52 ++++++++++++++++--------------
tools/perf/util/synthetic-events.c | 30 ++++++++---------
tools/perf/util/synthetic-events.h | 2 --
3 files changed, 40 insertions(+), 44 deletions(-)

diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 3d48c8140ad9..f0d7b4888598 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -147,14 +147,12 @@ struct event_entry {
static int tool__inject_build_id(const struct perf_tool *tool,
struct perf_sample *sample,
struct machine *machine,
- const struct evsel *evsel,
__u16 misc,
const char *filename,
struct dso *dso, u32 flags);
static int tool__inject_mmap2_build_id(const struct perf_tool *tool,
struct perf_sample *sample,
struct machine *machine,
- const struct evsel *evsel,
__u16 misc,
__u32 pid, __u32 tid,
__u64 start, __u64 len, __u64 pgoff,
@@ -357,7 +355,6 @@ perf_inject__cut_auxtrace_sample(struct perf_inject *inject,
typedef int (*inject_handler)(const struct perf_tool *tool,
union perf_event *event,
struct perf_sample *sample,
- struct evsel *evsel,
struct machine *machine);

static int perf_event__repipe_sample(const struct perf_tool *tool,
@@ -370,7 +367,7 @@ static int perf_event__repipe_sample(const struct perf_tool *tool,

if (evsel && evsel->handler) {
inject_handler f = evsel->handler;
- return f(tool, event, sample, evsel, machine);
+ return f(tool, event, sample, machine);
}

build_id__mark_dso_hit(tool, event, sample, machine);
@@ -585,11 +582,12 @@ static int perf_event__repipe_common_mmap(const struct perf_tool *tool,
}

if (dso && !dso__hit(dso)) {
- struct evsel *evsel = evlist__event2evsel(inject->session->evlist, event);
+ if (!sample->evsel)
+ sample->evsel = evlist__event2evsel(inject->session->evlist, event);

- if (evsel) {
+ if (sample->evsel) {
dso__set_hit(dso);
- tool__inject_build_id(tool, sample, machine, evsel,
+ tool__inject_build_id(tool, sample, machine,
/*misc=*/sample->cpumode,
filename, dso, flags);
}
@@ -616,23 +614,26 @@ static int perf_event__repipe_common_mmap(const struct perf_tool *tool,
}
if ((inject->build_id_style == BID_RWS__MMAP2_BUILDID_ALL) &&
!(event->header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID)) {
- struct evsel *evsel = evlist__event2evsel(inject->session->evlist, event);
+ struct evsel *saved_evsel = sample->evsel;

- if (evsel && !dso_sought) {
+ sample->evsel = evlist__event2evsel(inject->session->evlist, event);
+ if (sample->evsel && !dso_sought) {
dso = findnew_dso(pid, tid, filename, dso_id, machine);
dso_sought = true;
}
- if (evsel && dso &&
- !tool__inject_mmap2_build_id(tool, sample, machine, evsel,
+ if (sample->evsel && dso &&
+ !tool__inject_mmap2_build_id(tool, sample, machine,
sample->cpumode | PERF_RECORD_MISC_MMAP_BUILD_ID,
pid, tid, start, len, pgoff,
dso,
prot, flags,
filename)) {
/* Injected mmap2 so no need to repipe. */
+ sample->evsel = saved_evsel;
dso__put(dso);
return 0;
}
+ sample->evsel = saved_evsel;
}
dso__put(dso);
if (inject->build_id_style == BID_RWS__MMAP2_BUILDID_LAZY)
@@ -837,7 +838,6 @@ static bool perf_inject__lookup_known_build_id(struct perf_inject *inject,
static int tool__inject_build_id(const struct perf_tool *tool,
struct perf_sample *sample,
struct machine *machine,
- const struct evsel *evsel,
__u16 misc,
const char *filename,
struct dso *dso, u32 flags)
@@ -861,7 +861,7 @@ static int tool__inject_build_id(const struct perf_tool *tool,

err = perf_event__synthesize_build_id(tool, sample, machine,
perf_event__repipe,
- evsel, misc, dso__bid(dso),
+ misc, dso__bid(dso),
filename);
if (err) {
pr_err("Can't synthesize build_id event for %s\n", filename);
@@ -874,7 +874,6 @@ static int tool__inject_build_id(const struct perf_tool *tool,
static int tool__inject_mmap2_build_id(const struct perf_tool *tool,
struct perf_sample *sample,
struct machine *machine,
- const struct evsel *evsel,
__u16 misc,
__u32 pid, __u32 tid,
__u64 start, __u64 len, __u64 pgoff,
@@ -897,7 +896,6 @@ static int tool__inject_mmap2_build_id(const struct perf_tool *tool,

err = perf_event__synthesize_mmap2_build_id(tool, sample, machine,
perf_event__repipe,
- evsel,
misc, pid, tid,
start, len, pgoff,
dso__bid(dso),
@@ -914,7 +912,7 @@ static int mark_dso_hit(const struct perf_inject *inject,
const struct perf_tool *tool,
struct perf_sample *sample,
struct machine *machine,
- const struct evsel *mmap_evsel,
+ struct evsel *mmap_evsel,
struct map *map, bool sample_in_dso)
{
struct dso *dso;
@@ -942,9 +940,13 @@ static int mark_dso_hit(const struct perf_inject *inject,
dso = map__dso(map);
if (inject->build_id_style == BID_RWS__INJECT_HEADER_LAZY) {
if (dso && !dso__hit(dso)) {
+ /*
+ * The sample is just read for identifiers which we want
+ * to match the for the event of the sample.
+ */
dso__set_hit(dso);
tool__inject_build_id(tool, sample, machine,
- mmap_evsel, misc, dso__long_name(dso), dso,
+ misc, dso__long_name(dso), dso,
map__flags(map));
}
} else if (inject->build_id_style == BID_RWS__MMAP2_BUILDID_LAZY) {
@@ -952,11 +954,13 @@ static int mark_dso_hit(const struct perf_inject *inject,
const struct build_id null_bid = { .size = 0 };
const struct build_id *bid = dso ? dso__bid(dso) : &null_bid;
const char *filename = dso ? dso__long_name(dso) : "";
+ struct evsel *saved_evsel = sample->evsel;

map__set_hit(map);
+ /* Creating a new mmap2 event which has an evsel for the mmap event. */
+ sample->evsel = mmap_evsel;
perf_event__synthesize_mmap2_build_id(tool, sample, machine,
perf_event__repipe,
- mmap_evsel,
misc,
sample->pid, sample->tid,
map__start(map),
@@ -966,6 +970,7 @@ static int mark_dso_hit(const struct perf_inject *inject,
map__prot(map),
map__flags(map),
filename);
+ sample->evsel = saved_evsel;
}
}
return 0;
@@ -976,7 +981,7 @@ struct mark_dso_hit_args {
const struct perf_tool *tool;
struct perf_sample *sample;
struct machine *machine;
- const struct evsel *mmap_evsel;
+ struct evsel *mmap_evsel;
};

static int mark_dso_hit_callback(struct callchain_cursor_node *node, void *data)
@@ -1031,7 +1036,6 @@ static int perf_event__inject_buildid(const struct perf_tool *tool, union perf_e
static int perf_inject__sched_process_exit(const struct perf_tool *tool,
union perf_event *event __maybe_unused,
struct perf_sample *sample,
- struct evsel *evsel __maybe_unused,
struct machine *machine __maybe_unused)
{
struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
@@ -1051,13 +1055,12 @@ static int perf_inject__sched_process_exit(const struct perf_tool *tool,
static int perf_inject__sched_switch(const struct perf_tool *tool,
union perf_event *event,
struct perf_sample *sample,
- struct evsel *evsel,
struct machine *machine)
{
struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
struct event_entry *ent;

- perf_inject__sched_process_exit(tool, event, sample, evsel, machine);
+ perf_inject__sched_process_exit(tool, event, sample, machine);

ent = malloc(event->header.size + sizeof(struct event_entry));
if (ent == NULL) {
@@ -1076,13 +1079,13 @@ static int perf_inject__sched_switch(const struct perf_tool *tool,
static int perf_inject__sched_stat(const struct perf_tool *tool,
union perf_event *event __maybe_unused,
struct perf_sample *sample,
- struct evsel *evsel,
struct machine *machine)
{
struct event_entry *ent;
union perf_event *event_sw;
struct perf_sample sample_sw;
struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
+ struct evsel *evsel = sample->evsel;
u32 pid = perf_sample__intval(sample, "pid");
int ret;

@@ -1447,7 +1450,7 @@ static int synthesize_build_id(struct perf_inject *inject, struct dso *dso, pid_
dso__set_hit(dso);

return perf_event__synthesize_build_id(&inject->tool, &synth_sample, machine,
- process_build_id, inject__mmap_evsel(inject),
+ process_build_id,
/*misc=*/synth_sample.cpumode,
dso__bid(dso), dso__long_name(dso));
}
@@ -2009,7 +2012,6 @@ static int evsel__check_stype(struct evsel *evsel, u64 sample_type, const char *
static int drop_sample(const struct perf_tool *tool __maybe_unused,
union perf_event *event __maybe_unused,
struct perf_sample *sample __maybe_unused,
- struct evsel *evsel __maybe_unused,
struct machine *machine __maybe_unused)
{
return 0;
diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c
index 85bee747f4cd..de812a2befbc 100644
--- a/tools/perf/util/synthetic-events.c
+++ b/tools/perf/util/synthetic-events.c
@@ -2252,13 +2252,15 @@ int perf_event__synthesize_build_id(const struct perf_tool *tool,
struct perf_sample *sample,
struct machine *machine,
perf_event__handler_t process,
- const struct evsel *evsel,
__u16 misc,
const struct build_id *bid,
const char *filename)
{
union perf_event ev;
size_t len;
+ u64 sample_type = sample->evsel ? sample->evsel->core.attr.sample_type : 0;
+ void *array = &ev;
+ int ret;

len = sizeof(ev.build_id) + strlen(filename) + 1;
len = PERF_ALIGN(len, sizeof(u64));
@@ -2275,23 +2277,17 @@ int perf_event__synthesize_build_id(const struct perf_tool *tool,
ev.build_id.header.size = len;
strcpy(ev.build_id.filename, filename);

- if (evsel) {
- void *array = &ev;
- int ret;
-
- array += ev.header.size;
- ret = perf_event__synthesize_id_sample(array, evsel->core.attr.sample_type, sample);
- if (ret < 0)
- return ret;
-
- if (ret & 7) {
- pr_err("Bad id sample size %d\n", ret);
- return -EINVAL;
- }
+ array += ev.header.size;
+ ret = perf_event__synthesize_id_sample(array, sample_type, sample);
+ if (ret < 0)
+ return ret;

- ev.header.size += ret;
+ if (ret & 7) {
+ pr_err("Bad id sample size %d\n", ret);
+ return -EINVAL;
}

+ ev.header.size += ret;
return process(tool, &ev, sample, machine);
}

@@ -2299,7 +2295,6 @@ int perf_event__synthesize_mmap2_build_id(const struct perf_tool *tool,
struct perf_sample *sample,
struct machine *machine,
perf_event__handler_t process,
- const struct evsel *evsel,
__u16 misc,
__u32 pid, __u32 tid,
__u64 start, __u64 len, __u64 pgoff,
@@ -2309,6 +2304,7 @@ int perf_event__synthesize_mmap2_build_id(const struct perf_tool *tool,
{
union perf_event ev;
size_t ev_len;
+ u64 sample_type = sample->evsel ? sample->evsel->core.attr.sample_type : 0;
void *array;
int ret;

@@ -2339,7 +2335,7 @@ int perf_event__synthesize_mmap2_build_id(const struct perf_tool *tool,

array = &ev;
array += ev.header.size;
- ret = perf_event__synthesize_id_sample(array, evsel->core.attr.sample_type, sample);
+ ret = perf_event__synthesize_id_sample(array, sample_type, sample);
if (ret < 0)
return ret;

diff --git a/tools/perf/util/synthetic-events.h b/tools/perf/util/synthetic-events.h
index b0edad0c3100..473a43a78993 100644
--- a/tools/perf/util/synthetic-events.h
+++ b/tools/perf/util/synthetic-events.h
@@ -50,7 +50,6 @@ int perf_event__synthesize_build_id(const struct perf_tool *tool,
struct perf_sample *sample,
struct machine *machine,
perf_event__handler_t process,
- const struct evsel *evsel,
__u16 misc,
const struct build_id *bid,
const char *filename);
@@ -58,7 +57,6 @@ int perf_event__synthesize_mmap2_build_id(const struct perf_tool *tool,
struct perf_sample *sample,
struct machine *machine,
perf_event__handler_t process,
- const struct evsel *evsel,
__u16 misc,
__u32 pid, __u32 tid,
__u64 start, __u64 len, __u64 pgoff,
--
2.54.0.746.g67dd491aae-goog