Skip to content

Commit 7cec2e1

Browse files
committed
Merge tag 'perf-urgent-2024-06-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf event fix from Ingo Molnar: "Fix race between perf_event_free_task() and perf_event_release_kernel() that can result in missed wakeups and hung tasks" * tag 'perf-urgent-2024-06-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: perf/core: Fix missing wakeup when waiting for context reference
2 parents bbc5332 + 74751ef commit 7cec2e1

File tree

1 file changed

+13
-0
lines changed

1 file changed

+13
-0
lines changed

kernel/events/core.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5384,6 +5384,7 @@ int perf_event_release_kernel(struct perf_event *event)
53845384
again:
53855385
mutex_lock(&event->child_mutex);
53865386
list_for_each_entry(child, &event->child_list, child_list) {
5387+
void *var = NULL;
53875388

53885389
/*
53895390
* Cannot change, child events are not migrated, see the
@@ -5424,11 +5425,23 @@ int perf_event_release_kernel(struct perf_event *event)
54245425
* this can't be the last reference.
54255426
*/
54265427
put_event(event);
5428+
} else {
5429+
var = &ctx->refcount;
54275430
}
54285431

54295432
mutex_unlock(&event->child_mutex);
54305433
mutex_unlock(&ctx->mutex);
54315434
put_ctx(ctx);
5435+
5436+
if (var) {
5437+
/*
5438+
* If perf_event_free_task() has deleted all events from the
5439+
* ctx while the child_mutex got released above, make sure to
5440+
* notify about the preceding put_ctx().
5441+
*/
5442+
smp_mb(); /* pairs with wait_var_event() */
5443+
wake_up_var(var);
5444+
}
54325445
goto again;
54335446
}
54345447
mutex_unlock(&event->child_mutex);

0 commit comments

Comments
 (0)