mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v1] perf/core: Restore header fields in sideband output callbacks
@ 2026-09-29  1:42 Ian Rogers
  2026-09-29 12:04 ` Peter Zijlstra
  0 siblings, 1 reply; 2+ messages in thread
From: Ian Rogers @ 2026-09-29  1:42 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim
  Cc: Mark Rutland, Alexander Shishkin, Jiri Olsa, Ian Rogers,
	Adrian Hunter, James Clark, Song Liu, Alexei Starovoitov,
	linux-perf-users, linux-kernel, bpf, stable

perf_iterate_sb() invokes its callback for each matching perf_event on
the CPU and task context, passing a shared caller-allocated event
structure.

perf_event_header__init_id() increments header->size by
event->id_header_size. Unlike perf_event_task_output(),
perf_event_comm_output(), perf_event_namespaces_output(),
perf_event_cgroup_output(), perf_event_mmap_output(), and
perf_callchain_deferred_output(), three sideband callbacks failed to
save and restore header.size around perf_event_header__init_id():
- perf_event_ksymbol_output()
- perf_event_bpf_output()
- perf_event_text_poke_output()

When multiple events with attr.ksymbol, attr.bpf_event, or
attr.text_poke and sample_id_all are active on the same CPU, each
subsequent event receives a record whose header.size is inflated by all
preceding events' id_header_size values while only a single id_sample is
written, leaving uninitialized ring-buffer bytes at the end of the
record and causing userspace perf to fail with -EFAULT ("Bad address")
when parsing the sample_id trailer.

Similarly, perf_event_mmap_output() sets PERF_RECORD_MISC_MMAP_BUILD_ID
in mmap_event->event_id.header.misc when event->attr.build_id is
enabled, but only saved and restored header.size and header.type. If an
event with attr.build_id is followed by an event with attr.mmap2 and
!attr.build_id, the second event receives PERF_RECORD_MISC_MMAP_BUILD_ID
in header.misc while its payload contains maj/min/ino/ino_generation
instead of a build ID.

Save and restore header.size in the ksymbol, bpf, and text_poke output
callbacks, and save and restore header.misc in perf_event_mmap_output().

Fixes: 76193a94522f ("perf, bpf: Introduce PERF_RECORD_KSYMBOL")
Fixes: 6ee52e2a3fe4 ("perf, bpf: Introduce PERF_RECORD_BPF_EVENT")
Fixes: e17d43b93e54 ("perf: Add perf text poke event")
Fixes: 88a16a130933 ("perf: Add build id data in mmap2 event")
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
---
 kernel/events/core.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 33210aff3ee6..ea3697295bd4 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -9029,6 +9029,11 @@ static void perf_iterate_sb_cpu(perf_iterate_f output, void *data)
  *
  * For new callers; ensure that account_pmu_sb_event() includes
  * your event, otherwise it might not get delivered.
+ *
+ * Note: @data is shared across all @output calls, so any fields modified
+ * incrementally or conditionally (e.g. header.size via
+ * perf_event_header__init_id()) must be saved and restored by @output,
+ * or unconditionally re-initialized on each call.
  */
 static void
 perf_iterate_sb(perf_iterate_f output, void *data,
@@ -9723,6 +9728,7 @@ static void perf_event_mmap_output(struct perf_event *event,
 	struct perf_sample_data sample;
 	int size = mmap_event->event_id.header.size;
 	u32 type = mmap_event->event_id.header.type;
+	u16 misc = mmap_event->event_id.header.misc;
 	bool use_build_id;
 	int ret;
 
@@ -9780,6 +9786,7 @@ static void perf_event_mmap_output(struct perf_event *event,
 out:
 	mmap_event->event_id.header.size = size;
 	mmap_event->event_id.header.type = type;
+	mmap_event->event_id.header.misc = misc;
 }
 
 static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
@@ -10244,6 +10251,7 @@ static void perf_event_ksymbol_output(struct perf_event *event, void *data)
 	struct perf_ksymbol_event *ksymbol_event = data;
 	struct perf_output_handle handle;
 	struct perf_sample_data sample;
+	u16 header_size = ksymbol_event->event_id.header.size;
 	int ret;
 
 	if (!perf_event_ksymbol_match(event))
@@ -10254,13 +10262,15 @@ static void perf_event_ksymbol_output(struct perf_event *event, void *data)
 	ret = perf_output_begin(&handle, &sample, event,
 				ksymbol_event->event_id.header.size);
 	if (ret)
-		return;
+		goto out;
 
 	perf_output_put(&handle, ksymbol_event->event_id);
 	__output_copy(&handle, ksymbol_event->name, ksymbol_event->name_len);
 	perf_event__output_id_sample(event, &handle, &sample);
 
 	perf_output_end(&handle);
+out:
+	ksymbol_event->event_id.header.size = header_size;
 }
 
 void perf_event_ksymbol(u16 ksym_type, u64 addr, u32 len, bool unregister,
@@ -10334,6 +10344,7 @@ static void perf_event_bpf_output(struct perf_event *event, void *data)
 	struct perf_bpf_event *bpf_event = data;
 	struct perf_output_handle handle;
 	struct perf_sample_data sample;
+	u16 header_size = bpf_event->event_id.header.size;
 	int ret;
 
 	if (!perf_event_bpf_match(event))
@@ -10344,12 +10355,14 @@ static void perf_event_bpf_output(struct perf_event *event, void *data)
 	ret = perf_output_begin(&handle, &sample, event,
 				bpf_event->event_id.header.size);
 	if (ret)
-		return;
+		goto out;
 
 	perf_output_put(&handle, bpf_event->event_id);
 	perf_event__output_id_sample(event, &handle, &sample);
 
 	perf_output_end(&handle);
+out:
+	bpf_event->event_id.header.size = header_size;
 }
 
 static void perf_event_bpf_emit_ksymbols(struct bpf_prog *prog,
@@ -10496,6 +10509,7 @@ static void perf_event_text_poke_output(struct perf_event *event, void *data)
 	struct perf_text_poke_event *text_poke_event = data;
 	struct perf_output_handle handle;
 	struct perf_sample_data sample;
+	u16 header_size = text_poke_event->event_id.header.size;
 	u64 padding = 0;
 	int ret;
 
@@ -10507,7 +10521,7 @@ static void perf_event_text_poke_output(struct perf_event *event, void *data)
 	ret = perf_output_begin(&handle, &sample, event,
 				text_poke_event->event_id.header.size);
 	if (ret)
-		return;
+		goto out;
 
 	perf_output_put(&handle, text_poke_event->event_id);
 	perf_output_put(&handle, text_poke_event->old_len);
@@ -10522,6 +10536,8 @@ static void perf_event_text_poke_output(struct perf_event *event, void *data)
 	perf_event__output_id_sample(event, &handle, &sample);
 
 	perf_output_end(&handle);
+out:
+	text_poke_event->event_id.header.size = header_size;
 }
 
 void perf_event_text_poke(const void *addr, const void *old_bytes,
-- 
2.56.0.rc1.315.gc6ed9934b7-goog


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

* Re: [PATCH v1] perf/core: Restore header fields in sideband output callbacks
  2026-09-29  1:42 [PATCH v1] perf/core: Restore header fields in sideband output callbacks Ian Rogers
@ 2026-09-29 12:04 ` Peter Zijlstra
  0 siblings, 0 replies; 2+ messages in thread
