Commit a0507c84 authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar

perf: Annotate perf_event_read_group() vs perf_event_release_kernel()

Stephane reported a lockdep warning while using PERF_FORMAT_GROUP.

The issue is that perf_event_read_group() takes faults while holding
the ctx->mutex, while perf_event_release_kernel() can be called from
munmap(). Which makes for an AB-BA deadlock.

Except we can never establish the deadlock because we'll only ever
call perf_event_release_kernel() after all file descriptors are dead
so there is no concurrency possible.
Reported-by: default avatarStephane Eranian <eranian@google.com>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <new-submission>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent cce91317
...@@ -1867,7 +1867,19 @@ int perf_event_release_kernel(struct perf_event *event) ...@@ -1867,7 +1867,19 @@ int perf_event_release_kernel(struct perf_event *event)
event->state = PERF_EVENT_STATE_FREE; event->state = PERF_EVENT_STATE_FREE;
WARN_ON_ONCE(ctx->parent_ctx); WARN_ON_ONCE(ctx->parent_ctx);
mutex_lock(&ctx->mutex); /*
* There are two ways this annotation is useful:
*
* 1) there is a lock recursion from perf_event_exit_task
* see the comment there.
*
* 2) there is a lock-inversion with mmap_sem through
* perf_event_read_group(), which takes faults while
* holding ctx->mutex, however this is called after
* the last filedesc died, so there is no possibility
* to trigger the AB-BA case.
*/
mutex_lock_nested(&ctx->mutex, SINGLE_DEPTH_NESTING);
perf_event_remove_from_context(event); perf_event_remove_from_context(event);
mutex_unlock(&ctx->mutex); mutex_unlock(&ctx->mutex);
...@@ -5305,7 +5317,7 @@ void perf_event_exit_task(struct task_struct *child) ...@@ -5305,7 +5317,7 @@ void perf_event_exit_task(struct task_struct *child)
* *
* But since its the parent context it won't be the same instance. * But since its the parent context it won't be the same instance.
*/ */
mutex_lock_nested(&child_ctx->mutex, SINGLE_DEPTH_NESTING); mutex_lock(&child_ctx->mutex);
again: again:
list_for_each_entry_safe(child_event, tmp, &child_ctx->pinned_groups, list_for_each_entry_safe(child_event, tmp, &child_ctx->pinned_groups,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment