diff options
author | Peter Zijlstra <peterz@infradead.org> | 2017-05-31 11:11:49 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2017-06-08 04:35:50 -0400 |
commit | 018956d6419be3e5ff5aacc60b2a3cff585adee1 (patch) | |
tree | 6ecde8e95a6fc80d93933ab0e4d8c8463ea3b1ce /lib/locking-selftest.c | |
parent | cfb6133399a490419cda55fcdcf9dbbca65eacba (diff) |
locking/selftest: Add RT-mutex support
Now that RT-mutex has lockdep annotations, add them to the selftest.
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: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'lib/locking-selftest.c')
-rw-r--r-- | lib/locking-selftest.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c index dd09e517c492..6f2b135dc5e8 100644 --- a/lib/locking-selftest.c +++ b/lib/locking-selftest.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
22 | #include <linux/debug_locks.h> | 22 | #include <linux/debug_locks.h> |
23 | #include <linux/irqflags.h> | 23 | #include <linux/irqflags.h> |
24 | #include <linux/rtmutex.h> | ||
24 | 25 | ||
25 | /* | 26 | /* |
26 | * Change this to 1 if you want to see the failure printouts: | 27 | * Change this to 1 if you want to see the failure printouts: |
@@ -46,6 +47,7 @@ __setup("debug_locks_verbose=", setup_debug_locks_verbose); | |||
46 | #define LOCKTYPE_MUTEX 0x4 | 47 | #define LOCKTYPE_MUTEX 0x4 |
47 | #define LOCKTYPE_RWSEM 0x8 | 48 | #define LOCKTYPE_RWSEM 0x8 |
48 | #define LOCKTYPE_WW 0x10 | 49 | #define LOCKTYPE_WW 0x10 |
50 | #define LOCKTYPE_RTMUTEX 0x20 | ||
49 | 51 | ||
50 | static struct ww_acquire_ctx t, t2; | 52 | static struct ww_acquire_ctx t, t2; |
51 | static struct ww_mutex o, o2, o3; | 53 | static struct ww_mutex o, o2, o3; |
@@ -74,6 +76,15 @@ static DECLARE_RWSEM(rwsem_B); | |||
74 | static DECLARE_RWSEM(rwsem_C); | 76 | static DECLARE_RWSEM(rwsem_C); |
75 | static DECLARE_RWSEM(rwsem_D); | 77 | static DECLARE_RWSEM(rwsem_D); |
76 | 78 | ||
79 | #ifdef CONFIG_RT_MUTEXES | ||
80 | |||
81 | static DEFINE_RT_MUTEX(rtmutex_A); | ||
82 | static DEFINE_RT_MUTEX(rtmutex_B); | ||
83 | static DEFINE_RT_MUTEX(rtmutex_C); | ||
84 | static DEFINE_RT_MUTEX(rtmutex_D); | ||
85 | |||
86 | #endif | ||
87 | |||
77 | /* | 88 | /* |
78 | * Locks that we initialize dynamically as well so that | 89 | * Locks that we initialize dynamically as well so that |
79 | * e.g. X1 and X2 becomes two instances of the same class, | 90 | * e.g. X1 and X2 becomes two instances of the same class, |
@@ -108,6 +119,17 @@ static DECLARE_RWSEM(rwsem_Y2); | |||
108 | static DECLARE_RWSEM(rwsem_Z1); | 119 | static DECLARE_RWSEM(rwsem_Z1); |
109 | static DECLARE_RWSEM(rwsem_Z2); | 120 | static DECLARE_RWSEM(rwsem_Z2); |
110 | 121 | ||
122 | #ifdef CONFIG_RT_MUTEXES | ||
123 | |||
124 | static DEFINE_RT_MUTEX(rtmutex_X1); | ||
125 | static DEFINE_RT_MUTEX(rtmutex_X2); | ||
126 | static DEFINE_RT_MUTEX(rtmutex_Y1); | ||
127 | static DEFINE_RT_MUTEX(rtmutex_Y2); | ||
128 | static DEFINE_RT_MUTEX(rtmutex_Z1); | ||
129 | static DEFINE_RT_MUTEX(rtmutex_Z2); | ||
130 | |||
131 | #endif | ||
132 | |||
111 | /* | 133 | /* |
112 | * non-inlined runtime initializers, to let separate locks share | 134 | * non-inlined runtime initializers, to let separate locks share |
113 | * the same lock-class: | 135 | * the same lock-class: |
@@ -129,6 +151,17 @@ INIT_CLASS_FUNC(Z) | |||
129 | 151 | ||
130 | static void init_shared_classes(void) | 152 | static void init_shared_classes(void) |
131 | { | 153 | { |
154 | #ifdef CONFIG_RT_MUTEXES | ||
155 | static struct lock_class_key rt_X, rt_Y, rt_Z; | ||
156 | |||
157 | __rt_mutex_init(&rtmutex_X1, __func__, &rt_X); | ||
158 | __rt_mutex_init(&rtmutex_X2, __func__, &rt_X); | ||
159 | __rt_mutex_init(&rtmutex_Y1, __func__, &rt_Y); | ||
160 | __rt_mutex_init(&rtmutex_Y2, __func__, &rt_Y); | ||
161 | __rt_mutex_init(&rtmutex_Z1, __func__, &rt_Z); | ||
162 | __rt_mutex_init(&rtmutex_Z2, __func__, &rt_Z); | ||
163 | #endif | ||
164 | |||
132 | init_class_X(&lock_X1, &rwlock_X1, &mutex_X1, &rwsem_X1); | 165 | init_class_X(&lock_X1, &rwlock_X1, &mutex_X1, &rwsem_X1); |
133 | init_class_X(&lock_X2, &rwlock_X2, &mutex_X2, &rwsem_X2); | 166 | init_class_X(&lock_X2, &rwlock_X2, &mutex_X2, &rwsem_X2); |
134 | 167 | ||
@@ -193,6 +226,10 @@ static void init_shared_classes(void) | |||
193 | #define MU(x) mutex_unlock(&mutex_##x) | 226 | #define MU(x) mutex_unlock(&mutex_##x) |
194 | #define MI(x) mutex_init(&mutex_##x) | 227 | #define MI(x) mutex_init(&mutex_##x) |
195 | 228 | ||
229 | #define RTL(x) rt_mutex_lock(&rtmutex_##x) | ||
230 | #define RTU(x) rt_mutex_unlock(&rtmutex_##x) | ||
231 | #define RTI(x) rt_mutex_init(&rtmutex_##x) | ||
232 | |||
196 | #define WSL(x) down_write(&rwsem_##x) | 233 | #define WSL(x) down_write(&rwsem_##x) |
197 | #define WSU(x) up_write(&rwsem_##x) | 234 | #define WSU(x) up_write(&rwsem_##x) |
198 | 235 | ||
@@ -264,6 +301,11 @@ GENERATE_TESTCASE(AA_wsem) | |||
264 | #include "locking-selftest-rsem.h" | 301 | #include "locking-selftest-rsem.h" |
265 | GENERATE_TESTCASE(AA_rsem) | 302 | GENERATE_TESTCASE(AA_rsem) |
266 | 303 | ||
304 | #ifdef CONFIG_RT_MUTEXES | ||
305 | #include "locking-selftest-rtmutex.h" | ||
306 | GENERATE_TESTCASE(AA_rtmutex); | ||
307 | #endif | ||
308 | |||
267 | #undef E | 309 | #undef E |
268 | 310 | ||
269 | /* | 311 | /* |
@@ -345,6 +387,11 @@ GENERATE_TESTCASE(ABBA_wsem) | |||
345 | #include "locking-selftest-rsem.h" | 387 | #include "locking-selftest-rsem.h" |
346 | GENERATE_TESTCASE(ABBA_rsem) | 388 | GENERATE_TESTCASE(ABBA_rsem) |
347 | 389 | ||
390 | #ifdef CONFIG_RT_MUTEXES | ||
391 | #include "locking-selftest-rtmutex.h" | ||
392 | GENERATE_TESTCASE(ABBA_rtmutex); | ||
393 | #endif | ||
394 | |||
348 | #undef E | 395 | #undef E |
349 | 396 | ||
350 | /* | 397 | /* |
@@ -373,6 +420,11 @@ GENERATE_TESTCASE(ABBCCA_wsem) | |||
373 | #include "locking-selftest-rsem.h" | 420 | #include "locking-selftest-rsem.h" |
374 | GENERATE_TESTCASE(ABBCCA_rsem) | 421 | GENERATE_TESTCASE(ABBCCA_rsem) |
375 | 422 | ||
423 | #ifdef CONFIG_RT_MUTEXES | ||
424 | #include "locking-selftest-rtmutex.h" | ||
425 | GENERATE_TESTCASE(ABBCCA_rtmutex); | ||
426 | #endif | ||
427 | |||
376 | #undef E | 428 | #undef E |
377 | 429 | ||
378 | /* | 430 | /* |
@@ -401,6 +453,11 @@ GENERATE_TESTCASE(ABCABC_wsem) | |||
401 | #include "locking-selftest-rsem.h" | 453 | #include "locking-selftest-rsem.h" |
402 | GENERATE_TESTCASE(ABCABC_rsem) | 454 | GENERATE_TESTCASE(ABCABC_rsem) |
403 | 455 | ||
456 | #ifdef CONFIG_RT_MUTEXES | ||
457 | #include "locking-selftest-rtmutex.h" | ||
458 | GENERATE_TESTCASE(ABCABC_rtmutex); | ||
459 | #endif | ||
460 | |||
404 | #undef E | 461 | #undef E |
405 | 462 | ||
406 | /* | 463 | /* |
@@ -430,6 +487,11 @@ GENERATE_TESTCASE(ABBCCDDA_wsem) | |||
430 | #include "locking-selftest-rsem.h" | 487 | #include "locking-selftest-rsem.h" |
431 | GENERATE_TESTCASE(ABBCCDDA_rsem) | 488 | GENERATE_TESTCASE(ABBCCDDA_rsem) |
432 | 489 | ||
490 | #ifdef CONFIG_RT_MUTEXES | ||
491 | #include "locking-selftest-rtmutex.h" | ||
492 | GENERATE_TESTCASE(ABBCCDDA_rtmutex); | ||
493 | #endif | ||
494 | |||
433 | #undef E | 495 | #undef E |
434 | 496 | ||
435 | /* | 497 | /* |
@@ -458,6 +520,11 @@ GENERATE_TESTCASE(ABCDBDDA_wsem) | |||
458 | #include "locking-selftest-rsem.h" | 520 | #include "locking-selftest-rsem.h" |
459 | GENERATE_TESTCASE(ABCDBDDA_rsem) | 521 | GENERATE_TESTCASE(ABCDBDDA_rsem) |
460 | 522 | ||
523 | #ifdef CONFIG_RT_MUTEXES | ||
524 | #include "locking-selftest-rtmutex.h" | ||
525 | GENERATE_TESTCASE(ABCDBDDA_rtmutex); | ||
526 | #endif | ||
527 | |||
461 | #undef E | 528 | #undef E |
462 | 529 | ||
463 | /* | 530 | /* |
@@ -486,6 +553,11 @@ GENERATE_TESTCASE(ABCDBCDA_wsem) | |||
486 | #include "locking-selftest-rsem.h" | 553 | #include "locking-selftest-rsem.h" |
487 | GENERATE_TESTCASE(ABCDBCDA_rsem) | 554 | GENERATE_TESTCASE(ABCDBCDA_rsem) |
488 | 555 | ||
556 | #ifdef CONFIG_RT_MUTEXES | ||
557 | #include "locking-selftest-rtmutex.h" | ||
558 | GENERATE_TESTCASE(ABCDBCDA_rtmutex); | ||
559 | #endif | ||
560 | |||
489 | #undef E | 561 | #undef E |
490 | 562 | ||
491 | /* | 563 | /* |
@@ -513,6 +585,11 @@ GENERATE_TESTCASE(double_unlock_wsem) | |||
513 | #include "locking-selftest-rsem.h" | 585 | #include "locking-selftest-rsem.h" |
514 | GENERATE_TESTCASE(double_unlock_rsem) | 586 | GENERATE_TESTCASE(double_unlock_rsem) |
515 | 587 | ||
588 | #ifdef CONFIG_RT_MUTEXES | ||
589 | #include "locking-selftest-rtmutex.h" | ||
590 | GENERATE_TESTCASE(double_unlock_rtmutex); | ||
591 | #endif | ||
592 | |||
516 | #undef E | 593 | #undef E |
517 | 594 | ||
518 | /* | 595 | /* |
@@ -539,6 +616,11 @@ GENERATE_TESTCASE(init_held_wsem) | |||
539 | #include "locking-selftest-rsem.h" | 616 | #include "locking-selftest-rsem.h" |
540 | GENERATE_TESTCASE(init_held_rsem) | 617 | GENERATE_TESTCASE(init_held_rsem) |
541 | 618 | ||
619 | #ifdef CONFIG_RT_MUTEXES | ||
620 | #include "locking-selftest-rtmutex.h" | ||
621 | GENERATE_TESTCASE(init_held_rtmutex); | ||
622 | #endif | ||
623 | |||
542 | #undef E | 624 | #undef E |
543 | 625 | ||
544 | /* | 626 | /* |
@@ -888,6 +970,9 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft) | |||
888 | # define I_MUTEX(x) lockdep_reset_lock(&mutex_##x.dep_map) | 970 | # define I_MUTEX(x) lockdep_reset_lock(&mutex_##x.dep_map) |
889 | # define I_RWSEM(x) lockdep_reset_lock(&rwsem_##x.dep_map) | 971 | # define I_RWSEM(x) lockdep_reset_lock(&rwsem_##x.dep_map) |
890 | # define I_WW(x) lockdep_reset_lock(&x.dep_map) | 972 | # define I_WW(x) lockdep_reset_lock(&x.dep_map) |
973 | #ifdef CONFIG_RT_MUTEXES | ||
974 | # define I_RTMUTEX(x) lockdep_reset_lock(&rtmutex_##x.dep_map) | ||
975 | #endif | ||
891 | #else | 976 | #else |
892 | # define I_SPINLOCK(x) | 977 | # define I_SPINLOCK(x) |
893 | # define I_RWLOCK(x) | 978 | # define I_RWLOCK(x) |
@@ -896,12 +981,23 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft) | |||
896 | # define I_WW(x) | 981 | # define I_WW(x) |
897 | #endif | 982 | #endif |
898 | 983 | ||
984 | #ifndef I_RTMUTEX | ||
985 | # define I_RTMUTEX(x) | ||
986 | #endif | ||
987 | |||
988 | #ifdef CONFIG_RT_MUTEXES | ||
989 | #define I2_RTMUTEX(x) rt_mutex_init(&rtmutex_##x) | ||
990 | #else | ||
991 | #define I2_RTMUTEX(x) | ||
992 | #endif | ||
993 | |||
899 | #define I1(x) \ | 994 | #define I1(x) \ |
900 | do { \ | 995 | do { \ |
901 | I_SPINLOCK(x); \ | 996 | I_SPINLOCK(x); \ |
902 | I_RWLOCK(x); \ | 997 | I_RWLOCK(x); \ |
903 | I_MUTEX(x); \ | 998 | I_MUTEX(x); \ |
904 | I_RWSEM(x); \ | 999 | I_RWSEM(x); \ |
1000 | I_RTMUTEX(x); \ | ||
905 | } while (0) | 1001 | } while (0) |
906 | 1002 | ||
907 | #define I2(x) \ | 1003 | #define I2(x) \ |
@@ -910,6 +1006,7 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft) | |||
910 | rwlock_init(&rwlock_##x); \ | 1006 | rwlock_init(&rwlock_##x); \ |
911 | mutex_init(&mutex_##x); \ | 1007 | mutex_init(&mutex_##x); \ |
912 | init_rwsem(&rwsem_##x); \ | 1008 | init_rwsem(&rwsem_##x); \ |
1009 | I2_RTMUTEX(x); \ | ||
913 | } while (0) | 1010 | } while (0) |
914 | 1011 | ||
915 | static void reset_locks(void) | 1012 | static void reset_locks(void) |
@@ -985,6 +1082,12 @@ static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask) | |||
985 | reset_locks(); | 1082 | reset_locks(); |
986 | } | 1083 | } |
987 | 1084 | ||
1085 | #ifdef CONFIG_RT_MUTEXES | ||
1086 | #define dotest_rt(fn, e, m) dotest((fn), (e), (m)) | ||
1087 | #else | ||
1088 | #define dotest_rt(fn, e, m) | ||
1089 | #endif | ||
1090 | |||
988 | static inline void print_testname(const char *testname) | 1091 | static inline void print_testname(const char *testname) |
989 | { | 1092 | { |
990 | printk("%33s:", testname); | 1093 | printk("%33s:", testname); |
@@ -1022,6 +1125,7 @@ static inline void print_testname(const char *testname) | |||
1022 | dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \ | 1125 | dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \ |
1023 | dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \ | 1126 | dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \ |
1024 | dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \ | 1127 | dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \ |
1128 | dotest_rt(name##_rtmutex, FAILURE, LOCKTYPE_RTMUTEX); \ | ||
1025 | pr_cont("\n"); | 1129 | pr_cont("\n"); |
1026 | 1130 | ||
1027 | #define DO_TESTCASE_6_SUCCESS(desc, name) \ | 1131 | #define DO_TESTCASE_6_SUCCESS(desc, name) \ |
@@ -1032,6 +1136,7 @@ static inline void print_testname(const char *testname) | |||
1032 | dotest(name##_mutex, SUCCESS, LOCKTYPE_MUTEX); \ | 1136 | dotest(name##_mutex, SUCCESS, LOCKTYPE_MUTEX); \ |
1033 | dotest(name##_wsem, SUCCESS, LOCKTYPE_RWSEM); \ | 1137 | dotest(name##_wsem, SUCCESS, LOCKTYPE_RWSEM); \ |
1034 | dotest(name##_rsem, SUCCESS, LOCKTYPE_RWSEM); \ | 1138 | dotest(name##_rsem, SUCCESS, LOCKTYPE_RWSEM); \ |
1139 | dotest_rt(name##_rtmutex, SUCCESS, LOCKTYPE_RTMUTEX); \ | ||
1035 | pr_cont("\n"); | 1140 | pr_cont("\n"); |
1036 | 1141 | ||
1037 | /* | 1142 | /* |
@@ -1045,6 +1150,7 @@ static inline void print_testname(const char *testname) | |||
1045 | dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \ | 1150 | dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \ |
1046 | dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \ | 1151 | dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \ |
1047 | dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \ | 1152 | dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \ |
1153 | dotest_rt(name##_rtmutex, FAILURE, LOCKTYPE_RTMUTEX); \ | ||
1048 | pr_cont("\n"); | 1154 | pr_cont("\n"); |
1049 | 1155 | ||
1050 | #define DO_TESTCASE_2I(desc, name, nr) \ | 1156 | #define DO_TESTCASE_2I(desc, name, nr) \ |