From: Peter Zijlstra @ 2026-09-29 12:04 UTC (permalink / raw)
  To: Ian Rogers
  Cc: Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Adrian Hunter,
	James Clark, Song Liu, Alexei Starovoitov, linux-perf-users,
	linux-kernel, bpf, stable

On Mon, Sep 28, 2026 at 06:42:06PM -0700, Ian Rogers wrote:
> perf_iterate_sb() invokes its callback for each matching perf_event on
> the CPU and task context, passing a shared caller-allocated event
> structure.
> 
> perf_event_header__init_id() increments header->size by
> event->id_header_size. Unlike perf_event_task_output(),
> perf_event_comm_output(), perf_event_namespaces_output(),
> perf_event_cgroup_output(), perf_event_mmap_output(), and
> perf_callchain_deferred_output(), three sideband callbacks failed to
> save and restore header.size around perf_event_header__init_id():
> - perf_event_ksymbol_output()
> - perf_event_bpf_output()
> - perf_event_text_poke_output()

I also found perf_event_switch_output(). Does something like so also
work?

---
 kernel/events/core.c | 131 ++++++++++++++++++++++++---------------------------
 1 file changed, 61 insertions(+), 70 deletions(-)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index de05df65ab3d..28770ca689c8 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -9108,12 +9108,22 @@ perf_event_read_event(struct perf_event *event,
 	perf_output_end(&handle);
 }
 
