OSDN Git Service

perf/core: Fix ctx::mutex deadlock
authorPeter Zijlstra <peterz@infradead.org>
Tue, 9 Jan 2018 20:23:02 +0000 (21:23 +0100)
committerIngo Molnar <mingo@kernel.org>
Thu, 25 Jan 2018 13:48:30 +0000 (14:48 +0100)
commit0c7296cad651a3a40286d70ff37e73bd6fa4e4da
tree8e22faa9d84a0b7e339f966bdbb58b324fc29ebf
parent43fa87f7deed52e8c8420182e0c133bc4cf395f6
perf/core: Fix ctx::mutex deadlock

Lockdep noticed the following 3-way lockup scenario:

sys_perf_event_open()
  perf_event_alloc()
    perf_try_init_event()
 #0       ctx = perf_event_ctx_lock_nested(1)
      perf_swevent_init()
swevent_hlist_get()
 #1   mutex_lock(&pmus_lock)

perf_event_init_cpu()
 #1   mutex_lock(&pmus_lock)
 #2   mutex_lock(&ctx->mutex)

sys_perf_event_open()
  mutex_lock_double()
 #2    mutex_lock()
 #0    mutex_lock_nested()

And while we need that perf_event_ctx_lock_nested() for HW PMUs such
that they can iterate the sibling list, trying to match it to the
available counters, the software PMUs need do no such thing. Exclude
them.

In particular the swevent triggers the above invertion, while the
tpevent PMU triggers a more elaborate one through their event_mutex.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
kernel/events/core.c