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

+13
+13
kernel/events/core.c
··· 5384 5384 again: 5385 5385 mutex_lock(&event->child_mutex); 5386 5386 list_for_each_entry(child, &event->child_list, child_list) { 5387 + void *var = NULL; 5387 5388 5388 5389 /* 5389 5390 * Cannot change, child events are not migrated, see the ··· 5425 5424 * this can't be the last reference. 5426 5425 */ 5427 5426 put_event(event); 5427 + } else { 5428 + var = &ctx->refcount; 5428 5429 } 5429 5430 5430 5431 mutex_unlock(&event->child_mutex); 5431 5432 mutex_unlock(&ctx->mutex); 5432 5433 put_ctx(ctx); 5434 + 5435 + if (var) { 5436 + /* 5437 + * If perf_event_free_task() has deleted all events from the 5438 + * ctx while the child_mutex got released above, make sure to 5439 + * notify about the preceding put_ctx(). 5440 + */ 5441 + smp_mb(); /* pairs with wait_var_event() */ 5442 + wake_up_var(var); 5443 + } 5433 5444 goto again; 5434 5445 } 5435 5446 mutex_unlock(&event->child_mutex);