[PATCH v3 3/3] test-ww_mutex: Handle transient -EDEADLK in test_cycle_work

Håkon Bugge <[email protected]>
Newsgroups gmane.linux.kernel
Message-ID <[email protected]>
There is a timing issue in test_cycle_work(), in the sense that
acquiring *a_mutex* after deadlock has been detected on the *b_mutex*,
may not succeed immediately. This may lead to false negatives, which
shows up in the log as:

   cyclic deadlock not resolved, ret[77/93] = -35

We re-factor the inner part test_cycle_work(), where we loop a few
times attempting to acquire the mutexes in BAAB order. If the first A
succeeds or the last B succeeds, we break out of the loop.

Fixes: d1b42b800e5d ("locking/ww_mutex: Add kselftests for resolving ww_mutex cyclic deadlocks")
Fixes: e4a02ed2aaf4 ("locking/ww_mutex: Fix runtime warning in the WW mutex selftest")
Signed-off-by: Håkon Bugge <[email protected]>
Acked-by: John Stultz <[email protected]>

---

v2 -> v3:
      * Added John's a-b
      * Renamed the "ok" label to "out", as suggested by John

v1 -> v2:
      * Removed the end-less lock acquisition attempts, as that
        strategy did not obey the big-rules of the WW
        mutexes. Instead, re-factor the test, and loop a handful
        times.
---
 kernel/locking/test-ww_mutex.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/kernel/locking/test-ww_mutex.c b/kernel/locking/test-ww_mutex.c
index 5ed91f2cf30d9..47e016a4f4fea 100644
--- a/kernel/locking/test-ww_mutex.c
+++ b/kernel/locking/test-ww_mutex.c
@@ -294,6 +294,8 @@ static void test_cycle_work(struct work_struct *work)
 	struct test_cycle *cycle = container_of(work, typeof(*cycle), work);
 	struct ww_acquire_ctx ctx;
 	int err, erra = 0;
+	const int max_attempts = 5;
+	int attempt;
 
 	ww_acquire_init_noinject(&ctx, cycle->class);
 	ww_mutex_lock(&cycle->a_mutex, &ctx);
@@ -302,13 +304,26 @@ static void test_cycle_work(struct work_struct *work)
 	wait_for_completion(&cycle->b_signal);
 
 	err = ww_mutex_lock(cycle->b_mutex, &ctx);
-	if (err == -EDEADLK) {
+	if (err != -EDEADLK)
+		goto out;
+
+	for (attempt = 0; attempt < max_attempts; ++attempt) {
 		err = 0;
 		ww_mutex_unlock(&cycle->a_mutex);
 		ww_mutex_lock_slow(cycle->b_mutex, &ctx);
 		erra = ww_mutex_lock(&cycle->a_mutex, &ctx);
+		if (erra != -EDEADLK)
+			break;
+
+		erra = 0;
+		ww_mutex_unlock(cycle->b_mutex);
+		ww_mutex_lock_slow(&cycle->a_mutex, &ctx);
+		err = ww_mutex_lock(cycle->b_mutex, &ctx);
+		if (err != -EDEADLK)
+			break;
 	}
 
+out:
 	if (!err)
 		ww_mutex_unlock(cycle->b_mutex);
 	if (!erra)
-- 
2.43.5
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.