diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2021-08-13 13:40:49 +0300 |
---|---|---|
committer | Minda Chen <minda.chen@starfivetech.com> | 2023-11-06 14:24:44 +0300 |
commit | eb893f04744a485ef1a9e6c69f872a48e4932657 (patch) | |
tree | a86e06db5ed7869fe473b67b3ea2b347a2b8592b /kernel/locking | |
parent | 27b073576dcb1cac6c2855aa6688156903d4740e (diff) | |
download | linux-eb893f04744a485ef1a9e6c69f872a48e4932657.tar.xz |
rtmutex: Add a special case for ww-mutex handling.
The lockdep selftest for ww-mutex assumes in a few cases the
ww_ctx->contending_lock assignment via __ww_mutex_check_kill() which
does not happen if the rtmutex detects the deadlock early.
The testcase passes if the deadlock handling here is removed. This means
that it will work if multiple threads/tasks are involved and not just a
single one.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Diffstat (limited to 'kernel/locking')
-rw-r--r-- | kernel/locking/rtmutex.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c index 6bb116c559b4..3665583361c0 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -1097,8 +1097,26 @@ static int __sched task_blocks_on_rt_mutex(struct rt_mutex_base *lock, * which is wrong, as the other waiter is not in a deadlock * situation. */ - if (owner == task) + if (owner == task) { +#if defined(DEBUG_WW_MUTEXES) && defined(CONFIG_DEBUG_LOCKING_API_SELFTESTS) + /* + * The lockdep selftest for ww-mutex assumes in a few cases + * the ww_ctx->contending_lock assignment via + * __ww_mutex_check_kill() which does not happen if the rtmutex + * detects the deadlock early. + */ + if (build_ww_mutex() && ww_ctx) { + struct rt_mutex *rtm; + + /* Check whether the waiter should backout immediately */ + rtm = container_of(lock, struct rt_mutex, rtmutex); + + __ww_mutex_add_waiter(waiter, rtm, ww_ctx); + __ww_mutex_check_kill(rtm, waiter, ww_ctx); + } +#endif return -EDEADLK; + } raw_spin_lock(&task->pi_lock); waiter->task = task; |