Re: [PATCH v3] perf/core: Fix missing read event generation on task exit
From: Peter Zijlstra
Date: Wed Mar 04 2026 - 10:27:07 EST
On Wed, Mar 04, 2026 at 11:26:10AM +0000, James Clark wrote:
> > @@ -14564,11 +14556,21 @@ static void perf_event_exit_task_context(struct task_struct *task, bool exit)
> > * won't get any samples after PERF_RECORD_EXIT. We can however still
> > * get a few PERF_RECORD_READ events.
> > */
> > - if (exit)
> > + if (exit) {
> > perf_event_task(task, ctx, 0);
> > - list_for_each_entry_safe(child_event, next, &ctx->event_list, event_entry)
> > - perf_event_exit_event(child_event, ctx, exit ? task : NULL, false);
> > + guard(raw_spinlock_irq)(&ctx->lock);
> > + list_for_each_entry(event, &ctx->event_list, event_entry) {
> > + if (event->attr.inherit_stat) {
> > + if (task && task != TASK_TOMBSTONE &&
> > + event_filter_match(event))
> > + perf_event_read_event(event, task);
>
> Doesn't this only work if you happened to have an event opened on every CPU?
> Otherwise you could get rescheduled onto a core without an event and the
> event_filter_match() will fail and you'd drop the sample read for that exit.
Yes, absolutely. But that is more or less what you get.
So perf has per-task buffers and per-cpu buffers. For a simple per-task
profile, the per-task buffer works fine. However, if you want inherited
tasks, they can't all emit to the same buffer -- this would be a
scalability nightmake. So in that scenario you have to have
per-task-per-cpu events and make sure everybody emits to the local
buffer.
If you 'forget' to create an event/buffer for a particular CPU the
task(s) can run on, you loose events the moment they end up there.
There just isn't much you can do about that.