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