diff options
author | Peter Zijlstra <peterz@infradead.org> | 2017-08-23 07:13:11 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2017-08-25 05:06:31 -0400 |
commit | e91498589746065e3ae95d9a00b068e525eec34f (patch) | |
tree | 9b7d6663dbfce16abc8cb6228c56dd72e4fff83c | |
parent | 0e709703af5bbc9ea6e75e1f99c2dd0dae261869 (diff) |
locking/lockdep/selftests: Add mixed read-write ABBA tests
Currently lockdep has limited support for recursive readers, add a few
mixed read-write ABBA selftests to show the extend of these
limitations.
[ 0.000000] ----------------------------------------------------------------------------
[ 0.000000] | spin |wlock |rlock |mutex | wsem | rsem |
[ 0.000000] --------------------------------------------------------------------------
[ 0.000000] mixed read-lock/lock-write ABBA: |FAILED| | ok |
[ 0.000000] mixed read-lock/lock-read ABBA: | ok | | ok |
[ 0.000000] mixed write-lock/lock-write ABBA: | ok | | ok |
This clearly illustrates the case where lockdep fails to find a
deadlock.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: boqun.feng@gmail.com
Cc: byungchul.park@lge.com
Cc: david@fromorbit.com
Cc: johannes@sipsolutions.net
Cc: oleg@redhat.com
Cc: tj@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | lib/locking-selftest.c | 117 |
1 files changed, 115 insertions, 2 deletions
diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c index 6f2b135dc5e8..3c7151a6cd98 100644 --- a/lib/locking-selftest.c +++ b/lib/locking-selftest.c | |||
@@ -363,6 +363,103 @@ static void rsem_AA3(void) | |||
363 | } | 363 | } |
364 | 364 | ||
365 | /* | 365 | /* |
366 | * read_lock(A) | ||
367 | * spin_lock(B) | ||
368 | * spin_lock(B) | ||
369 | * write_lock(A) | ||
370 | */ | ||
371 | static void rlock_ABBA1(void) | ||
372 | { | ||
373 | RL(X1); | ||
374 | L(Y1); | ||
375 | U(Y1); | ||
376 | RU(X1); | ||
377 | |||
378 | L(Y1); | ||
379 | WL(X1); | ||
380 | WU(X1); | ||
381 | U(Y1); // should fail | ||
382 | } | ||
383 | |||
384 | static void rwsem_ABBA1(void) | ||
385 | { | ||
386 | RSL(X1); | ||
387 | ML(Y1); | ||
388 | MU(Y1); | ||
389 | RSU(X1); | ||
390 | |||
391 | ML(Y1); | ||
392 | WSL(X1); | ||
393 | WSU(X1); | ||
394 | MU(Y1); // should fail | ||
395 | } | ||
396 | |||
397 | /* | ||
398 | * read_lock(A) | ||
399 | * spin_lock(B) | ||
400 | * spin_lock(B) | ||
401 | * read_lock(A) | ||
402 | */ | ||
403 | static void rlock_ABBA2(void) | ||
404 | { | ||
405 | RL(X1); | ||
406 | L(Y1); | ||
407 | U(Y1); | ||
408 | RU(X1); | ||
409 | |||
410 | L(Y1); | ||
411 | RL(X1); | ||
412 | RU(X1); | ||
413 | U(Y1); // should NOT fail | ||
414 | } | ||
415 | |||
416 | static void rwsem_ABBA2(void) | ||
417 | { | ||
418 | RSL(X1); | ||
419 | ML(Y1); | ||
420 | MU(Y1); | ||
421 | RSU(X1); | ||
422 | |||
423 | ML(Y1); | ||
424 | RSL(X1); | ||
425 | RSU(X1); | ||
426 | MU(Y1); // should fail | ||
427 | } | ||
428 | |||
429 | |||
430 | /* | ||
431 | * write_lock(A) | ||
432 | * spin_lock(B) | ||
433 | * spin_lock(B) | ||
434 | * write_lock(A) | ||
435 | */ | ||
436 | static void rlock_ABBA3(void) | ||
437 | { | ||
438 | WL(X1); | ||
439 | L(Y1); | ||
440 | U(Y1); | ||
441 | WU(X1); | ||
442 | |||
443 | L(Y1); | ||
444 | WL(X1); | ||
445 | WU(X1); | ||
446 | U(Y1); // should fail | ||
447 | } | ||
448 | |||
449 | static void rwsem_ABBA3(void) | ||
450 | { | ||
451 | WSL(X1); | ||
452 | ML(Y1); | ||
453 | MU(Y1); | ||
454 | WSU(X1); | ||
455 | |||
456 | ML(Y1); | ||
457 | WSL(X1); | ||
458 | WSU(X1); | ||
459 | MU(Y1); // should fail | ||
460 | } | ||
461 | |||
462 | /* | ||
366 | * ABBA deadlock: | 463 | * ABBA deadlock: |
367 | */ | 464 | */ |
368 | 465 | ||
@@ -1056,8 +1153,6 @@ static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask) | |||
1056 | if (debug_locks != expected) { | 1153 | if (debug_locks != expected) { |
1057 | unexpected_testcase_failures++; | 1154 | unexpected_testcase_failures++; |
1058 | pr_cont("FAILED|"); | 1155 | pr_cont("FAILED|"); |
1059 | |||
1060 | dump_stack(); | ||
1061 | } else { | 1156 | } else { |
1062 | testcase_successes++; | 1157 | testcase_successes++; |
1063 | pr_cont(" ok |"); | 1158 | pr_cont(" ok |"); |
@@ -1933,6 +2028,24 @@ void locking_selftest(void) | |||
1933 | dotest(rsem_AA3, FAILURE, LOCKTYPE_RWSEM); | 2028 | dotest(rsem_AA3, FAILURE, LOCKTYPE_RWSEM); |
1934 | pr_cont("\n"); | 2029 | pr_cont("\n"); |
1935 | 2030 | ||
2031 | print_testname("mixed read-lock/lock-write ABBA"); | ||
2032 | pr_cont(" |"); | ||
2033 | dotest(rlock_ABBA1, FAILURE, LOCKTYPE_RWLOCK); | ||
2034 | pr_cont(" |"); | ||
2035 | dotest(rwsem_ABBA1, FAILURE, LOCKTYPE_RWSEM); | ||
2036 | |||
2037 | print_testname("mixed read-lock/lock-read ABBA"); | ||
2038 | pr_cont(" |"); | ||
2039 | dotest(rlock_ABBA2, SUCCESS, LOCKTYPE_RWLOCK); | ||
2040 | pr_cont(" |"); | ||
2041 | dotest(rwsem_ABBA2, FAILURE, LOCKTYPE_RWSEM); | ||
2042 | |||
2043 | print_testname("mixed write-lock/lock-write ABBA"); | ||
2044 | pr_cont(" |"); | ||
2045 | dotest(rlock_ABBA3, FAILURE, LOCKTYPE_RWLOCK); | ||
2046 | pr_cont(" |"); | ||
2047 | dotest(rwsem_ABBA3, FAILURE, LOCKTYPE_RWSEM); | ||
2048 | |||
1936 | printk(" --------------------------------------------------------------------------\n"); | 2049 | printk(" --------------------------------------------------------------------------\n"); |
1937 | 2050 | ||
1938 | /* | 2051 | /* |