xref: /linux-6.15/lib/locking-selftest.c (revision cae2ed9a)
1*cae2ed9aSIngo Molnar /*
2*cae2ed9aSIngo Molnar  * lib/locking-selftest.c
3*cae2ed9aSIngo Molnar  *
4*cae2ed9aSIngo Molnar  * Testsuite for various locking APIs: spinlocks, rwlocks,
5*cae2ed9aSIngo Molnar  * mutexes and rw-semaphores.
6*cae2ed9aSIngo Molnar  *
7*cae2ed9aSIngo Molnar  * It is checking both false positives and false negatives.
8*cae2ed9aSIngo Molnar  *
9*cae2ed9aSIngo Molnar  * Started by Ingo Molnar:
10*cae2ed9aSIngo Molnar  *
11*cae2ed9aSIngo Molnar  *  Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <[email protected]>
12*cae2ed9aSIngo Molnar  */
13*cae2ed9aSIngo Molnar #include <linux/rwsem.h>
14*cae2ed9aSIngo Molnar #include <linux/mutex.h>
15*cae2ed9aSIngo Molnar #include <linux/sched.h>
16*cae2ed9aSIngo Molnar #include <linux/delay.h>
17*cae2ed9aSIngo Molnar #include <linux/module.h>
18*cae2ed9aSIngo Molnar #include <linux/spinlock.h>
19*cae2ed9aSIngo Molnar #include <linux/kallsyms.h>
20*cae2ed9aSIngo Molnar #include <linux/interrupt.h>
21*cae2ed9aSIngo Molnar #include <linux/debug_locks.h>
22*cae2ed9aSIngo Molnar #include <linux/irqflags.h>
23*cae2ed9aSIngo Molnar 
24*cae2ed9aSIngo Molnar /*
25*cae2ed9aSIngo Molnar  * Change this to 1 if you want to see the failure printouts:
26*cae2ed9aSIngo Molnar  */
27*cae2ed9aSIngo Molnar static unsigned int debug_locks_verbose;
28*cae2ed9aSIngo Molnar 
29*cae2ed9aSIngo Molnar static int __init setup_debug_locks_verbose(char *str)
30*cae2ed9aSIngo Molnar {
31*cae2ed9aSIngo Molnar 	get_option(&str, &debug_locks_verbose);
32*cae2ed9aSIngo Molnar 
33*cae2ed9aSIngo Molnar 	return 1;
34*cae2ed9aSIngo Molnar }
35*cae2ed9aSIngo Molnar 
36*cae2ed9aSIngo Molnar __setup("debug_locks_verbose=", setup_debug_locks_verbose);
37*cae2ed9aSIngo Molnar 
38*cae2ed9aSIngo Molnar #define FAILURE		0
39*cae2ed9aSIngo Molnar #define SUCCESS		1
40*cae2ed9aSIngo Molnar 
41*cae2ed9aSIngo Molnar #define LOCKTYPE_SPIN	0x1
42*cae2ed9aSIngo Molnar #define LOCKTYPE_RWLOCK	0x2
43*cae2ed9aSIngo Molnar #define LOCKTYPE_MUTEX	0x4
44*cae2ed9aSIngo Molnar #define LOCKTYPE_RWSEM	0x8
45*cae2ed9aSIngo Molnar 
46*cae2ed9aSIngo Molnar /*
47*cae2ed9aSIngo Molnar  * Normal standalone locks, for the circular and irq-context
48*cae2ed9aSIngo Molnar  * dependency tests:
49*cae2ed9aSIngo Molnar  */
50*cae2ed9aSIngo Molnar static DEFINE_SPINLOCK(lock_A);
51*cae2ed9aSIngo Molnar static DEFINE_SPINLOCK(lock_B);
52*cae2ed9aSIngo Molnar static DEFINE_SPINLOCK(lock_C);
53*cae2ed9aSIngo Molnar static DEFINE_SPINLOCK(lock_D);
54*cae2ed9aSIngo Molnar 
55*cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_A);
56*cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_B);
57*cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_C);
58*cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_D);
59*cae2ed9aSIngo Molnar 
60*cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_A);
61*cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_B);
62*cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_C);
63*cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_D);
64*cae2ed9aSIngo Molnar 
65*cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_A);
66*cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_B);
67*cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_C);
68*cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_D);
69*cae2ed9aSIngo Molnar 
70*cae2ed9aSIngo Molnar /*
71*cae2ed9aSIngo Molnar  * Locks that we initialize dynamically as well so that
72*cae2ed9aSIngo Molnar  * e.g. X1 and X2 becomes two instances of the same class,
73*cae2ed9aSIngo Molnar  * but X* and Y* are different classes. We do this so that
74*cae2ed9aSIngo Molnar  * we do not trigger a real lockup:
75*cae2ed9aSIngo Molnar  */
76*cae2ed9aSIngo Molnar static DEFINE_SPINLOCK(lock_X1);
77*cae2ed9aSIngo Molnar static DEFINE_SPINLOCK(lock_X2);
78*cae2ed9aSIngo Molnar static DEFINE_SPINLOCK(lock_Y1);
79*cae2ed9aSIngo Molnar static DEFINE_SPINLOCK(lock_Y2);
80*cae2ed9aSIngo Molnar static DEFINE_SPINLOCK(lock_Z1);
81*cae2ed9aSIngo Molnar static DEFINE_SPINLOCK(lock_Z2);
82*cae2ed9aSIngo Molnar 
83*cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_X1);
84*cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_X2);
85*cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Y1);
86*cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Y2);
87*cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Z1);
88*cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Z2);
89*cae2ed9aSIngo Molnar 
90*cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_X1);
91*cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_X2);
92*cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Y1);
93*cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Y2);
94*cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Z1);
95*cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Z2);
96*cae2ed9aSIngo Molnar 
97*cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_X1);
98*cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_X2);
99*cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Y1);
100*cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Y2);
101*cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Z1);
102*cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Z2);
103*cae2ed9aSIngo Molnar 
104*cae2ed9aSIngo Molnar /*
105*cae2ed9aSIngo Molnar  * non-inlined runtime initializers, to let separate locks share
106*cae2ed9aSIngo Molnar  * the same lock-class:
107*cae2ed9aSIngo Molnar  */
108*cae2ed9aSIngo Molnar #define INIT_CLASS_FUNC(class) 				\
109*cae2ed9aSIngo Molnar static noinline void					\
110*cae2ed9aSIngo Molnar init_class_##class(spinlock_t *lock, rwlock_t *rwlock, struct mutex *mutex, \
111*cae2ed9aSIngo Molnar 		 struct rw_semaphore *rwsem)		\
112*cae2ed9aSIngo Molnar {							\
113*cae2ed9aSIngo Molnar 	spin_lock_init(lock);				\
114*cae2ed9aSIngo Molnar 	rwlock_init(rwlock);				\
115*cae2ed9aSIngo Molnar 	mutex_init(mutex);				\
116*cae2ed9aSIngo Molnar 	init_rwsem(rwsem);				\
117*cae2ed9aSIngo Molnar }
118*cae2ed9aSIngo Molnar 
119*cae2ed9aSIngo Molnar INIT_CLASS_FUNC(X)
120*cae2ed9aSIngo Molnar INIT_CLASS_FUNC(Y)
121*cae2ed9aSIngo Molnar INIT_CLASS_FUNC(Z)
122*cae2ed9aSIngo Molnar 
123*cae2ed9aSIngo Molnar static void init_shared_classes(void)
124*cae2ed9aSIngo Molnar {
125*cae2ed9aSIngo Molnar 	init_class_X(&lock_X1, &rwlock_X1, &mutex_X1, &rwsem_X1);
126*cae2ed9aSIngo Molnar 	init_class_X(&lock_X2, &rwlock_X2, &mutex_X2, &rwsem_X2);
127*cae2ed9aSIngo Molnar 
128*cae2ed9aSIngo Molnar 	init_class_Y(&lock_Y1, &rwlock_Y1, &mutex_Y1, &rwsem_Y1);
129*cae2ed9aSIngo Molnar 	init_class_Y(&lock_Y2, &rwlock_Y2, &mutex_Y2, &rwsem_Y2);
130*cae2ed9aSIngo Molnar 
131*cae2ed9aSIngo Molnar 	init_class_Z(&lock_Z1, &rwlock_Z1, &mutex_Z1, &rwsem_Z1);
132*cae2ed9aSIngo Molnar 	init_class_Z(&lock_Z2, &rwlock_Z2, &mutex_Z2, &rwsem_Z2);
133*cae2ed9aSIngo Molnar }
134*cae2ed9aSIngo Molnar 
135*cae2ed9aSIngo Molnar /*
136*cae2ed9aSIngo Molnar  * For spinlocks and rwlocks we also do hardirq-safe / softirq-safe tests.
137*cae2ed9aSIngo Molnar  * The following functions use a lock from a simulated hardirq/softirq
138*cae2ed9aSIngo Molnar  * context, causing the locks to be marked as hardirq-safe/softirq-safe:
139*cae2ed9aSIngo Molnar  */
140*cae2ed9aSIngo Molnar 
141*cae2ed9aSIngo Molnar #define HARDIRQ_DISABLE		local_irq_disable
142*cae2ed9aSIngo Molnar #define HARDIRQ_ENABLE		local_irq_enable
143*cae2ed9aSIngo Molnar 
144*cae2ed9aSIngo Molnar #define HARDIRQ_ENTER()				\
145*cae2ed9aSIngo Molnar 	local_irq_disable();			\
146*cae2ed9aSIngo Molnar 	irq_enter();				\
147*cae2ed9aSIngo Molnar 	WARN_ON(!in_irq());
148*cae2ed9aSIngo Molnar 
149*cae2ed9aSIngo Molnar #define HARDIRQ_EXIT()				\
150*cae2ed9aSIngo Molnar 	__irq_exit();				\
151*cae2ed9aSIngo Molnar 	local_irq_enable();
152*cae2ed9aSIngo Molnar 
153*cae2ed9aSIngo Molnar #define SOFTIRQ_DISABLE		local_bh_disable
154*cae2ed9aSIngo Molnar #define SOFTIRQ_ENABLE		local_bh_enable
155*cae2ed9aSIngo Molnar 
156*cae2ed9aSIngo Molnar #define SOFTIRQ_ENTER()				\
157*cae2ed9aSIngo Molnar 		local_bh_disable();		\
158*cae2ed9aSIngo Molnar 		local_irq_disable();		\
159*cae2ed9aSIngo Molnar 		trace_softirq_enter();		\
160*cae2ed9aSIngo Molnar 		WARN_ON(!in_softirq());
161*cae2ed9aSIngo Molnar 
162*cae2ed9aSIngo Molnar #define SOFTIRQ_EXIT()				\
163*cae2ed9aSIngo Molnar 		trace_softirq_exit();		\
164*cae2ed9aSIngo Molnar 		local_irq_enable();		\
165*cae2ed9aSIngo Molnar 		local_bh_enable();
166*cae2ed9aSIngo Molnar 
167*cae2ed9aSIngo Molnar /*
168*cae2ed9aSIngo Molnar  * Shortcuts for lock/unlock API variants, to keep
169*cae2ed9aSIngo Molnar  * the testcases compact:
170*cae2ed9aSIngo Molnar  */
171*cae2ed9aSIngo Molnar #define L(x)			spin_lock(&lock_##x)
172*cae2ed9aSIngo Molnar #define U(x)			spin_unlock(&lock_##x)
173*cae2ed9aSIngo Molnar #define LU(x)			L(x); U(x)
174*cae2ed9aSIngo Molnar #define SI(x)			spin_lock_init(&lock_##x)
175*cae2ed9aSIngo Molnar 
176*cae2ed9aSIngo Molnar #define WL(x)			write_lock(&rwlock_##x)
177*cae2ed9aSIngo Molnar #define WU(x)			write_unlock(&rwlock_##x)
178*cae2ed9aSIngo Molnar #define WLU(x)			WL(x); WU(x)
179*cae2ed9aSIngo Molnar 
180*cae2ed9aSIngo Molnar #define RL(x)			read_lock(&rwlock_##x)
181*cae2ed9aSIngo Molnar #define RU(x)			read_unlock(&rwlock_##x)
182*cae2ed9aSIngo Molnar #define RLU(x)			RL(x); RU(x)
183*cae2ed9aSIngo Molnar #define RWI(x)			rwlock_init(&rwlock_##x)
184*cae2ed9aSIngo Molnar 
185*cae2ed9aSIngo Molnar #define ML(x)			mutex_lock(&mutex_##x)
186*cae2ed9aSIngo Molnar #define MU(x)			mutex_unlock(&mutex_##x)
187*cae2ed9aSIngo Molnar #define MI(x)			mutex_init(&mutex_##x)
188*cae2ed9aSIngo Molnar 
189*cae2ed9aSIngo Molnar #define WSL(x)			down_write(&rwsem_##x)
190*cae2ed9aSIngo Molnar #define WSU(x)			up_write(&rwsem_##x)
191*cae2ed9aSIngo Molnar 
192*cae2ed9aSIngo Molnar #define RSL(x)			down_read(&rwsem_##x)
193*cae2ed9aSIngo Molnar #define RSU(x)			up_read(&rwsem_##x)
194*cae2ed9aSIngo Molnar #define RWSI(x)			init_rwsem(&rwsem_##x)
195*cae2ed9aSIngo Molnar 
196*cae2ed9aSIngo Molnar #define LOCK_UNLOCK_2(x,y)	LOCK(x); LOCK(y); UNLOCK(y); UNLOCK(x)
197*cae2ed9aSIngo Molnar 
198*cae2ed9aSIngo Molnar /*
199*cae2ed9aSIngo Molnar  * Generate different permutations of the same testcase, using
200*cae2ed9aSIngo Molnar  * the same basic lock-dependency/state events:
201*cae2ed9aSIngo Molnar  */
202*cae2ed9aSIngo Molnar 
203*cae2ed9aSIngo Molnar #define GENERATE_TESTCASE(name)			\
204*cae2ed9aSIngo Molnar 						\
205*cae2ed9aSIngo Molnar static void name(void) { E(); }
206*cae2ed9aSIngo Molnar 
207*cae2ed9aSIngo Molnar #define GENERATE_PERMUTATIONS_2_EVENTS(name)	\
208*cae2ed9aSIngo Molnar 						\
209*cae2ed9aSIngo Molnar static void name##_12(void) { E1(); E2(); }	\
210*cae2ed9aSIngo Molnar static void name##_21(void) { E2(); E1(); }
211*cae2ed9aSIngo Molnar 
212*cae2ed9aSIngo Molnar #define GENERATE_PERMUTATIONS_3_EVENTS(name)		\
213*cae2ed9aSIngo Molnar 							\
214*cae2ed9aSIngo Molnar static void name##_123(void) { E1(); E2(); E3(); }	\
215*cae2ed9aSIngo Molnar static void name##_132(void) { E1(); E3(); E2(); }	\
216*cae2ed9aSIngo Molnar static void name##_213(void) { E2(); E1(); E3(); }	\
217*cae2ed9aSIngo Molnar static void name##_231(void) { E2(); E3(); E1(); }	\
218*cae2ed9aSIngo Molnar static void name##_312(void) { E3(); E1(); E2(); }	\
219*cae2ed9aSIngo Molnar static void name##_321(void) { E3(); E2(); E1(); }
220*cae2ed9aSIngo Molnar 
221*cae2ed9aSIngo Molnar /*
222*cae2ed9aSIngo Molnar  * AA deadlock:
223*cae2ed9aSIngo Molnar  */
224*cae2ed9aSIngo Molnar 
225*cae2ed9aSIngo Molnar #define E()					\
226*cae2ed9aSIngo Molnar 						\
227*cae2ed9aSIngo Molnar 	LOCK(X1);				\
228*cae2ed9aSIngo Molnar 	LOCK(X2); /* this one should fail */
229*cae2ed9aSIngo Molnar 
230*cae2ed9aSIngo Molnar /*
231*cae2ed9aSIngo Molnar  * 6 testcases:
232*cae2ed9aSIngo Molnar  */
233*cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
234*cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_spin)
235*cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
236*cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_wlock)
237*cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
238*cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_rlock)
239*cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
240*cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_mutex)
241*cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
242*cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_wsem)
243*cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
244*cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_rsem)
245*cae2ed9aSIngo Molnar 
246*cae2ed9aSIngo Molnar #undef E
247*cae2ed9aSIngo Molnar 
248*cae2ed9aSIngo Molnar /*
249*cae2ed9aSIngo Molnar  * Special-case for read-locking, they are
250*cae2ed9aSIngo Molnar  * allowed to recurse on the same lock instance:
251*cae2ed9aSIngo Molnar  */
252*cae2ed9aSIngo Molnar static void rlock_AA1(void)
253*cae2ed9aSIngo Molnar {
254*cae2ed9aSIngo Molnar 	RL(X1);
255*cae2ed9aSIngo Molnar 	RL(X1); // this one should NOT fail
256*cae2ed9aSIngo Molnar }
257*cae2ed9aSIngo Molnar 
258*cae2ed9aSIngo Molnar static void rlock_AA1B(void)
259*cae2ed9aSIngo Molnar {
260*cae2ed9aSIngo Molnar 	RL(X1);
261*cae2ed9aSIngo Molnar 	RL(X2); // this one should fail
262*cae2ed9aSIngo Molnar }
263*cae2ed9aSIngo Molnar 
264*cae2ed9aSIngo Molnar static void rsem_AA1(void)
265*cae2ed9aSIngo Molnar {
266*cae2ed9aSIngo Molnar 	RSL(X1);
267*cae2ed9aSIngo Molnar 	RSL(X1); // this one should fail
268*cae2ed9aSIngo Molnar }
269*cae2ed9aSIngo Molnar 
270*cae2ed9aSIngo Molnar static void rsem_AA1B(void)
271*cae2ed9aSIngo Molnar {
272*cae2ed9aSIngo Molnar 	RSL(X1);
273*cae2ed9aSIngo Molnar 	RSL(X2); // this one should fail
274*cae2ed9aSIngo Molnar }
275*cae2ed9aSIngo Molnar /*
276*cae2ed9aSIngo Molnar  * The mixing of read and write locks is not allowed:
277*cae2ed9aSIngo Molnar  */
278*cae2ed9aSIngo Molnar static void rlock_AA2(void)
279*cae2ed9aSIngo Molnar {
280*cae2ed9aSIngo Molnar 	RL(X1);
281*cae2ed9aSIngo Molnar 	WL(X2); // this one should fail
282*cae2ed9aSIngo Molnar }
283*cae2ed9aSIngo Molnar 
284*cae2ed9aSIngo Molnar static void rsem_AA2(void)
285*cae2ed9aSIngo Molnar {
286*cae2ed9aSIngo Molnar 	RSL(X1);
287*cae2ed9aSIngo Molnar 	WSL(X2); // this one should fail
288*cae2ed9aSIngo Molnar }
289*cae2ed9aSIngo Molnar 
290*cae2ed9aSIngo Molnar static void rlock_AA3(void)
291*cae2ed9aSIngo Molnar {
292*cae2ed9aSIngo Molnar 	WL(X1);
293*cae2ed9aSIngo Molnar 	RL(X2); // this one should fail
294*cae2ed9aSIngo Molnar }
295*cae2ed9aSIngo Molnar 
296*cae2ed9aSIngo Molnar static void rsem_AA3(void)
297*cae2ed9aSIngo Molnar {
298*cae2ed9aSIngo Molnar 	WSL(X1);
299*cae2ed9aSIngo Molnar 	RSL(X2); // this one should fail
300*cae2ed9aSIngo Molnar }
301*cae2ed9aSIngo Molnar 
302*cae2ed9aSIngo Molnar /*
303*cae2ed9aSIngo Molnar  * ABBA deadlock:
304*cae2ed9aSIngo Molnar  */
305*cae2ed9aSIngo Molnar 
306*cae2ed9aSIngo Molnar #define E()					\
307*cae2ed9aSIngo Molnar 						\
308*cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
309*cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, A); /* fail */
310*cae2ed9aSIngo Molnar 
311*cae2ed9aSIngo Molnar /*
312*cae2ed9aSIngo Molnar  * 6 testcases:
313*cae2ed9aSIngo Molnar  */
314*cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
315*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_spin)
316*cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
317*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_wlock)
318*cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
319*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_rlock)
320*cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
321*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_mutex)
322*cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
323*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_wsem)
324*cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
325*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_rsem)
326*cae2ed9aSIngo Molnar 
327*cae2ed9aSIngo Molnar #undef E
328*cae2ed9aSIngo Molnar 
329*cae2ed9aSIngo Molnar /*
330*cae2ed9aSIngo Molnar  * AB BC CA deadlock:
331*cae2ed9aSIngo Molnar  */
332*cae2ed9aSIngo Molnar 
333*cae2ed9aSIngo Molnar #define E()					\
334*cae2ed9aSIngo Molnar 						\
335*cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
336*cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, C);			\
337*cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, A); /* fail */
338*cae2ed9aSIngo Molnar 
339*cae2ed9aSIngo Molnar /*
340*cae2ed9aSIngo Molnar  * 6 testcases:
341*cae2ed9aSIngo Molnar  */
342*cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
343*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_spin)
344*cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
345*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_wlock)
346*cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
347*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_rlock)
348*cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
349*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_mutex)
350*cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
351*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_wsem)
352*cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
353*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_rsem)
354*cae2ed9aSIngo Molnar 
355*cae2ed9aSIngo Molnar #undef E
356*cae2ed9aSIngo Molnar 
357*cae2ed9aSIngo Molnar /*
358*cae2ed9aSIngo Molnar  * AB CA BC deadlock:
359*cae2ed9aSIngo Molnar  */
360*cae2ed9aSIngo Molnar 
361*cae2ed9aSIngo Molnar #define E()					\
362*cae2ed9aSIngo Molnar 						\
363*cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
364*cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, A);			\
365*cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, C); /* fail */
366*cae2ed9aSIngo Molnar 
367*cae2ed9aSIngo Molnar /*
368*cae2ed9aSIngo Molnar  * 6 testcases:
369*cae2ed9aSIngo Molnar  */
370*cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
371*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_spin)
372*cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
373*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_wlock)
374*cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
375*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_rlock)
376*cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
377*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_mutex)
378*cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
379*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_wsem)
380*cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
381*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_rsem)
382*cae2ed9aSIngo Molnar 
383*cae2ed9aSIngo Molnar #undef E
384*cae2ed9aSIngo Molnar 
385*cae2ed9aSIngo Molnar /*
386*cae2ed9aSIngo Molnar  * AB BC CD DA deadlock:
387*cae2ed9aSIngo Molnar  */
388*cae2ed9aSIngo Molnar 
389*cae2ed9aSIngo Molnar #define E()					\
390*cae2ed9aSIngo Molnar 						\
391*cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
392*cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, C);			\
393*cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, D);			\
394*cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(D, A); /* fail */
395*cae2ed9aSIngo Molnar 
396*cae2ed9aSIngo Molnar /*
397*cae2ed9aSIngo Molnar  * 6 testcases:
398*cae2ed9aSIngo Molnar  */
399*cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
400*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_spin)
401*cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
402*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_wlock)
403*cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
404*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_rlock)
405*cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
406*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_mutex)
407*cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
408*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_wsem)
409*cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
410*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_rsem)
411*cae2ed9aSIngo Molnar 
412*cae2ed9aSIngo Molnar #undef E
413*cae2ed9aSIngo Molnar 
414*cae2ed9aSIngo Molnar /*
415*cae2ed9aSIngo Molnar  * AB CD BD DA deadlock:
416*cae2ed9aSIngo Molnar  */
417*cae2ed9aSIngo Molnar #define E()					\
418*cae2ed9aSIngo Molnar 						\
419*cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
420*cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, D);			\
421*cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, D);			\
422*cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(D, A); /* fail */
423*cae2ed9aSIngo Molnar 
424*cae2ed9aSIngo Molnar /*
425*cae2ed9aSIngo Molnar  * 6 testcases:
426*cae2ed9aSIngo Molnar  */
427*cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
428*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_spin)
429*cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
430*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_wlock)
431*cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
432*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_rlock)
433*cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
434*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_mutex)
435*cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
436*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_wsem)
437*cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
438*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_rsem)
439*cae2ed9aSIngo Molnar 
440*cae2ed9aSIngo Molnar #undef E
441*cae2ed9aSIngo Molnar 
442*cae2ed9aSIngo Molnar /*
443*cae2ed9aSIngo Molnar  * AB CD BC DA deadlock:
444*cae2ed9aSIngo Molnar  */
445*cae2ed9aSIngo Molnar #define E()					\
446*cae2ed9aSIngo Molnar 						\
447*cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
448*cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, D);			\
449*cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, C);			\
450*cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(D, A); /* fail */
451*cae2ed9aSIngo Molnar 
452*cae2ed9aSIngo Molnar /*
453*cae2ed9aSIngo Molnar  * 6 testcases:
454*cae2ed9aSIngo Molnar  */
455*cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
456*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_spin)
457*cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
458*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_wlock)
459*cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
460*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_rlock)
461*cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
462*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_mutex)
463*cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
464*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_wsem)
465*cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
466*cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_rsem)
467*cae2ed9aSIngo Molnar 
468*cae2ed9aSIngo Molnar #undef E
469*cae2ed9aSIngo Molnar 
470*cae2ed9aSIngo Molnar /*
471*cae2ed9aSIngo Molnar  * Double unlock:
472*cae2ed9aSIngo Molnar  */
473*cae2ed9aSIngo Molnar #define E()					\
474*cae2ed9aSIngo Molnar 						\
475*cae2ed9aSIngo Molnar 	LOCK(A);				\
476*cae2ed9aSIngo Molnar 	UNLOCK(A);				\
477*cae2ed9aSIngo Molnar 	UNLOCK(A); /* fail */
478*cae2ed9aSIngo Molnar 
479*cae2ed9aSIngo Molnar /*
480*cae2ed9aSIngo Molnar  * 6 testcases:
481*cae2ed9aSIngo Molnar  */
482*cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
483*cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_spin)
484*cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
485*cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_wlock)
486*cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
487*cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_rlock)
488*cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
489*cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_mutex)
490*cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
491*cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_wsem)
492*cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
493*cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_rsem)
494*cae2ed9aSIngo Molnar 
495*cae2ed9aSIngo Molnar #undef E
496*cae2ed9aSIngo Molnar 
497*cae2ed9aSIngo Molnar /*
498*cae2ed9aSIngo Molnar  * Bad unlock ordering:
499*cae2ed9aSIngo Molnar  */
500*cae2ed9aSIngo Molnar #define E()					\
501*cae2ed9aSIngo Molnar 						\
502*cae2ed9aSIngo Molnar 	LOCK(A);				\
503*cae2ed9aSIngo Molnar 	LOCK(B);				\
504*cae2ed9aSIngo Molnar 	UNLOCK(A); /* fail */			\
505*cae2ed9aSIngo Molnar 	UNLOCK(B);
506*cae2ed9aSIngo Molnar 
507*cae2ed9aSIngo Molnar /*
508*cae2ed9aSIngo Molnar  * 6 testcases:
509*cae2ed9aSIngo Molnar  */
510*cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
511*cae2ed9aSIngo Molnar GENERATE_TESTCASE(bad_unlock_order_spin)
512*cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
513*cae2ed9aSIngo Molnar GENERATE_TESTCASE(bad_unlock_order_wlock)
514*cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
515*cae2ed9aSIngo Molnar GENERATE_TESTCASE(bad_unlock_order_rlock)
516*cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
517*cae2ed9aSIngo Molnar GENERATE_TESTCASE(bad_unlock_order_mutex)
518*cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
519*cae2ed9aSIngo Molnar GENERATE_TESTCASE(bad_unlock_order_wsem)
520*cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
521*cae2ed9aSIngo Molnar GENERATE_TESTCASE(bad_unlock_order_rsem)
522*cae2ed9aSIngo Molnar 
523*cae2ed9aSIngo Molnar #undef E
524*cae2ed9aSIngo Molnar 
525*cae2ed9aSIngo Molnar /*
526*cae2ed9aSIngo Molnar  * initializing a held lock:
527*cae2ed9aSIngo Molnar  */
528*cae2ed9aSIngo Molnar #define E()					\
529*cae2ed9aSIngo Molnar 						\
530*cae2ed9aSIngo Molnar 	LOCK(A);				\
531*cae2ed9aSIngo Molnar 	INIT(A); /* fail */
532*cae2ed9aSIngo Molnar 
533*cae2ed9aSIngo Molnar /*
534*cae2ed9aSIngo Molnar  * 6 testcases:
535*cae2ed9aSIngo Molnar  */
536*cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
537*cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_spin)
538*cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
539*cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_wlock)
540*cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
541*cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_rlock)
542*cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
543*cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_mutex)
544*cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
545*cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_wsem)
546*cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
547*cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_rsem)
548*cae2ed9aSIngo Molnar 
549*cae2ed9aSIngo Molnar #undef E
550*cae2ed9aSIngo Molnar 
551*cae2ed9aSIngo Molnar /*
552*cae2ed9aSIngo Molnar  * locking an irq-safe lock with irqs enabled:
553*cae2ed9aSIngo Molnar  */
554*cae2ed9aSIngo Molnar #define E1()				\
555*cae2ed9aSIngo Molnar 					\
556*cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
557*cae2ed9aSIngo Molnar 	LOCK(A);			\
558*cae2ed9aSIngo Molnar 	UNLOCK(A);			\
559*cae2ed9aSIngo Molnar 	IRQ_EXIT();
560*cae2ed9aSIngo Molnar 
561*cae2ed9aSIngo Molnar #define E2()				\
562*cae2ed9aSIngo Molnar 					\
563*cae2ed9aSIngo Molnar 	LOCK(A);			\
564*cae2ed9aSIngo Molnar 	UNLOCK(A);
565*cae2ed9aSIngo Molnar 
566*cae2ed9aSIngo Molnar /*
567*cae2ed9aSIngo Molnar  * Generate 24 testcases:
568*cae2ed9aSIngo Molnar  */
569*cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
570*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_spin)
571*cae2ed9aSIngo Molnar 
572*cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
573*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_rlock)
574*cae2ed9aSIngo Molnar 
575*cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
576*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_wlock)
577*cae2ed9aSIngo Molnar 
578*cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
579*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_spin)
580*cae2ed9aSIngo Molnar 
581*cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
582*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_rlock)
583*cae2ed9aSIngo Molnar 
584*cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
585*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_wlock)
586*cae2ed9aSIngo Molnar 
587*cae2ed9aSIngo Molnar #undef E1
588*cae2ed9aSIngo Molnar #undef E2
589*cae2ed9aSIngo Molnar 
590*cae2ed9aSIngo Molnar /*
591*cae2ed9aSIngo Molnar  * Enabling hardirqs with a softirq-safe lock held:
592*cae2ed9aSIngo Molnar  */
593*cae2ed9aSIngo Molnar #define E1()				\
594*cae2ed9aSIngo Molnar 					\
595*cae2ed9aSIngo Molnar 	SOFTIRQ_ENTER();		\
596*cae2ed9aSIngo Molnar 	LOCK(A);			\
597*cae2ed9aSIngo Molnar 	UNLOCK(A);			\
598*cae2ed9aSIngo Molnar 	SOFTIRQ_EXIT();
599*cae2ed9aSIngo Molnar 
600*cae2ed9aSIngo Molnar #define E2()				\
601*cae2ed9aSIngo Molnar 					\
602*cae2ed9aSIngo Molnar 	HARDIRQ_DISABLE();		\
603*cae2ed9aSIngo Molnar 	LOCK(A);			\
604*cae2ed9aSIngo Molnar 	HARDIRQ_ENABLE();		\
605*cae2ed9aSIngo Molnar 	UNLOCK(A);
606*cae2ed9aSIngo Molnar 
607*cae2ed9aSIngo Molnar /*
608*cae2ed9aSIngo Molnar  * Generate 12 testcases:
609*cae2ed9aSIngo Molnar  */
610*cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
611*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_spin)
612*cae2ed9aSIngo Molnar 
613*cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
614*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_wlock)
615*cae2ed9aSIngo Molnar 
616*cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
617*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_rlock)
618*cae2ed9aSIngo Molnar 
619*cae2ed9aSIngo Molnar #undef E1
620*cae2ed9aSIngo Molnar #undef E2
621*cae2ed9aSIngo Molnar 
622*cae2ed9aSIngo Molnar /*
623*cae2ed9aSIngo Molnar  * Enabling irqs with an irq-safe lock held:
624*cae2ed9aSIngo Molnar  */
625*cae2ed9aSIngo Molnar #define E1()				\
626*cae2ed9aSIngo Molnar 					\
627*cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
628*cae2ed9aSIngo Molnar 	LOCK(A);			\
629*cae2ed9aSIngo Molnar 	UNLOCK(A);			\
630*cae2ed9aSIngo Molnar 	IRQ_EXIT();
631*cae2ed9aSIngo Molnar 
632*cae2ed9aSIngo Molnar #define E2()				\
633*cae2ed9aSIngo Molnar 					\
634*cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
635*cae2ed9aSIngo Molnar 	LOCK(A);			\
636*cae2ed9aSIngo Molnar 	IRQ_ENABLE();			\
637*cae2ed9aSIngo Molnar 	UNLOCK(A);
638*cae2ed9aSIngo Molnar 
639*cae2ed9aSIngo Molnar /*
640*cae2ed9aSIngo Molnar  * Generate 24 testcases:
641*cae2ed9aSIngo Molnar  */
642*cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
643*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_spin)
644*cae2ed9aSIngo Molnar 
645*cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
646*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_rlock)
647*cae2ed9aSIngo Molnar 
648*cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
649*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_wlock)
650*cae2ed9aSIngo Molnar 
651*cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
652*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_spin)
653*cae2ed9aSIngo Molnar 
654*cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
655*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_rlock)
656*cae2ed9aSIngo Molnar 
657*cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
658*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock)
659*cae2ed9aSIngo Molnar 
660*cae2ed9aSIngo Molnar #undef E1
661*cae2ed9aSIngo Molnar #undef E2
662*cae2ed9aSIngo Molnar 
663*cae2ed9aSIngo Molnar /*
664*cae2ed9aSIngo Molnar  * Acquiring a irq-unsafe lock while holding an irq-safe-lock:
665*cae2ed9aSIngo Molnar  */
666*cae2ed9aSIngo Molnar #define E1()				\
667*cae2ed9aSIngo Molnar 					\
668*cae2ed9aSIngo Molnar 	LOCK(A);			\
669*cae2ed9aSIngo Molnar 	LOCK(B);			\
670*cae2ed9aSIngo Molnar 	UNLOCK(B);			\
671*cae2ed9aSIngo Molnar 	UNLOCK(A);			\
672*cae2ed9aSIngo Molnar 
673*cae2ed9aSIngo Molnar #define E2()				\
674*cae2ed9aSIngo Molnar 					\
675*cae2ed9aSIngo Molnar 	LOCK(B);			\
676*cae2ed9aSIngo Molnar 	UNLOCK(B);
677*cae2ed9aSIngo Molnar 
678*cae2ed9aSIngo Molnar #define E3()				\
679*cae2ed9aSIngo Molnar 					\
680*cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
681*cae2ed9aSIngo Molnar 	LOCK(A);			\
682*cae2ed9aSIngo Molnar 	UNLOCK(A);			\
683*cae2ed9aSIngo Molnar 	IRQ_EXIT();
684*cae2ed9aSIngo Molnar 
685*cae2ed9aSIngo Molnar /*
686*cae2ed9aSIngo Molnar  * Generate 36 testcases:
687*cae2ed9aSIngo Molnar  */
688*cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
689*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_spin)
690*cae2ed9aSIngo Molnar 
691*cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
692*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_rlock)
693*cae2ed9aSIngo Molnar 
694*cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
695*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_wlock)
696*cae2ed9aSIngo Molnar 
697*cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
698*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_spin)
699*cae2ed9aSIngo Molnar 
700*cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
701*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_rlock)
702*cae2ed9aSIngo Molnar 
703*cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
704*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock)
705*cae2ed9aSIngo Molnar 
706*cae2ed9aSIngo Molnar #undef E1
707*cae2ed9aSIngo Molnar #undef E2
708*cae2ed9aSIngo Molnar #undef E3
709*cae2ed9aSIngo Molnar 
710*cae2ed9aSIngo Molnar /*
711*cae2ed9aSIngo Molnar  * If a lock turns into softirq-safe, but earlier it took
712*cae2ed9aSIngo Molnar  * a softirq-unsafe lock:
713*cae2ed9aSIngo Molnar  */
714*cae2ed9aSIngo Molnar 
715*cae2ed9aSIngo Molnar #define E1()				\
716*cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
717*cae2ed9aSIngo Molnar 	LOCK(A);			\
718*cae2ed9aSIngo Molnar 	LOCK(B);			\
719*cae2ed9aSIngo Molnar 	UNLOCK(B);			\
720*cae2ed9aSIngo Molnar 	UNLOCK(A);			\
721*cae2ed9aSIngo Molnar 	IRQ_ENABLE();
722*cae2ed9aSIngo Molnar 
723*cae2ed9aSIngo Molnar #define E2()				\
724*cae2ed9aSIngo Molnar 	LOCK(B);			\
725*cae2ed9aSIngo Molnar 	UNLOCK(B);
726*cae2ed9aSIngo Molnar 
727*cae2ed9aSIngo Molnar #define E3()				\
728*cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
729*cae2ed9aSIngo Molnar 	LOCK(A);			\
730*cae2ed9aSIngo Molnar 	UNLOCK(A);			\
731*cae2ed9aSIngo Molnar 	IRQ_EXIT();
732*cae2ed9aSIngo Molnar 
733*cae2ed9aSIngo Molnar /*
734*cae2ed9aSIngo Molnar  * Generate 36 testcases:
735*cae2ed9aSIngo Molnar  */
736*cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
737*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_spin)
738*cae2ed9aSIngo Molnar 
739*cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
740*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_rlock)
741*cae2ed9aSIngo Molnar 
742*cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
743*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_wlock)
744*cae2ed9aSIngo Molnar 
745*cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
746*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_spin)
747*cae2ed9aSIngo Molnar 
748*cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
749*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_rlock)
750*cae2ed9aSIngo Molnar 
751*cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
752*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_wlock)
753*cae2ed9aSIngo Molnar 
754*cae2ed9aSIngo Molnar #undef E1
755*cae2ed9aSIngo Molnar #undef E2
756*cae2ed9aSIngo Molnar #undef E3
757*cae2ed9aSIngo Molnar 
758*cae2ed9aSIngo Molnar /*
759*cae2ed9aSIngo Molnar  * read-lock / write-lock irq inversion.
760*cae2ed9aSIngo Molnar  *
761*cae2ed9aSIngo Molnar  * Deadlock scenario:
762*cae2ed9aSIngo Molnar  *
763*cae2ed9aSIngo Molnar  * CPU#1 is at #1, i.e. it has write-locked A, but has not
764*cae2ed9aSIngo Molnar  * taken B yet.
765*cae2ed9aSIngo Molnar  *
766*cae2ed9aSIngo Molnar  * CPU#2 is at #2, i.e. it has locked B.
767*cae2ed9aSIngo Molnar  *
768*cae2ed9aSIngo Molnar  * Hardirq hits CPU#2 at point #2 and is trying to read-lock A.
769*cae2ed9aSIngo Molnar  *
770*cae2ed9aSIngo Molnar  * The deadlock occurs because CPU#1 will spin on B, and CPU#2
771*cae2ed9aSIngo Molnar  * will spin on A.
772*cae2ed9aSIngo Molnar  */
773*cae2ed9aSIngo Molnar 
774*cae2ed9aSIngo Molnar #define E1()				\
775*cae2ed9aSIngo Molnar 					\
776*cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
777*cae2ed9aSIngo Molnar 	WL(A);				\
778*cae2ed9aSIngo Molnar 	LOCK(B);			\
779*cae2ed9aSIngo Molnar 	UNLOCK(B);			\
780*cae2ed9aSIngo Molnar 	WU(A);				\
781*cae2ed9aSIngo Molnar 	IRQ_ENABLE();
782*cae2ed9aSIngo Molnar 
783*cae2ed9aSIngo Molnar #define E2()				\
784*cae2ed9aSIngo Molnar 					\
785*cae2ed9aSIngo Molnar 	LOCK(B);			\
786*cae2ed9aSIngo Molnar 	UNLOCK(B);
787*cae2ed9aSIngo Molnar 
788*cae2ed9aSIngo Molnar #define E3()				\
789*cae2ed9aSIngo Molnar 					\
790*cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
791*cae2ed9aSIngo Molnar 	RL(A);				\
792*cae2ed9aSIngo Molnar 	RU(A);				\
793*cae2ed9aSIngo Molnar 	IRQ_EXIT();
794*cae2ed9aSIngo Molnar 
795*cae2ed9aSIngo Molnar /*
796*cae2ed9aSIngo Molnar  * Generate 36 testcases:
797*cae2ed9aSIngo Molnar  */
798*cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
799*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_spin)
800*cae2ed9aSIngo Molnar 
801*cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
802*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_rlock)
803*cae2ed9aSIngo Molnar 
804*cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
805*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_wlock)
806*cae2ed9aSIngo Molnar 
807*cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
808*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_spin)
809*cae2ed9aSIngo Molnar 
810*cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
811*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_rlock)
812*cae2ed9aSIngo Molnar 
813*cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
814*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_wlock)
815*cae2ed9aSIngo Molnar 
816*cae2ed9aSIngo Molnar #undef E1
817*cae2ed9aSIngo Molnar #undef E2
818*cae2ed9aSIngo Molnar #undef E3
819*cae2ed9aSIngo Molnar 
820*cae2ed9aSIngo Molnar /*
821*cae2ed9aSIngo Molnar  * read-lock / write-lock recursion that is actually safe.
822*cae2ed9aSIngo Molnar  */
823*cae2ed9aSIngo Molnar 
824*cae2ed9aSIngo Molnar #define E1()				\
825*cae2ed9aSIngo Molnar 					\
826*cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
827*cae2ed9aSIngo Molnar 	WL(A);				\
828*cae2ed9aSIngo Molnar 	WU(A);				\
829*cae2ed9aSIngo Molnar 	IRQ_ENABLE();
830*cae2ed9aSIngo Molnar 
831*cae2ed9aSIngo Molnar #define E2()				\
832*cae2ed9aSIngo Molnar 					\
833*cae2ed9aSIngo Molnar 	RL(A);				\
834*cae2ed9aSIngo Molnar 	RU(A);				\
835*cae2ed9aSIngo Molnar 
836*cae2ed9aSIngo Molnar #define E3()				\
837*cae2ed9aSIngo Molnar 					\
838*cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
839*cae2ed9aSIngo Molnar 	RL(A);				\
840*cae2ed9aSIngo Molnar 	L(B);				\
841*cae2ed9aSIngo Molnar 	U(B);				\
842*cae2ed9aSIngo Molnar 	RU(A);				\
843*cae2ed9aSIngo Molnar 	IRQ_EXIT();
844*cae2ed9aSIngo Molnar 
845*cae2ed9aSIngo Molnar /*
846*cae2ed9aSIngo Molnar  * Generate 12 testcases:
847*cae2ed9aSIngo Molnar  */
848*cae2ed9aSIngo Molnar #include "locking-selftest-hardirq.h"
849*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard)
850*cae2ed9aSIngo Molnar 
851*cae2ed9aSIngo Molnar #include "locking-selftest-softirq.h"
852*cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft)
853*cae2ed9aSIngo Molnar 
854*cae2ed9aSIngo Molnar #undef E1
855*cae2ed9aSIngo Molnar #undef E2
856*cae2ed9aSIngo Molnar #undef E3
857*cae2ed9aSIngo Molnar 
858*cae2ed9aSIngo Molnar /*
859*cae2ed9aSIngo Molnar  * read-lock / write-lock recursion that is unsafe.
860*cae2ed9aSIngo Molnar  */
861*cae2ed9aSIngo Molnar 
862*cae2ed9aSIngo Molnar #define E1()				\
863*cae2ed9aSIngo Molnar 					\
864*cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
865*cae2ed9aSIngo Molnar 	L(B);				\
866*cae2ed9aSIngo Molnar 	WL(A);				\
867*cae2ed9aSIngo Molnar 	WU(A);				\
868*cae2ed9aSIngo Molnar 	U(B);				\
869*cae2ed9aSIngo Molnar 	IRQ_ENABLE();
870*cae2ed9aSIngo Molnar 
871*cae2ed9aSIngo Molnar #define E2()				\
872*cae2ed9aSIngo Molnar 					\
873*cae2ed9aSIngo Molnar 	RL(A);				\
874*cae2ed9aSIngo Molnar 	RU(A);				\
875*cae2ed9aSIngo Molnar 
876*cae2ed9aSIngo Molnar #define E3()				\
877*cae2ed9aSIngo Molnar 					\
878*cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
879*cae2ed9aSIngo Molnar 	L(B);				\
880*cae2ed9aSIngo Molnar 	U(B);				\
881*cae2ed9aSIngo Molnar 	IRQ_EXIT();
882*cae2ed9aSIngo Molnar 
883*cae2ed9aSIngo Molnar /*
884*cae2ed9aSIngo Molnar  * Generate 12 testcases:
885*cae2ed9aSIngo Molnar  */
886*cae2ed9aSIngo Molnar #include "locking-selftest-hardirq.h"
887*cae2ed9aSIngo Molnar // GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard)
888*cae2ed9aSIngo Molnar 
889*cae2ed9aSIngo Molnar #include "locking-selftest-softirq.h"
890*cae2ed9aSIngo Molnar // GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft)
891*cae2ed9aSIngo Molnar 
892*cae2ed9aSIngo Molnar #define lockdep_reset()
893*cae2ed9aSIngo Molnar #define lockdep_reset_lock(x)
894*cae2ed9aSIngo Molnar 
895*cae2ed9aSIngo Molnar #ifdef CONFIG_DEBUG_LOCK_ALLOC
896*cae2ed9aSIngo Molnar # define I_SPINLOCK(x)	lockdep_reset_lock(&lock_##x.dep_map)
897*cae2ed9aSIngo Molnar # define I_RWLOCK(x)	lockdep_reset_lock(&rwlock_##x.dep_map)
898*cae2ed9aSIngo Molnar # define I_MUTEX(x)	lockdep_reset_lock(&mutex_##x.dep_map)
899*cae2ed9aSIngo Molnar # define I_RWSEM(x)	lockdep_reset_lock(&rwsem_##x.dep_map)
900*cae2ed9aSIngo Molnar #else
901*cae2ed9aSIngo Molnar # define I_SPINLOCK(x)
902*cae2ed9aSIngo Molnar # define I_RWLOCK(x)
903*cae2ed9aSIngo Molnar # define I_MUTEX(x)
904*cae2ed9aSIngo Molnar # define I_RWSEM(x)
905*cae2ed9aSIngo Molnar #endif
906*cae2ed9aSIngo Molnar 
907*cae2ed9aSIngo Molnar #define I1(x)					\
908*cae2ed9aSIngo Molnar 	do {					\
909*cae2ed9aSIngo Molnar 		I_SPINLOCK(x);			\
910*cae2ed9aSIngo Molnar 		I_RWLOCK(x);			\
911*cae2ed9aSIngo Molnar 		I_MUTEX(x);			\
912*cae2ed9aSIngo Molnar 		I_RWSEM(x);			\
913*cae2ed9aSIngo Molnar 	} while (0)
914*cae2ed9aSIngo Molnar 
915*cae2ed9aSIngo Molnar #define I2(x)					\
916*cae2ed9aSIngo Molnar 	do {					\
917*cae2ed9aSIngo Molnar 		spin_lock_init(&lock_##x);	\
918*cae2ed9aSIngo Molnar 		rwlock_init(&rwlock_##x);	\
919*cae2ed9aSIngo Molnar 		mutex_init(&mutex_##x);		\
920*cae2ed9aSIngo Molnar 		init_rwsem(&rwsem_##x);		\
921*cae2ed9aSIngo Molnar 	} while (0)
922*cae2ed9aSIngo Molnar 
923*cae2ed9aSIngo Molnar static void reset_locks(void)
924*cae2ed9aSIngo Molnar {
925*cae2ed9aSIngo Molnar 	local_irq_disable();
926*cae2ed9aSIngo Molnar 	I1(A); I1(B); I1(C); I1(D);
927*cae2ed9aSIngo Molnar 	I1(X1); I1(X2); I1(Y1); I1(Y2); I1(Z1); I1(Z2);
928*cae2ed9aSIngo Molnar 	lockdep_reset();
929*cae2ed9aSIngo Molnar 	I2(A); I2(B); I2(C); I2(D);
930*cae2ed9aSIngo Molnar 	init_shared_classes();
931*cae2ed9aSIngo Molnar 	local_irq_enable();
932*cae2ed9aSIngo Molnar }
933*cae2ed9aSIngo Molnar 
934*cae2ed9aSIngo Molnar #undef I
935*cae2ed9aSIngo Molnar 
936*cae2ed9aSIngo Molnar static int testcase_total;
937*cae2ed9aSIngo Molnar static int testcase_successes;
938*cae2ed9aSIngo Molnar static int expected_testcase_failures;
939*cae2ed9aSIngo Molnar static int unexpected_testcase_failures;
940*cae2ed9aSIngo Molnar 
941*cae2ed9aSIngo Molnar static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask)
942*cae2ed9aSIngo Molnar {
943*cae2ed9aSIngo Molnar 	unsigned long saved_preempt_count = preempt_count();
944*cae2ed9aSIngo Molnar 	int expected_failure = 0;
945*cae2ed9aSIngo Molnar 
946*cae2ed9aSIngo Molnar 	WARN_ON(irqs_disabled());
947*cae2ed9aSIngo Molnar 
948*cae2ed9aSIngo Molnar 	testcase_fn();
949*cae2ed9aSIngo Molnar 	/*
950*cae2ed9aSIngo Molnar 	 * Filter out expected failures:
951*cae2ed9aSIngo Molnar 	 */
952*cae2ed9aSIngo Molnar #ifndef CONFIG_PROVE_LOCKING
953*cae2ed9aSIngo Molnar 	if ((lockclass_mask & LOCKTYPE_SPIN) && debug_locks != expected)
954*cae2ed9aSIngo Molnar 		expected_failure = 1;
955*cae2ed9aSIngo Molnar 	if ((lockclass_mask & LOCKTYPE_RWLOCK) && debug_locks != expected)
956*cae2ed9aSIngo Molnar 		expected_failure = 1;
957*cae2ed9aSIngo Molnar 	if ((lockclass_mask & LOCKTYPE_MUTEX) && debug_locks != expected)
958*cae2ed9aSIngo Molnar 		expected_failure = 1;
959*cae2ed9aSIngo Molnar 	if ((lockclass_mask & LOCKTYPE_RWSEM) && debug_locks != expected)
960*cae2ed9aSIngo Molnar 		expected_failure = 1;
961*cae2ed9aSIngo Molnar #endif
962*cae2ed9aSIngo Molnar 	if (debug_locks != expected) {
963*cae2ed9aSIngo Molnar 		if (expected_failure) {
964*cae2ed9aSIngo Molnar 			expected_testcase_failures++;
965*cae2ed9aSIngo Molnar 			printk("failed|");
966*cae2ed9aSIngo Molnar 		} else {
967*cae2ed9aSIngo Molnar 			unexpected_testcase_failures++;
968*cae2ed9aSIngo Molnar 			printk("FAILED|");
969*cae2ed9aSIngo Molnar 		}
970*cae2ed9aSIngo Molnar 	} else {
971*cae2ed9aSIngo Molnar 		testcase_successes++;
972*cae2ed9aSIngo Molnar 		printk("  ok  |");
973*cae2ed9aSIngo Molnar 	}
974*cae2ed9aSIngo Molnar 	testcase_total++;
975*cae2ed9aSIngo Molnar 
976*cae2ed9aSIngo Molnar 	if (debug_locks_verbose)
977*cae2ed9aSIngo Molnar 		printk(" lockclass mask: %x, debug_locks: %d, expected: %d\n",
978*cae2ed9aSIngo Molnar 			lockclass_mask, debug_locks, expected);
979*cae2ed9aSIngo Molnar 	/*
980*cae2ed9aSIngo Molnar 	 * Some tests (e.g. double-unlock) might corrupt the preemption
981*cae2ed9aSIngo Molnar 	 * count, so restore it:
982*cae2ed9aSIngo Molnar 	 */
983*cae2ed9aSIngo Molnar 	preempt_count() = saved_preempt_count;
984*cae2ed9aSIngo Molnar #ifdef CONFIG_TRACE_IRQFLAGS
985*cae2ed9aSIngo Molnar 	if (softirq_count())
986*cae2ed9aSIngo Molnar 		current->softirqs_enabled = 0;
987*cae2ed9aSIngo Molnar 	else
988*cae2ed9aSIngo Molnar 		current->softirqs_enabled = 1;
989*cae2ed9aSIngo Molnar #endif
990*cae2ed9aSIngo Molnar 
991*cae2ed9aSIngo Molnar 	reset_locks();
992*cae2ed9aSIngo Molnar }
993*cae2ed9aSIngo Molnar 
994*cae2ed9aSIngo Molnar static inline void print_testname(const char *testname)
995*cae2ed9aSIngo Molnar {
996*cae2ed9aSIngo Molnar 	printk("%33s:", testname);
997*cae2ed9aSIngo Molnar }
998*cae2ed9aSIngo Molnar 
999*cae2ed9aSIngo Molnar #define DO_TESTCASE_1(desc, name, nr)				\
1000*cae2ed9aSIngo Molnar 	print_testname(desc"/"#nr);				\
1001*cae2ed9aSIngo Molnar 	dotest(name##_##nr, SUCCESS, LOCKTYPE_RWLOCK);		\
1002*cae2ed9aSIngo Molnar 	printk("\n");
1003*cae2ed9aSIngo Molnar 
1004*cae2ed9aSIngo Molnar #define DO_TESTCASE_1B(desc, name, nr)				\
1005*cae2ed9aSIngo Molnar 	print_testname(desc"/"#nr);				\
1006*cae2ed9aSIngo Molnar 	dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK);		\
1007*cae2ed9aSIngo Molnar 	printk("\n");
1008*cae2ed9aSIngo Molnar 
1009*cae2ed9aSIngo Molnar #define DO_TESTCASE_3(desc, name, nr)				\
1010*cae2ed9aSIngo Molnar 	print_testname(desc"/"#nr);				\
1011*cae2ed9aSIngo Molnar 	dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN);	\
1012*cae2ed9aSIngo Molnar 	dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK);	\
1013*cae2ed9aSIngo Molnar 	dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK);	\
1014*cae2ed9aSIngo Molnar 	printk("\n");
1015*cae2ed9aSIngo Molnar 
1016*cae2ed9aSIngo Molnar #define DO_TESTCASE_3RW(desc, name, nr)				\
1017*cae2ed9aSIngo Molnar 	print_testname(desc"/"#nr);				\
1018*cae2ed9aSIngo Molnar 	dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN|LOCKTYPE_RWLOCK);\
1019*cae2ed9aSIngo Molnar 	dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK);	\
1020*cae2ed9aSIngo Molnar 	dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK);	\
1021*cae2ed9aSIngo Molnar 	printk("\n");
1022*cae2ed9aSIngo Molnar 
1023*cae2ed9aSIngo Molnar #define DO_TESTCASE_6(desc, name)				\
1024*cae2ed9aSIngo Molnar 	print_testname(desc);					\
1025*cae2ed9aSIngo Molnar 	dotest(name##_spin, FAILURE, LOCKTYPE_SPIN);		\
1026*cae2ed9aSIngo Molnar 	dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK);		\
1027*cae2ed9aSIngo Molnar 	dotest(name##_rlock, FAILURE, LOCKTYPE_RWLOCK);		\
1028*cae2ed9aSIngo Molnar 	dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX);		\
1029*cae2ed9aSIngo Molnar 	dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM);		\
1030*cae2ed9aSIngo Molnar 	dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM);		\
1031*cae2ed9aSIngo Molnar 	printk("\n");
1032*cae2ed9aSIngo Molnar 
1033*cae2ed9aSIngo Molnar #define DO_TESTCASE_6_SUCCESS(desc, name)			\
1034*cae2ed9aSIngo Molnar 	print_testname(desc);					\
1035*cae2ed9aSIngo Molnar 	dotest(name##_spin, SUCCESS, LOCKTYPE_SPIN);		\
1036*cae2ed9aSIngo Molnar 	dotest(name##_wlock, SUCCESS, LOCKTYPE_RWLOCK);		\
1037*cae2ed9aSIngo Molnar 	dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK);		\
1038*cae2ed9aSIngo Molnar 	dotest(name##_mutex, SUCCESS, LOCKTYPE_MUTEX);		\
1039*cae2ed9aSIngo Molnar 	dotest(name##_wsem, SUCCESS, LOCKTYPE_RWSEM);		\
1040*cae2ed9aSIngo Molnar 	dotest(name##_rsem, SUCCESS, LOCKTYPE_RWSEM);		\
1041*cae2ed9aSIngo Molnar 	printk("\n");
1042*cae2ed9aSIngo Molnar 
1043*cae2ed9aSIngo Molnar /*
1044*cae2ed9aSIngo Molnar  * 'read' variant: rlocks must not trigger.
1045*cae2ed9aSIngo Molnar  */
1046*cae2ed9aSIngo Molnar #define DO_TESTCASE_6R(desc, name)				\
1047*cae2ed9aSIngo Molnar 	print_testname(desc);					\
1048*cae2ed9aSIngo Molnar 	dotest(name##_spin, FAILURE, LOCKTYPE_SPIN);		\
1049*cae2ed9aSIngo Molnar 	dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK);		\
1050*cae2ed9aSIngo Molnar 	dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK);		\
1051*cae2ed9aSIngo Molnar 	dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX);		\
1052*cae2ed9aSIngo Molnar 	dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM);		\
1053*cae2ed9aSIngo Molnar 	dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM);		\
1054*cae2ed9aSIngo Molnar 	printk("\n");
1055*cae2ed9aSIngo Molnar 
1056*cae2ed9aSIngo Molnar #define DO_TESTCASE_2I(desc, name, nr)				\
1057*cae2ed9aSIngo Molnar 	DO_TESTCASE_1("hard-"desc, name##_hard, nr);		\
1058*cae2ed9aSIngo Molnar 	DO_TESTCASE_1("soft-"desc, name##_soft, nr);
1059*cae2ed9aSIngo Molnar 
1060*cae2ed9aSIngo Molnar #define DO_TESTCASE_2IB(desc, name, nr)				\
1061*cae2ed9aSIngo Molnar 	DO_TESTCASE_1B("hard-"desc, name##_hard, nr);		\
1062*cae2ed9aSIngo Molnar 	DO_TESTCASE_1B("soft-"desc, name##_soft, nr);
1063*cae2ed9aSIngo Molnar 
1064*cae2ed9aSIngo Molnar #define DO_TESTCASE_6I(desc, name, nr)				\
1065*cae2ed9aSIngo Molnar 	DO_TESTCASE_3("hard-"desc, name##_hard, nr);		\
1066*cae2ed9aSIngo Molnar 	DO_TESTCASE_3("soft-"desc, name##_soft, nr);
1067*cae2ed9aSIngo Molnar 
1068*cae2ed9aSIngo Molnar #define DO_TESTCASE_6IRW(desc, name, nr)			\
1069*cae2ed9aSIngo Molnar 	DO_TESTCASE_3RW("hard-"desc, name##_hard, nr);		\
1070*cae2ed9aSIngo Molnar 	DO_TESTCASE_3RW("soft-"desc, name##_soft, nr);
1071*cae2ed9aSIngo Molnar 
1072*cae2ed9aSIngo Molnar #define DO_TESTCASE_2x3(desc, name)				\
1073*cae2ed9aSIngo Molnar 	DO_TESTCASE_3(desc, name, 12);				\
1074*cae2ed9aSIngo Molnar 	DO_TESTCASE_3(desc, name, 21);
1075*cae2ed9aSIngo Molnar 
1076*cae2ed9aSIngo Molnar #define DO_TESTCASE_2x6(desc, name)				\
1077*cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 12);				\
1078*cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 21);
1079*cae2ed9aSIngo Molnar 
1080*cae2ed9aSIngo Molnar #define DO_TESTCASE_6x2(desc, name)				\
1081*cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 123);			\
1082*cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 132);			\
1083*cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 213);			\
1084*cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 231);			\
1085*cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 312);			\
1086*cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 321);
1087*cae2ed9aSIngo Molnar 
1088*cae2ed9aSIngo Molnar #define DO_TESTCASE_6x2B(desc, name)				\
1089*cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 123);			\
1090*cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 132);			\
1091*cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 213);			\
1092*cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 231);			\
1093*cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 312);			\
1094*cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 321);
1095*cae2ed9aSIngo Molnar 
1096*cae2ed9aSIngo Molnar #define DO_TESTCASE_6x6(desc, name)				\
1097*cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 123);			\
1098*cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 132);			\
1099*cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 213);			\
1100*cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 231);			\
1101*cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 312);			\
1102*cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 321);
1103*cae2ed9aSIngo Molnar 
1104*cae2ed9aSIngo Molnar #define DO_TESTCASE_6x6RW(desc, name)				\
1105*cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 123);			\
1106*cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 132);			\
1107*cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 213);			\
1108*cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 231);			\
1109*cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 312);			\
1110*cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 321);
1111*cae2ed9aSIngo Molnar 
1112*cae2ed9aSIngo Molnar 
1113*cae2ed9aSIngo Molnar void locking_selftest(void)
1114*cae2ed9aSIngo Molnar {
1115*cae2ed9aSIngo Molnar 	/*
1116*cae2ed9aSIngo Molnar 	 * Got a locking failure before the selftest ran?
1117*cae2ed9aSIngo Molnar 	 */
1118*cae2ed9aSIngo Molnar 	if (!debug_locks) {
1119*cae2ed9aSIngo Molnar 		printk("----------------------------------\n");
1120*cae2ed9aSIngo Molnar 		printk("| Locking API testsuite disabled |\n");
1121*cae2ed9aSIngo Molnar 		printk("----------------------------------\n");
1122*cae2ed9aSIngo Molnar 		return;
1123*cae2ed9aSIngo Molnar 	}
1124*cae2ed9aSIngo Molnar 
1125*cae2ed9aSIngo Molnar 	/*
1126*cae2ed9aSIngo Molnar 	 * Run the testsuite:
1127*cae2ed9aSIngo Molnar 	 */
1128*cae2ed9aSIngo Molnar 	printk("------------------------\n");
1129*cae2ed9aSIngo Molnar 	printk("| Locking API testsuite:\n");
1130*cae2ed9aSIngo Molnar 	printk("----------------------------------------------------------------------------\n");
1131*cae2ed9aSIngo Molnar 	printk("                                 | spin |wlock |rlock |mutex | wsem | rsem |\n");
1132*cae2ed9aSIngo Molnar 	printk("  --------------------------------------------------------------------------\n");
1133*cae2ed9aSIngo Molnar 
1134*cae2ed9aSIngo Molnar 	init_shared_classes();
1135*cae2ed9aSIngo Molnar 	debug_locks_silent = !debug_locks_verbose;
1136*cae2ed9aSIngo Molnar 
1137*cae2ed9aSIngo Molnar 	DO_TESTCASE_6("A-A deadlock", AA);
1138*cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-B-A deadlock", ABBA);
1139*cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-B-C-C-A deadlock", ABBCCA);
1140*cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-C-A-B-C deadlock", ABCABC);
1141*cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-B-C-C-D-D-A deadlock", ABBCCDDA);
1142*cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-C-D-B-D-D-A deadlock", ABCDBDDA);
1143*cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-C-D-B-C-D-A deadlock", ABCDBCDA);
1144*cae2ed9aSIngo Molnar 	DO_TESTCASE_6("double unlock", double_unlock);
1145*cae2ed9aSIngo Molnar 	DO_TESTCASE_6("initialize held", init_held);
1146*cae2ed9aSIngo Molnar 	DO_TESTCASE_6_SUCCESS("bad unlock order", bad_unlock_order);
1147*cae2ed9aSIngo Molnar 
1148*cae2ed9aSIngo Molnar 	printk("  --------------------------------------------------------------------------\n");
1149*cae2ed9aSIngo Molnar 	print_testname("recursive read-lock");
1150*cae2ed9aSIngo Molnar 	printk("             |");
1151*cae2ed9aSIngo Molnar 	dotest(rlock_AA1, SUCCESS, LOCKTYPE_RWLOCK);
1152*cae2ed9aSIngo Molnar 	printk("             |");
1153*cae2ed9aSIngo Molnar 	dotest(rsem_AA1, FAILURE, LOCKTYPE_RWSEM);
1154*cae2ed9aSIngo Molnar 	printk("\n");
1155*cae2ed9aSIngo Molnar 
1156*cae2ed9aSIngo Molnar 	print_testname("recursive read-lock #2");
1157*cae2ed9aSIngo Molnar 	printk("             |");
1158*cae2ed9aSIngo Molnar 	dotest(rlock_AA1B, FAILURE, LOCKTYPE_RWLOCK);
1159*cae2ed9aSIngo Molnar 	printk("             |");
1160*cae2ed9aSIngo Molnar 	dotest(rsem_AA1B, FAILURE, LOCKTYPE_RWSEM);
1161*cae2ed9aSIngo Molnar 	printk("\n");
1162*cae2ed9aSIngo Molnar 
1163*cae2ed9aSIngo Molnar 	print_testname("mixed read-write-lock");
1164*cae2ed9aSIngo Molnar 	printk("             |");
1165*cae2ed9aSIngo Molnar 	dotest(rlock_AA2, FAILURE, LOCKTYPE_RWLOCK);
1166*cae2ed9aSIngo Molnar 	printk("             |");
1167*cae2ed9aSIngo Molnar 	dotest(rsem_AA2, FAILURE, LOCKTYPE_RWSEM);
1168*cae2ed9aSIngo Molnar 	printk("\n");
1169*cae2ed9aSIngo Molnar 
1170*cae2ed9aSIngo Molnar 	print_testname("mixed write-read-lock");
1171*cae2ed9aSIngo Molnar 	printk("             |");
1172*cae2ed9aSIngo Molnar 	dotest(rlock_AA3, FAILURE, LOCKTYPE_RWLOCK);
1173*cae2ed9aSIngo Molnar 	printk("             |");
1174*cae2ed9aSIngo Molnar 	dotest(rsem_AA3, FAILURE, LOCKTYPE_RWSEM);
1175*cae2ed9aSIngo Molnar 	printk("\n");
1176*cae2ed9aSIngo Molnar 
1177*cae2ed9aSIngo Molnar 	printk("  --------------------------------------------------------------------------\n");
1178*cae2ed9aSIngo Molnar 
1179*cae2ed9aSIngo Molnar 	/*
1180*cae2ed9aSIngo Molnar 	 * irq-context testcases:
1181*cae2ed9aSIngo Molnar 	 */
1182*cae2ed9aSIngo Molnar 	DO_TESTCASE_2x6("irqs-on + irq-safe-A", irqsafe1);
1183*cae2ed9aSIngo Molnar 	DO_TESTCASE_2x3("sirq-safe-A => hirqs-on", irqsafe2A);
1184*cae2ed9aSIngo Molnar 	DO_TESTCASE_2x6("safe-A + irqs-on", irqsafe2B);
1185*cae2ed9aSIngo Molnar 	DO_TESTCASE_6x6("safe-A + unsafe-B #1", irqsafe3);
1186*cae2ed9aSIngo Molnar 	DO_TESTCASE_6x6("safe-A + unsafe-B #2", irqsafe4);
1187*cae2ed9aSIngo Molnar 	DO_TESTCASE_6x6RW("irq lock-inversion", irq_inversion);
1188*cae2ed9aSIngo Molnar 
1189*cae2ed9aSIngo Molnar 	DO_TESTCASE_6x2("irq read-recursion", irq_read_recursion);
1190*cae2ed9aSIngo Molnar //	DO_TESTCASE_6x2B("irq read-recursion #2", irq_read_recursion2);
1191*cae2ed9aSIngo Molnar 
1192*cae2ed9aSIngo Molnar 	if (unexpected_testcase_failures) {
1193*cae2ed9aSIngo Molnar 		printk("-----------------------------------------------------------------\n");
1194*cae2ed9aSIngo Molnar 		debug_locks = 0;
1195*cae2ed9aSIngo Molnar 		printk("BUG: %3d unexpected failures (out of %3d) - debugging disabled! |\n",
1196*cae2ed9aSIngo Molnar 			unexpected_testcase_failures, testcase_total);
1197*cae2ed9aSIngo Molnar 		printk("-----------------------------------------------------------------\n");
1198*cae2ed9aSIngo Molnar 	} else if (expected_testcase_failures && testcase_successes) {
1199*cae2ed9aSIngo Molnar 		printk("--------------------------------------------------------\n");
1200*cae2ed9aSIngo Molnar 		printk("%3d out of %3d testcases failed, as expected. |\n",
1201*cae2ed9aSIngo Molnar 			expected_testcase_failures, testcase_total);
1202*cae2ed9aSIngo Molnar 		printk("----------------------------------------------------\n");
1203*cae2ed9aSIngo Molnar 		debug_locks = 1;
1204*cae2ed9aSIngo Molnar 	} else if (expected_testcase_failures && !testcase_successes) {
1205*cae2ed9aSIngo Molnar 		printk("--------------------------------------------------------\n");
1206*cae2ed9aSIngo Molnar 		printk("All %3d testcases failed, as expected. |\n",
1207*cae2ed9aSIngo Molnar 			expected_testcase_failures);
1208*cae2ed9aSIngo Molnar 		printk("----------------------------------------\n");
1209*cae2ed9aSIngo Molnar 		debug_locks = 1;
1210*cae2ed9aSIngo Molnar 	} else {
1211*cae2ed9aSIngo Molnar 		printk("-------------------------------------------------------\n");
1212*cae2ed9aSIngo Molnar 		printk("Good, all %3d testcases passed! |\n",
1213*cae2ed9aSIngo Molnar 			testcase_successes);
1214*cae2ed9aSIngo Molnar 		printk("---------------------------------\n");
1215*cae2ed9aSIngo Molnar 		debug_locks = 1;
1216*cae2ed9aSIngo Molnar 	}
1217*cae2ed9aSIngo Molnar 	debug_locks_silent = 0;
1218*cae2ed9aSIngo Molnar }
1219