15 #include <linux/sched.h>
27 static unsigned int debug_locks_verbose;
29 static int __init setup_debug_locks_verbose(
char *
str)
36 __setup(
"debug_locks_verbose=", setup_debug_locks_verbose);
41 #define LOCKTYPE_SPIN 0x1
42 #define LOCKTYPE_RWLOCK 0x2
43 #define LOCKTYPE_MUTEX 0x4
44 #define LOCKTYPE_RWSEM 0x8
108 #define INIT_CLASS_FUNC(class) \
109 static noinline void \
110 init_class_##class(spinlock_t *lock, rwlock_t *rwlock, struct mutex *mutex, \
111 struct rw_semaphore *rwsem) \
113 spin_lock_init(lock); \
114 rwlock_init(rwlock); \
123 static
void init_shared_classes(
void)
125 init_class_X(&lock_X1, &rwlock_X1, &mutex_X1, &rwsem_X1);
126 init_class_X(&lock_X2, &rwlock_X2, &mutex_X2, &rwsem_X2);
128 init_class_Y(&lock_Y1, &rwlock_Y1, &mutex_Y1, &rwsem_Y1);
129 init_class_Y(&lock_Y2, &rwlock_Y2, &mutex_Y2, &rwsem_Y2);
131 init_class_Z(&lock_Z1, &rwlock_Z1, &mutex_Z1, &rwsem_Z1);
132 init_class_Z(&lock_Z2, &rwlock_Z2, &mutex_Z2, &rwsem_Z2);
141 #define HARDIRQ_DISABLE local_irq_disable
142 #define HARDIRQ_ENABLE local_irq_enable
144 #define HARDIRQ_ENTER() \
145 local_irq_disable(); \
149 #define HARDIRQ_EXIT() \
153 #define SOFTIRQ_DISABLE local_bh_disable
154 #define SOFTIRQ_ENABLE local_bh_enable
156 #define SOFTIRQ_ENTER() \
157 local_bh_disable(); \
158 local_irq_disable(); \
159 lockdep_softirq_enter(); \
160 WARN_ON(!in_softirq());
162 #define SOFTIRQ_EXIT() \
163 lockdep_softirq_exit(); \
164 local_irq_enable(); \
171 #define L(x) spin_lock(&lock_##x)
172 #define U(x) spin_unlock(&lock_##x)
173 #define LU(x) L(x); U(x)
174 #define SI(x) spin_lock_init(&lock_##x)
176 #define WL(x) write_lock(&rwlock_##x)
177 #define WU(x) write_unlock(&rwlock_##x)
178 #define WLU(x) WL(x); WU(x)
180 #define RL(x) read_lock(&rwlock_##x)
181 #define RU(x) read_unlock(&rwlock_##x)
182 #define RLU(x) RL(x); RU(x)
183 #define RWI(x) rwlock_init(&rwlock_##x)
185 #define ML(x) mutex_lock(&mutex_##x)
186 #define MU(x) mutex_unlock(&mutex_##x)
187 #define MI(x) mutex_init(&mutex_##x)
189 #define WSL(x) down_write(&rwsem_##x)
190 #define WSU(x) up_write(&rwsem_##x)
192 #define RSL(x) down_read(&rwsem_##x)
193 #define RSU(x) up_read(&rwsem_##x)
194 #define RWSI(x) init_rwsem(&rwsem_##x)
196 #define LOCK_UNLOCK_2(x,y) LOCK(x); LOCK(y); UNLOCK(y); UNLOCK(x)
203 #define GENERATE_TESTCASE(name) \
205 static void name(void) { E(); }
207 #define GENERATE_PERMUTATIONS_2_EVENTS(name) \
209 static void name##_12(void) { E1(); E2(); } \
210 static void name##_21(void) { E2(); E1(); }
212 #define GENERATE_PERMUTATIONS_3_EVENTS(name) \
214 static void name##_123(void) { E1(); E2(); E3(); } \
215 static void name##_132(void) { E1(); E3(); E2(); } \
216 static void name##_213(void) { E2(); E1(); E3(); } \
217 static void name##_231(void) { E2(); E3(); E1(); } \
218 static void name##_312(void) { E3(); E1(); E2(); } \
219 static void name##_321(void) { E3(); E2(); E1(); }
235 #include "locking-selftest-wlock.h"
237 #include "locking-selftest-rlock.h"
239 #include "locking-selftest-mutex.h"
241 #include "locking-selftest-wsem.h"
243 #include "locking-selftest-rsem.h"
252 static void rlock_AA1(
void)
258 static void rlock_AA1B(
void)
264 static void rsem_AA1(
void)
270 static void rsem_AA1B(
void)
278 static void rlock_AA2(
void)
284 static void rsem_AA2(
void)
290 static void rlock_AA3(
void)
296 static void rsem_AA3(
void)
308 LOCK_UNLOCK_2(A, B); \
316 #include "locking-selftest-wlock.h"
318 #include "locking-selftest-rlock.h"
320 #include "locking-selftest-mutex.h"
322 #include "locking-selftest-wsem.h"
324 #include "locking-selftest-rsem.h"
335 LOCK_UNLOCK_2(A, B); \
336 LOCK_UNLOCK_2(B, C); \
344 #include "locking-selftest-wlock.h"
346 #include "locking-selftest-rlock.h"
348 #include "locking-selftest-mutex.h"
350 #include "locking-selftest-wsem.h"
352 #include "locking-selftest-rsem.h"
363 LOCK_UNLOCK_2(A, B); \
364 LOCK_UNLOCK_2(C, A); \
372 #include "locking-selftest-wlock.h"
374 #include "locking-selftest-rlock.h"
376 #include "locking-selftest-mutex.h"
378 #include "locking-selftest-wsem.h"
380 #include "locking-selftest-rsem.h"
391 LOCK_UNLOCK_2(A, B); \
392 LOCK_UNLOCK_2(B, C); \
393 LOCK_UNLOCK_2(C, D); \
401 #include "locking-selftest-wlock.h"
403 #include "locking-selftest-rlock.h"
405 #include "locking-selftest-mutex.h"
407 #include "locking-selftest-wsem.h"
409 #include "locking-selftest-rsem.h"
419 LOCK_UNLOCK_2(A, B); \
420 LOCK_UNLOCK_2(C, D); \
421 LOCK_UNLOCK_2(B, D); \
429 #include "locking-selftest-wlock.h"
431 #include "locking-selftest-rlock.h"
433 #include "locking-selftest-mutex.h"
435 #include "locking-selftest-wsem.h"
437 #include "locking-selftest-rsem.h"
447 LOCK_UNLOCK_2(A, B); \
448 LOCK_UNLOCK_2(C, D); \
449 LOCK_UNLOCK_2(B, C); \
457 #include "locking-selftest-wlock.h"
459 #include "locking-selftest-rlock.h"
461 #include "locking-selftest-mutex.h"
463 #include "locking-selftest-wsem.h"
465 #include "locking-selftest-rsem.h"
484 #include "locking-selftest-wlock.h"
486 #include "locking-selftest-rlock.h"
488 #include "locking-selftest-mutex.h"
490 #include "locking-selftest-wsem.h"
492 #include "locking-selftest-rsem.h"
512 #include "locking-selftest-wlock.h"
514 #include "locking-selftest-rlock.h"
516 #include "locking-selftest-mutex.h"
518 #include "locking-selftest-wsem.h"
520 #include "locking-selftest-rsem.h"
538 #include "locking-selftest-wlock.h"
540 #include "locking-selftest-rlock.h"
542 #include "locking-selftest-mutex.h"
544 #include "locking-selftest-wsem.h"
546 #include "locking-selftest-rsem.h"
572 #include "locking-selftest-rlock-hardirq.h"
575 #include "locking-selftest-wlock-hardirq.h"
578 #include "locking-selftest-spin-softirq.h"
581 #include "locking-selftest-rlock-softirq.h"
584 #include "locking-selftest-wlock-softirq.h"
613 #include "locking-selftest-wlock.h"
616 #include "locking-selftest-rlock.h"
645 #include "locking-selftest-rlock-hardirq.h"
648 #include "locking-selftest-wlock-hardirq.h"
651 #include "locking-selftest-spin-softirq.h"
654 #include "locking-selftest-rlock-softirq.h"
657 #include "locking-selftest-wlock-softirq.h"
691 #include "locking-selftest-rlock-hardirq.h"
694 #include "locking-selftest-wlock-hardirq.h"
697 #include "locking-selftest-spin-softirq.h"
700 #include "locking-selftest-rlock-softirq.h"
703 #include "locking-selftest-wlock-softirq.h"
739 #include "locking-selftest-rlock-hardirq.h"
742 #include "locking-selftest-wlock-hardirq.h"
745 #include "locking-selftest-spin-softirq.h"
748 #include "locking-selftest-rlock-softirq.h"
751 #include "locking-selftest-wlock-softirq.h"
801 #include "locking-selftest-rlock-hardirq.h"
804 #include "locking-selftest-wlock-hardirq.h"
807 #include "locking-selftest-spin-softirq.h"
810 #include "locking-selftest-rlock-softirq.h"
813 #include "locking-selftest-wlock-softirq.h"
851 #include "locking-selftest-softirq.h"
892 #ifdef CONFIG_DEBUG_LOCK_ALLOC
893 # define I_SPINLOCK(x) lockdep_reset_lock(&lock_##x.dep_map)
894 # define I_RWLOCK(x) lockdep_reset_lock(&rwlock_##x.dep_map)
895 # define I_MUTEX(x) lockdep_reset_lock(&mutex_##x.dep_map)
896 # define I_RWSEM(x) lockdep_reset_lock(&rwsem_##x.dep_map)
898 # define I_SPINLOCK(x)
914 spin_lock_init(&lock_##x); \
915 rwlock_init(&rwlock_##x); \
916 mutex_init(&mutex_##x); \
917 init_rwsem(&rwsem_##x); \
920 static void reset_locks(
void)
927 init_shared_classes();
933 static int testcase_total;
934 static int testcase_successes;
935 static int expected_testcase_failures;
936 static int unexpected_testcase_failures;
938 static void dotest(
void (*testcase_fn)(
void),
int expected,
int lockclass_mask)
941 int expected_failure = 0;
949 #ifndef CONFIG_PROVE_LOCKING
951 expected_failure = 1;
953 expected_failure = 1;
955 expected_failure = 1;
957 expected_failure = 1;
960 if (expected_failure) {
961 expected_testcase_failures++;
964 unexpected_testcase_failures++;
970 testcase_successes++;
975 if (debug_locks_verbose)
976 printk(
" lockclass mask: %x, debug_locks: %d, expected: %d\n",
983 #ifdef CONFIG_TRACE_IRQFLAGS
993 static inline void print_testname(
const char *testname)
995 printk(
"%33s:", testname);
998 #define DO_TESTCASE_1(desc, name, nr) \
999 print_testname(desc"/"#nr); \
1000 dotest(name##_##nr, SUCCESS, LOCKTYPE_RWLOCK); \
1003 #define DO_TESTCASE_1B(desc, name, nr) \
1004 print_testname(desc"/"#nr); \
1005 dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK); \
1008 #define DO_TESTCASE_3(desc, name, nr) \
1009 print_testname(desc"/"#nr); \
1010 dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN); \
1011 dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK); \
1012 dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK); \
1015 #define DO_TESTCASE_3RW(desc, name, nr) \
1016 print_testname(desc"/"#nr); \
1017 dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN|LOCKTYPE_RWLOCK);\
1018 dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK); \
1019 dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK); \
1022 #define DO_TESTCASE_6(desc, name) \
1023 print_testname(desc); \
1024 dotest(name##_spin, FAILURE, LOCKTYPE_SPIN); \
1025 dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK); \
1026 dotest(name##_rlock, FAILURE, LOCKTYPE_RWLOCK); \
1027 dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \
1028 dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \
1029 dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \
1032 #define DO_TESTCASE_6_SUCCESS(desc, name) \
1033 print_testname(desc); \
1034 dotest(name##_spin, SUCCESS, LOCKTYPE_SPIN); \
1035 dotest(name##_wlock, SUCCESS, LOCKTYPE_RWLOCK); \
1036 dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK); \
1037 dotest(name##_mutex, SUCCESS, LOCKTYPE_MUTEX); \
1038 dotest(name##_wsem, SUCCESS, LOCKTYPE_RWSEM); \
1039 dotest(name##_rsem, SUCCESS, LOCKTYPE_RWSEM); \
1045 #define DO_TESTCASE_6R(desc, name) \
1046 print_testname(desc); \
1047 dotest(name##_spin, FAILURE, LOCKTYPE_SPIN); \
1048 dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK); \
1049 dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK); \
1050 dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \
1051 dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \
1052 dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \
1055 #define DO_TESTCASE_2I(desc, name, nr) \
1056 DO_TESTCASE_1("hard-"desc, name##_hard, nr); \
1057 DO_TESTCASE_1("soft-"desc, name##_soft, nr);
1059 #define DO_TESTCASE_2IB(desc, name, nr) \
1060 DO_TESTCASE_1B("hard-"desc, name##_hard, nr); \
1061 DO_TESTCASE_1B("soft-"desc, name##_soft, nr);
1063 #define DO_TESTCASE_6I(desc, name, nr) \
1064 DO_TESTCASE_3("hard-"desc, name##_hard, nr); \
1065 DO_TESTCASE_3("soft-"desc, name##_soft, nr);
1067 #define DO_TESTCASE_6IRW(desc, name, nr) \
1068 DO_TESTCASE_3RW("hard-"desc, name##_hard, nr); \
1069 DO_TESTCASE_3RW("soft-"desc, name##_soft, nr);
1071 #define DO_TESTCASE_2x3(desc, name) \
1072 DO_TESTCASE_3(desc, name, 12); \
1073 DO_TESTCASE_3(desc, name, 21);
1075 #define DO_TESTCASE_2x6(desc, name) \
1076 DO_TESTCASE_6I(desc, name, 12); \
1077 DO_TESTCASE_6I(desc, name, 21);
1079 #define DO_TESTCASE_6x2(desc, name) \
1080 DO_TESTCASE_2I(desc, name, 123); \
1081 DO_TESTCASE_2I(desc, name, 132); \
1082 DO_TESTCASE_2I(desc, name, 213); \
1083 DO_TESTCASE_2I(desc, name, 231); \
1084 DO_TESTCASE_2I(desc, name, 312); \
1085 DO_TESTCASE_2I(desc, name, 321);
1087 #define DO_TESTCASE_6x2B(desc, name) \
1088 DO_TESTCASE_2IB(desc, name, 123); \
1089 DO_TESTCASE_2IB(desc, name, 132); \
1090 DO_TESTCASE_2IB(desc, name, 213); \
1091 DO_TESTCASE_2IB(desc, name, 231); \
1092 DO_TESTCASE_2IB(desc, name, 312); \
1093 DO_TESTCASE_2IB(desc, name, 321);
1095 #define DO_TESTCASE_6x6(desc, name) \
1096 DO_TESTCASE_6I(desc, name, 123); \
1097 DO_TESTCASE_6I(desc, name, 132); \
1098 DO_TESTCASE_6I(desc, name, 213); \
1099 DO_TESTCASE_6I(desc, name, 231); \
1100 DO_TESTCASE_6I(desc, name, 312); \
1101 DO_TESTCASE_6I(desc, name, 321);
1103 #define DO_TESTCASE_6x6RW(desc, name) \
1104 DO_TESTCASE_6IRW(desc, name, 123); \
1105 DO_TESTCASE_6IRW(desc, name, 132); \
1106 DO_TESTCASE_6IRW(desc, name, 213); \
1107 DO_TESTCASE_6IRW(desc, name, 231); \
1108 DO_TESTCASE_6IRW(desc, name, 312); \
1109 DO_TESTCASE_6IRW(desc, name, 321);
1118 printk(
"----------------------------------\n");
1119 printk(
"| Locking API testsuite disabled |\n");
1120 printk(
"----------------------------------\n");
1127 printk(
"------------------------\n");
1128 printk(
"| Locking API testsuite:\n");
1129 printk(
"----------------------------------------------------------------------------\n");
1130 printk(
" | spin |wlock |rlock |mutex | wsem | rsem |\n");
1131 printk(
" --------------------------------------------------------------------------\n");
1133 init_shared_classes();
1147 printk(
" --------------------------------------------------------------------------\n");
1148 print_testname(
"recursive read-lock");
1150 dotest(rlock_AA1,
SUCCESS, LOCKTYPE_RWLOCK);
1152 dotest(rsem_AA1,
FAILURE, LOCKTYPE_RWSEM);
1155 print_testname(
"recursive read-lock #2");
1157 dotest(rlock_AA1B,
SUCCESS, LOCKTYPE_RWLOCK);
1159 dotest(rsem_AA1B,
FAILURE, LOCKTYPE_RWSEM);
1162 print_testname(
"mixed read-write-lock");
1164 dotest(rlock_AA2,
FAILURE, LOCKTYPE_RWLOCK);
1166 dotest(rsem_AA2,
FAILURE, LOCKTYPE_RWSEM);
1169 print_testname(
"mixed write-read-lock");
1171 dotest(rlock_AA3,
FAILURE, LOCKTYPE_RWLOCK);
1173 dotest(rsem_AA3,
FAILURE, LOCKTYPE_RWSEM);
1176 printk(
" --------------------------------------------------------------------------\n");
1191 if (unexpected_testcase_failures) {
1192 printk(
"-----------------------------------------------------------------\n");
1194 printk(
"BUG: %3d unexpected failures (out of %3d) - debugging disabled! |\n",
1195 unexpected_testcase_failures, testcase_total);
1196 printk(
"-----------------------------------------------------------------\n");
1197 }
else if (expected_testcase_failures && testcase_successes) {
1198 printk(
"--------------------------------------------------------\n");
1199 printk(
"%3d out of %3d testcases failed, as expected. |\n",
1200 expected_testcase_failures, testcase_total);
1201 printk(
"----------------------------------------------------\n");
1203 }
else if (expected_testcase_failures && !testcase_successes) {
1204 printk(
"--------------------------------------------------------\n");
1205 printk(
"All %3d testcases failed, as expected. |\n",
1206 expected_testcase_failures);
1207 printk(
"----------------------------------------\n");
1210 printk(
"-------------------------------------------------------\n");
1211 printk(
"Good, all %3d testcases passed! |\n",
1212 testcase_successes);
1213 printk(
"---------------------------------\n");