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