forked from Minki/linux
perf/hw_breakpoint: Annotate tsk->perf_event_mutex vs ctx->mutex
Perf fuzzer gifted a lockdep splat:
perf_event_init_context()
mutex_lock(parent_ctx->mutex); (B)
inherit_task_group()
inherit_group()
inherit_event()
perf_event_alloc()
perf_try_init_event() := hw_breakpoint_event_init()
register_perf_hw_breakpoint()
mutex_lock(child->perf_event_mutex); (A)
Which is against the normal (documented) order. Now, this is a false
positive in that child is not published yet, but also inherited events
never end up on ->perf_event_list.
Annotate this one away.
Fixes: 0912037fec
("perf/hw_breakpoint: Reduce contention with large number of tasks")
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
This commit is contained in:
parent
7be51cc1c6
commit
82aad7ff7a
@ -117,7 +117,17 @@ static struct mutex *bp_constraints_lock(struct perf_event *bp)
|
||||
struct mutex *tsk_mtx = get_task_bps_mutex(bp);
|
||||
|
||||
if (tsk_mtx) {
|
||||
mutex_lock(tsk_mtx);
|
||||
/*
|
||||
* Fully analogous to the perf_try_init_event() nesting
|
||||
* argument in the comment near perf_event_ctx_lock_nested();
|
||||
* this child->perf_event_mutex cannot ever deadlock against
|
||||
* the parent->perf_event_mutex usage from
|
||||
* perf_event_task_{en,dis}able().
|
||||
*
|
||||
* Specifically, inherited events will never occur on
|
||||
* ->perf_event_list.
|
||||
*/
|
||||
mutex_lock_nested(tsk_mtx, SINGLE_DEPTH_NESTING);
|
||||
percpu_down_read(&bp_cpuinfo_sem);
|
||||
} else {
|
||||
percpu_down_write(&bp_cpuinfo_sem);
|
||||
|
Loading…
Reference in New Issue
Block a user