diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2014-05-22 03:25:39 +0000 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2014-05-28 17:28:13 +0200 |
commit | 397335f004f41e5fcf7a795e94eb3ab83411a17c (patch) | |
tree | 57890f2b82ec6739e4dda7b2e51d85423885bfb6 /kernel/locking/rtmutex-debug.c | |
parent | f0d71b3dcb8332f7971b5f2363632573e6d9486a (diff) | |
download | op-kernel-dev-397335f004f41e5fcf7a795e94eb3ab83411a17c.zip op-kernel-dev-397335f004f41e5fcf7a795e94eb3ab83411a17c.tar.gz |
rtmutex: Fix deadlock detector for real
The current deadlock detection logic does not work reliably due to the
following early exit path:
/*
* Drop out, when the task has no waiters. Note,
* top_waiter can be NULL, when we are in the deboosting
* mode!
*/
if (top_waiter && (!task_has_pi_waiters(task) ||
top_waiter != task_top_pi_waiter(task)))
goto out_unlock_pi;
So this not only exits when the task has no waiters, it also exits
unconditionally when the current waiter is not the top priority waiter
of the task.
So in a nested locking scenario, it might abort the lock chain walk
and therefor miss a potential deadlock.
Simple fix: Continue the chain walk, when deadlock detection is
enabled.
We also avoid the whole enqueue, if we detect the deadlock right away
(A-A). It's an optimization, but also prevents that another waiter who
comes in after the detection and before the task has undone the damage
observes the situation and detects the deadlock and returns
-EDEADLOCK, which is wrong as the other task is not in a deadlock
situation.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Reviewed-by: Steven Rostedt <rostedt@goodmis.org>
Cc: Lai Jiangshan <laijs@cn.fujitsu.com>
Cc: stable@vger.kernel.org
Link: http://lkml.kernel.org/r/20140522031949.725272460@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/locking/rtmutex-debug.c')
0 files changed, 0 insertions, 0 deletions