-typedef void (perf_iterate_f)(struct perf_event *event, void *data);
+typedef void (perf_iterate_f)(struct perf_event *event, struct perf_event_header *header);
+
+static __always_inline
+void __perf_iterate_output(perf_iterate_f output,
+			   struct perf_event *event,
+			   struct perf_event_header *header)
+{
+	struct perf_event_header old = *header;
+	output(event, header);
+	*header = old;
+}
 
 static void
 perf_iterate_ctx(struct perf_event_context *ctx,
 		   perf_iterate_f output,
-		   void *data, bool all)
+		   struct perf_event_header *header, bool all)
 {
 	struct perf_event *event;
 
@@ -9125,11 +9135,11 @@ perf_iterate_ctx(struct perf_event_context *ctx,
 				continue;
 		}
 
-		output(event, data);
+		__perf_iterate_output(output, event, header);
 	}
 }
 
-static void perf_iterate_sb_cpu(perf_iterate_f output, void *data)
+static void perf_iterate_sb_cpu(perf_iterate_f output, struct perf_event_header *header)
 {
 	struct pmu_event_list *pel = this_cpu_ptr(&pmu_sb_events);
 	struct perf_event *event;
@@ -9147,7 +9157,8 @@ static void perf_iterate_sb_cpu(perf_iterate_f output, void *data)
 			continue;
 		if (!event_filter_match(event))
 			continue;
-		output(event, data);
+
+		__perf_iterate_output(output, event, header);
 	}
 }
 
@@ -9158,7 +9169,7 @@ static void perf_iterate_sb_cpu(perf_iterate_f output, void *data)
  * your event, otherwise it might not get delivered.
  */
 static void
