Skip to content

Commit

Permalink
locking/rtmutex: Return success on deadlock for ww_mutex waiters
Browse files Browse the repository at this point in the history
ww_mutexes can legitimately cause a deadlock situation in the lock graph
which is resolved afterwards by the wait/wound mechanics. The rtmutex chain
walk can detect such a deadlock and returns EDEADLK which in turn skips the
wait/wound mechanism and returns EDEADLK to the caller. That's wrong
because both lock chains might get EDEADLK or the wrong waiter would back
out.

Detect that situation and return 'success' in case that the waiter which
initiated the chain walk is a ww_mutex with context. This allows the
wait/wound mechanics to resolve the situation according to the rules.

[ tglx: Split it apart and added changelog ]

Reported-by: Sebastian Siewior <[email protected]>
Fixes: add4613 ("locking/rtmutex: Extend the rtmutex core to support ww_mutex")
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
  • Loading branch information
Peter Zijlstra authored and KAGA-KOKO committed Aug 27, 2021
1 parent 6467822 commit a055fcc
Showing 1 changed file with 14 additions and 1 deletion.
15 changes: 14 additions & 1 deletion kernel/locking/rtmutex.c
Original file line number Diff line number Diff line change
Expand Up @@ -742,8 +742,21 @@ static int __sched rt_mutex_adjust_prio_chain(struct task_struct *task,
* walk, we detected a deadlock.
*/
if (lock == orig_lock || rt_mutex_owner(lock) == top_task) {
raw_spin_unlock(&lock->wait_lock);
ret = -EDEADLK;

/*
* When the deadlock is due to ww_mutex; also see above. Don't
* report the deadlock and instead let the ww_mutex wound/die
* logic pick which of the contending threads gets -EDEADLK.
*
* NOTE: assumes the cycle only contains a single ww_class; any
* other configuration and we fail to report; also, see
* lockdep.
*/
if (IS_ENABLED(CONFIG_PREEMPT_RT) && orig_waiter->ww_ctx)
ret = 0;

raw_spin_unlock(&lock->wait_lock);
goto out_unlock_pi;
}

Expand Down

0 comments on commit a055fcc

Please sign in to comment.