Commit 7cec2e16 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents bbc5332b 74751ef5
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -5384,6 +5384,7 @@ int perf_event_release_kernel(struct perf_event *event)
again:
	mutex_lock(&event->child_mutex);
	list_for_each_entry(child, &event->child_list, child_list) {
		void *var = NULL;

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

		mutex_unlock(&event->child_mutex);
		mutex_unlock(&ctx->mutex);
		put_ctx(ctx);

		if (var) {
			/*
			 * If perf_event_free_task() has deleted all events from the
			 * ctx while the child_mutex got released above, make sure to
			 * notify about the preceding put_ctx().
			 */
			smp_mb(); /* pairs with wait_var_event() */
			wake_up_var(var);
		}
		goto again;
	}
	mutex_unlock(&event->child_mutex);