-perf_iterate_sb(perf_iterate_f output, void *data,
+perf_iterate_sb(perf_iterate_f output, struct perf_event_header *header,
 	       struct perf_event_context *task_ctx)
 {
 	struct perf_event_context *ctx;
@@ -9172,15 +9183,15 @@ perf_iterate_sb(perf_iterate_f output, void *data,
 	 * context.
 	 */
 	if (task_ctx) {
-		perf_iterate_ctx(task_ctx, output, data, false);
+		perf_iterate_ctx(task_ctx, output, header, false);
 		goto done;
 	}
 
-	perf_iterate_sb_cpu(output, data);
+	perf_iterate_sb_cpu(output, header);
 
 	ctx = rcu_dereference(current->perf_event_ctxp);
 	if (ctx)
-		perf_iterate_ctx(ctx, output, data, false);
+		perf_iterate_ctx(ctx, output, header, false);
 done:
 	preempt_enable();
 	rcu_read_unlock();
@@ -9347,13 +9358,13 @@ static int perf_event_task_match(struct perf_event *event)
 }
 
 static void perf_event_task_output(struct perf_event *event,
-				   void *data)
+				   struct perf_event_header *header)
 {
-	struct perf_task_event *task_event = data;
+	auto task_event = container_of(header, struct perf_task_event, event_id.header);
+	struct task_struct *task = task_event->task;
 	struct perf_output_handle handle;
 	struct perf_sample_data	sample;
-	struct task_struct *task = task_event->task;
-	int ret, size = task_event->event_id.header.size;
+	int ret;
 
 	if (!perf_event_task_match(event))
 		return;
@@ -9363,7 +9374,7 @@ static void perf_event_task_output(struct perf_event *event,
 	ret = perf_output_begin(&handle, &sample, event,
 				task_event->event_id.header.size);
 	if (ret)
-		goto out;
+		return;
 
 	task_event->event_id.pid = perf_event_pid(event, task);
 	task_event->event_id.tid = perf_event_tid(event, task);
@@ -9385,8 +9396,6 @@ static void perf_event_task_output(struct perf_event *event,
 	perf_event__output_id_sample(event, &handle, &sample);
 
 	perf_output_end(&handle);
-out:
-	task_event->event_id.header.size = size;
 }
 
 static void perf_event_task(struct task_struct *task,
@@ -9418,7 +9427,7 @@ static void perf_event_task(struct task_struct *task,
 	};
 
 	perf_iterate_sb(perf_event_task_output,
-		       &task_event,
+		       &task_event.event_id.header,
 		       task_ctx);
 }
 
@@ -9499,12 +9508,11 @@ static int perf_event_comm_match(struct perf_event *event)
 }
 
 static void perf_event_comm_output(struct perf_event *event,
-				   void *data)
+				   struct perf_event_header *header)
 {
-	struct perf_comm_event *comm_event = data;
+	auto comm_event = container_of(header, struct perf_comm_event, event_id.header);
 	struct perf_output_handle handle;
 	struct perf_sample_data sample;
-	int size = comm_event->event_id.header.size;
 	int ret;
 
 	if (!perf_event_comm_match(event))
@@ -9513,9 +9521,8 @@ static void perf_event_comm_output(struct perf_event *event,
 	perf_event_header__init_id(&comm_event->event_id.header, &sample, event);
 	ret = perf_output_begin(&handle, &sample, event,
 				comm_event->event_id.header.size);
-
 	if (ret)
-		goto out;
+		return;
 
 	comm_event->event_id.pid = perf_event_pid(event, comm_event->task);
 	comm_event->event_id.tid = perf_event_tid(event, comm_event->task);
@@ -9527,8 +9534,6 @@ static void perf_event_comm_output(struct perf_event *event,
 	perf_event__output_id_sample(event, &handle, &sample);
 
 	perf_output_end(&handle);
-out:
-	comm_event->event_id.header.size = size;
 }
 
 static void perf_event_comm_event(struct perf_comm_event *comm_event)
@@ -9546,7 +9551,7 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event)
 	comm_event->event_id.header.size = sizeof(comm_event->event_id) + size;
 
 	perf_iterate_sb(perf_event_comm_output,
-		       comm_event,
+		       &comm_event->event_id.header,
 		       NULL);
 }
 
@@ -9598,12 +9603,11 @@ static int perf_event_namespaces_match(struct perf_event *event)
 }
 
 static void perf_event_namespaces_output(struct perf_event *event,
-					 void *data)
+					 struct perf_event_header *header)
 {
-	struct perf_namespaces_event *namespaces_event = data;
+	auto namespaces_event = container_of(header, struct perf_namespaces_event, event_id.header);
 	struct perf_output_handle handle;
 	struct perf_sample_data sample;
-	u16 header_size = namespaces_event->event_id.header.size;
 	int ret;
 
 	if (!perf_event_namespaces_match(event))
@@ -9614,7 +9618,7 @@ static void perf_event_namespaces_output(struct perf_event *event,
 	ret = perf_output_begin(&handle, &sample, event,
 				namespaces_event->event_id.header.size);
 	if (ret)
-		goto out;
+		return;
 
 	namespaces_event->event_id.pid = perf_event_pid(event,
 							namespaces_event->task);
@@ -9626,8 +9630,6 @@ static void perf_event_namespaces_output(struct perf_event *event,
 	perf_event__output_id_sample(event, &handle, &sample);
 
 	perf_output_end(&handle);
-out:
-	namespaces_event->event_id.header.size = header_size;
 }
 
 static void perf_fill_ns_link_info(struct perf_ns_link_info *ns_link_info,
@@ -9701,7 +9703,7 @@ void perf_event_namespaces(struct task_struct *task)
 #endif
 
 	perf_iterate_sb(perf_event_namespaces_output,
-			&namespaces_event,
+			&namespaces_event.event_id.header,
 			NULL);
 }
 
@@ -9725,12 +9727,11 @@ static int perf_event_cgroup_match(struct perf_event *event)
 	return event->attr.cgroup;
 }
 
-static void perf_event_cgroup_output(struct perf_event *event, void *data)
+static void perf_event_cgroup_output(struct perf_event *event, struct perf_event_header *header)
 {
-	struct perf_cgroup_event *cgroup_event = data;
+	auto cgroup_event = container_of(header, struct perf_cgroup_event, event_id.header);
 	struct perf_output_handle handle;
 	struct perf_sample_data sample;
-	u16 header_size = cgroup_event->event_id.header.size;
 	int ret;
 
 	if (!perf_event_cgroup_match(event))
@@ -9741,7 +9742,7 @@ static void perf_event_cgroup_output(struct perf_event *event, void *data)
 	ret = perf_output_begin(&handle, &sample, event,
 				cgroup_event->event_id.header.size);
 	if (ret)
-		goto out;
+		return;
 
 	perf_output_put(&handle, cgroup_event->event_id);
 	__output_copy(&handle, cgroup_event->path, cgroup_event->path_size);
@@ -9749,8 +9750,6 @@ static void perf_event_cgroup_output(struct perf_event *event, void *data)
 	perf_event__output_id_sample(event, &handle, &sample);
 
 	perf_output_end(&handle);
-out:
-	cgroup_event->event_id.header.size = header_size;
 }
 
 static void perf_event_cgroup(struct cgroup *cgrp)
@@ -9796,7 +9795,7 @@ static void perf_event_cgroup(struct cgroup *cgrp)
 	cgroup_event.path_size = size;
 
 	perf_iterate_sb(perf_event_cgroup_output,
-			&cgroup_event,
+			&cgroup_event.event_id.header,
 			NULL);
 
 	kfree(pathname);
@@ -9832,9 +9831,8 @@ struct perf_mmap_event {
 };
 
 static int perf_event_mmap_match(struct perf_event *event,
-				 void *data)
+				 struct perf_mmap_event *mmap_event)
 {
-	struct perf_mmap_event *mmap_event = data;
 	struct vm_area_struct *vma = mmap_event->vma;
 	int executable = vma->vm_flags & VM_EXEC;
 
@@ -9843,17 +9841,15 @@ static int perf_event_mmap_match(struct perf_event *event,
 }
 
 static void perf_event_mmap_output(struct perf_event *event,
-				   void *data)
+				   struct perf_event_header *header)
 {
-	struct perf_mmap_event *mmap_event = data;
+	auto mmap_event = container_of(header, struct perf_mmap_event, event_id.header);
 	struct perf_output_handle handle;
 	struct perf_sample_data sample;
-	int size = mmap_event->event_id.header.size;
-	u32 type = mmap_event->event_id.header.type;
 	bool use_build_id;
 	int ret;
 
-	if (!perf_event_mmap_match(event, data))
+	if (!perf_event_mmap_match(event, mmap_event))
 		return;
 
 	if (event->attr.mmap2) {
@@ -9870,7 +9866,7 @@ static void perf_event_mmap_output(struct perf_event *event,
 	ret = perf_output_begin(&handle, &sample, event,
 				mmap_event->event_id.header.size);
 	if (ret)
-		goto out;
+		return;
 
 	mmap_event->event_id.pid = perf_event_pid(event, current);
 	mmap_event->event_id.tid = perf_event_tid(event, current);
@@ -9904,9 +9900,6 @@ static void perf_event_mmap_output(struct perf_event *event,
 	perf_event__output_id_sample(event, &handle, &sample);
 
 	perf_output_end(&handle);
-out:
-	mmap_event->event_id.header.size = size;
-	mmap_event->event_id.header.type = type;
 }
 
 static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
@@ -10011,7 +10004,7 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
 		build_id_parse_nofault(vma, mmap_event->build_id, &mmap_event->build_id_size);
 
 	perf_iterate_sb(perf_event_mmap_output,
-		       mmap_event,
+		       &mmap_event->event_id.header,
 		       NULL);
 
 	kfree(buf);
@@ -10236,9 +10229,9 @@ static int perf_event_switch_match(struct perf_event *event)
 	return event->attr.context_switch;
 }
 
-static void perf_event_switch_output(struct perf_event *event, void *data)
+static void perf_event_switch_output(struct perf_event *event, struct perf_event_header *header)
 {
-	struct perf_switch_event *se = data;
+	auto se = container_of(header, struct perf_switch_event, event_id.header);
 	struct perf_output_handle handle;
 	struct perf_sample_data sample;
 	int ret;
@@ -10301,7 +10294,7 @@ static void perf_event_switch(struct task_struct *task,
 				PERF_RECORD_MISC_SWITCH_OUT_PREEMPT;
 	}
 
-	perf_iterate_sb(perf_event_switch_output, &switch_event, NULL);
+	perf_iterate_sb(perf_event_switch_output, &switch_event.event_id.header, NULL);
 }
 
 /*
@@ -10366,9 +10359,9 @@ static int perf_event_ksymbol_match(struct perf_event *event)
 	return event->attr.ksymbol;
 }
 
-static void perf_event_ksymbol_output(struct perf_event *event, void *data)
+static void perf_event_ksymbol_output(struct perf_event *event, struct perf_event_header *header)
 {
-	struct perf_ksymbol_event *ksymbol_event = data;
+	auto ksymbol_event = container_of(header, struct perf_ksymbol_event, event_id.header);
 	struct perf_output_handle handle;
 	struct perf_sample_data sample;
 	int ret;
@@ -10430,7 +10423,7 @@ void perf_event_ksymbol(u16 ksym_type, u64 addr, u32 len, bool unregister,
 		},
 	};
 
-	perf_iterate_sb(perf_event_ksymbol_output, &ksymbol_event, NULL);
+	perf_iterate_sb(perf_event_ksymbol_output, &ksymbol_event.event_id.header, NULL);
 	return;
 err:
 	WARN_ONCE(1, "%s: Invalid KSYMBOL type 0x%x\n", __func__, ksym_type);
@@ -10456,9 +10449,9 @@ static int perf_event_bpf_match(struct perf_event *event)
 	return event->attr.bpf_event;
 }
 
-static void perf_event_bpf_output(struct perf_event *event, void *data)
+static void perf_event_bpf_output(struct perf_event *event, struct perf_event_header *header)
 {
-	struct perf_bpf_event *bpf_event = data;
+	auto bpf_event = container_of(header, struct perf_bpf_event, event_id.header);
 	struct perf_output_handle handle;
 	struct perf_sample_data sample;
 	int ret;
@@ -10536,7 +10529,7 @@ void perf_event_bpf_event(struct bpf_prog *prog,
 	BUILD_BUG_ON(BPF_TAG_SIZE % sizeof(u64));
 
 	memcpy(bpf_event.event_id.tag, prog->tag, BPF_TAG_SIZE);
-	perf_iterate_sb(perf_event_bpf_output, &bpf_event, NULL);
+	perf_iterate_sb(perf_event_bpf_output, &bpf_event.event_id.header, NULL);
 }
 
 struct perf_callchain_deferred_event {
@@ -10549,12 +10542,12 @@ struct perf_callchain_deferred_event {
 	} event;
 };
 
-static void perf_callchain_deferred_output(struct perf_event *event, void *data)
+static void perf_callchain_deferred_output(struct perf_event *event, struct perf_event_header *header)
 {
-	struct perf_callchain_deferred_event *deferred_event = data;
+	auto deferred_event = container_of(header, struct perf_callchain_deferred_event, event.header);
 	struct perf_output_handle handle;
 	struct perf_sample_data sample;
-	int ret, size = deferred_event->event.header.size;
+	int ret;
 
 	if (!event->attr.defer_output)
 		return;
@@ -10565,7 +10558,7 @@ static void perf_callchain_deferred_output(struct perf_event *event, void *data)
 	ret = perf_output_begin(&handle, &sample, event,
 				deferred_event->event.header.size);
 	if (ret)
-		goto out;
+		return;
 
 	perf_output_put(&handle, deferred_event->event);
 	for (int i = 0; i < deferred_event->trace->nr; i++) {
@@ -10575,8 +10568,6 @@ static void perf_callchain_deferred_output(struct perf_event *event, void *data)
 	perf_event__output_id_sample(event, &handle, &sample);
 
 	perf_output_end(&handle);
-out:
-	deferred_event->event.header.size = size;
 }
 
 static void perf_unwind_deferred_callback(struct unwind_work *work,
@@ -10596,7 +10587,7 @@ static void perf_unwind_deferred_callback(struct unwind_work *work,
 		},
 	};
 
-	perf_iterate_sb(perf_callchain_deferred_output, &deferred_event, NULL);
+	perf_iterate_sb(perf_callchain_deferred_output, &deferred_event.event.header, NULL);
 }
 
 struct perf_text_poke_event {
@@ -10618,9 +10609,9 @@ static int perf_event_text_poke_match(struct perf_event *event)
 	return event->attr.text_poke;
 }
 
-static void perf_event_text_poke_output(struct perf_event *event, void *data)
+static void perf_event_text_poke_output(struct perf_event *event, struct perf_event_header *header)
 {
-	struct perf_text_poke_event *text_poke_event = data;
+	auto text_poke_event = container_of(header, struct perf_text_poke_event, event_id.header);
 	struct perf_output_handle handle;
 	struct perf_sample_data sample;
 	u64 padding = 0;
@@ -10680,7 +10671,7 @@ void perf_event_text_poke(const void *addr, const void *old_bytes,
 		},
 	};
 
-	perf_iterate_sb(perf_event_text_poke_output, &text_poke_event, NULL);
+	perf_iterate_sb(perf_event_text_poke_output, &text_poke_event.event_id.header, NULL);
 }
 
 void perf_event_itrace_started(struct perf_event *event)

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

end of thread, other threads:[~2026-09-29 12:04 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-29  1:42 [PATCH v1] perf/core: Restore header fields in sideband output callbacks Ian Rogers
2026-09-29 12:04 ` Peter Zijlstra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®