blob: 6c2a756b17809636fb4433d03cb4b69c7ba22144 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
From a2f7a496ecf1fc7afe5f70a3a471d8c21bb36f11 Mon Sep 17 00:00:00 2001
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Date: Fri, 13 Aug 2021 12:40:49 +0200
Subject: [PATCH 080/158] rtmutex: Add a special case for ww-mutex handling.
Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/5.15/older/patches-5.15.10-rt24.tar.xz
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>
---
kernel/locking/rtmutex.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
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;
--
2.33.1
|