xref: /linux-6.15/lib/locking-selftest.c (revision 166989e3)
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 
291de99445SMaarten Lankhorst static DEFINE_WW_CLASS(ww_lockdep);
301de99445SMaarten Lankhorst 
31cae2ed9aSIngo Molnar static int __init setup_debug_locks_verbose(char *str)
32cae2ed9aSIngo Molnar {
33cae2ed9aSIngo Molnar 	get_option(&str, &debug_locks_verbose);
34cae2ed9aSIngo Molnar 
35cae2ed9aSIngo Molnar 	return 1;
36cae2ed9aSIngo Molnar }
37cae2ed9aSIngo Molnar 
38cae2ed9aSIngo Molnar __setup("debug_locks_verbose=", setup_debug_locks_verbose);
39cae2ed9aSIngo Molnar 
40cae2ed9aSIngo Molnar #define FAILURE		0
41cae2ed9aSIngo Molnar #define SUCCESS		1
42cae2ed9aSIngo Molnar 
43cae2ed9aSIngo Molnar #define LOCKTYPE_SPIN	0x1
44cae2ed9aSIngo Molnar #define LOCKTYPE_RWLOCK	0x2
45cae2ed9aSIngo Molnar #define LOCKTYPE_MUTEX	0x4
46cae2ed9aSIngo Molnar #define LOCKTYPE_RWSEM	0x8
471de99445SMaarten Lankhorst #define LOCKTYPE_WW	0x10
481de99445SMaarten Lankhorst 
491de99445SMaarten Lankhorst static struct ww_acquire_ctx t, t2;
50f3cf139eSMaarten Lankhorst static struct ww_mutex o, o2, o3;
51cae2ed9aSIngo Molnar 
52cae2ed9aSIngo Molnar /*
53cae2ed9aSIngo Molnar  * Normal standalone locks, for the circular and irq-context
54cae2ed9aSIngo Molnar  * dependency tests:
55cae2ed9aSIngo Molnar  */
569fb1b90cSYong Zhang static DEFINE_RAW_SPINLOCK(lock_A);
579fb1b90cSYong Zhang static DEFINE_RAW_SPINLOCK(lock_B);
589fb1b90cSYong Zhang static DEFINE_RAW_SPINLOCK(lock_C);
599fb1b90cSYong Zhang static DEFINE_RAW_SPINLOCK(lock_D);
60cae2ed9aSIngo Molnar 
61cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_A);
62cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_B);
63cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_C);
64cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_D);
65cae2ed9aSIngo Molnar 
66cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_A);
67cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_B);
68cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_C);
69cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_D);
70cae2ed9aSIngo Molnar 
71cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_A);
72cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_B);
73cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_C);
74cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_D);
75cae2ed9aSIngo Molnar 
76cae2ed9aSIngo Molnar /*
77cae2ed9aSIngo Molnar  * Locks that we initialize dynamically as well so that
78cae2ed9aSIngo Molnar  * e.g. X1 and X2 becomes two instances of the same class,
79cae2ed9aSIngo Molnar  * but X* and Y* are different classes. We do this so that
80cae2ed9aSIngo Molnar  * we do not trigger a real lockup:
81cae2ed9aSIngo Molnar  */
829fb1b90cSYong Zhang static DEFINE_RAW_SPINLOCK(lock_X1);
839fb1b90cSYong Zhang static DEFINE_RAW_SPINLOCK(lock_X2);
849fb1b90cSYong Zhang static DEFINE_RAW_SPINLOCK(lock_Y1);
859fb1b90cSYong Zhang static DEFINE_RAW_SPINLOCK(lock_Y2);
869fb1b90cSYong Zhang static DEFINE_RAW_SPINLOCK(lock_Z1);
879fb1b90cSYong Zhang static DEFINE_RAW_SPINLOCK(lock_Z2);
88cae2ed9aSIngo Molnar 
89cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_X1);
90cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_X2);
91cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Y1);
92cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Y2);
93cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Z1);
94cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Z2);
95cae2ed9aSIngo Molnar 
96cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_X1);
97cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_X2);
98cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Y1);
99cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Y2);
100cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Z1);
101cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Z2);
102cae2ed9aSIngo Molnar 
103cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_X1);
104cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_X2);
105cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Y1);
106cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Y2);
107cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Z1);
108cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Z2);
109cae2ed9aSIngo Molnar 
110cae2ed9aSIngo Molnar /*
111cae2ed9aSIngo Molnar  * non-inlined runtime initializers, to let separate locks share
112cae2ed9aSIngo Molnar  * the same lock-class:
113cae2ed9aSIngo Molnar  */
114cae2ed9aSIngo Molnar #define INIT_CLASS_FUNC(class) 				\
115cae2ed9aSIngo Molnar static noinline void					\
1169fb1b90cSYong Zhang init_class_##class(raw_spinlock_t *lock, rwlock_t *rwlock, \
1179fb1b90cSYong Zhang 	struct mutex *mutex, struct rw_semaphore *rwsem)\
118cae2ed9aSIngo Molnar {							\
1199fb1b90cSYong Zhang 	raw_spin_lock_init(lock);			\
120cae2ed9aSIngo Molnar 	rwlock_init(rwlock);				\
121cae2ed9aSIngo Molnar 	mutex_init(mutex);				\
122cae2ed9aSIngo Molnar 	init_rwsem(rwsem);				\
123cae2ed9aSIngo Molnar }
124cae2ed9aSIngo Molnar 
125cae2ed9aSIngo Molnar INIT_CLASS_FUNC(X)
126cae2ed9aSIngo Molnar INIT_CLASS_FUNC(Y)
127cae2ed9aSIngo Molnar INIT_CLASS_FUNC(Z)
128cae2ed9aSIngo Molnar 
129cae2ed9aSIngo Molnar static void init_shared_classes(void)
130cae2ed9aSIngo Molnar {
131cae2ed9aSIngo Molnar 	init_class_X(&lock_X1, &rwlock_X1, &mutex_X1, &rwsem_X1);
132cae2ed9aSIngo Molnar 	init_class_X(&lock_X2, &rwlock_X2, &mutex_X2, &rwsem_X2);
133cae2ed9aSIngo Molnar 
134cae2ed9aSIngo Molnar 	init_class_Y(&lock_Y1, &rwlock_Y1, &mutex_Y1, &rwsem_Y1);
135cae2ed9aSIngo Molnar 	init_class_Y(&lock_Y2, &rwlock_Y2, &mutex_Y2, &rwsem_Y2);
136cae2ed9aSIngo Molnar 
137cae2ed9aSIngo Molnar 	init_class_Z(&lock_Z1, &rwlock_Z1, &mutex_Z1, &rwsem_Z1);
138cae2ed9aSIngo Molnar 	init_class_Z(&lock_Z2, &rwlock_Z2, &mutex_Z2, &rwsem_Z2);
139cae2ed9aSIngo Molnar }
140cae2ed9aSIngo Molnar 
141cae2ed9aSIngo Molnar /*
142cae2ed9aSIngo Molnar  * For spinlocks and rwlocks we also do hardirq-safe / softirq-safe tests.
143cae2ed9aSIngo Molnar  * The following functions use a lock from a simulated hardirq/softirq
144cae2ed9aSIngo Molnar  * context, causing the locks to be marked as hardirq-safe/softirq-safe:
145cae2ed9aSIngo Molnar  */
146cae2ed9aSIngo Molnar 
147cae2ed9aSIngo Molnar #define HARDIRQ_DISABLE		local_irq_disable
148cae2ed9aSIngo Molnar #define HARDIRQ_ENABLE		local_irq_enable
149cae2ed9aSIngo Molnar 
150cae2ed9aSIngo Molnar #define HARDIRQ_ENTER()				\
151cae2ed9aSIngo Molnar 	local_irq_disable();			\
152ba9f207cSFrederic Weisbecker 	__irq_enter();				\
153cae2ed9aSIngo Molnar 	WARN_ON(!in_irq());
154cae2ed9aSIngo Molnar 
155cae2ed9aSIngo Molnar #define HARDIRQ_EXIT()				\
156cae2ed9aSIngo Molnar 	__irq_exit();				\
157cae2ed9aSIngo Molnar 	local_irq_enable();
158cae2ed9aSIngo Molnar 
159cae2ed9aSIngo Molnar #define SOFTIRQ_DISABLE		local_bh_disable
160cae2ed9aSIngo Molnar #define SOFTIRQ_ENABLE		local_bh_enable
161cae2ed9aSIngo Molnar 
162cae2ed9aSIngo Molnar #define SOFTIRQ_ENTER()				\
163cae2ed9aSIngo Molnar 		local_bh_disable();		\
164cae2ed9aSIngo Molnar 		local_irq_disable();		\
165d820ac4cSIngo Molnar 		lockdep_softirq_enter();	\
166cae2ed9aSIngo Molnar 		WARN_ON(!in_softirq());
167cae2ed9aSIngo Molnar 
168cae2ed9aSIngo Molnar #define SOFTIRQ_EXIT()				\
169d820ac4cSIngo Molnar 		lockdep_softirq_exit();		\
170cae2ed9aSIngo Molnar 		local_irq_enable();		\
171cae2ed9aSIngo Molnar 		local_bh_enable();
172cae2ed9aSIngo Molnar 
173cae2ed9aSIngo Molnar /*
174cae2ed9aSIngo Molnar  * Shortcuts for lock/unlock API variants, to keep
175cae2ed9aSIngo Molnar  * the testcases compact:
176cae2ed9aSIngo Molnar  */
1779fb1b90cSYong Zhang #define L(x)			raw_spin_lock(&lock_##x)
1789fb1b90cSYong Zhang #define U(x)			raw_spin_unlock(&lock_##x)
179cae2ed9aSIngo Molnar #define LU(x)			L(x); U(x)
1809fb1b90cSYong Zhang #define SI(x)			raw_spin_lock_init(&lock_##x)
181cae2ed9aSIngo Molnar 
182cae2ed9aSIngo Molnar #define WL(x)			write_lock(&rwlock_##x)
183cae2ed9aSIngo Molnar #define WU(x)			write_unlock(&rwlock_##x)
184cae2ed9aSIngo Molnar #define WLU(x)			WL(x); WU(x)
185cae2ed9aSIngo Molnar 
186cae2ed9aSIngo Molnar #define RL(x)			read_lock(&rwlock_##x)
187cae2ed9aSIngo Molnar #define RU(x)			read_unlock(&rwlock_##x)
188cae2ed9aSIngo Molnar #define RLU(x)			RL(x); RU(x)
189cae2ed9aSIngo Molnar #define RWI(x)			rwlock_init(&rwlock_##x)
190cae2ed9aSIngo Molnar 
191cae2ed9aSIngo Molnar #define ML(x)			mutex_lock(&mutex_##x)
192cae2ed9aSIngo Molnar #define MU(x)			mutex_unlock(&mutex_##x)
193cae2ed9aSIngo Molnar #define MI(x)			mutex_init(&mutex_##x)
194cae2ed9aSIngo Molnar 
195cae2ed9aSIngo Molnar #define WSL(x)			down_write(&rwsem_##x)
196cae2ed9aSIngo Molnar #define WSU(x)			up_write(&rwsem_##x)
197cae2ed9aSIngo Molnar 
198cae2ed9aSIngo Molnar #define RSL(x)			down_read(&rwsem_##x)
199cae2ed9aSIngo Molnar #define RSU(x)			up_read(&rwsem_##x)
200cae2ed9aSIngo Molnar #define RWSI(x)			init_rwsem(&rwsem_##x)
201cae2ed9aSIngo Molnar 
2021de99445SMaarten Lankhorst #ifndef CONFIG_DEBUG_WW_MUTEX_SLOWPATH
2031de99445SMaarten Lankhorst #define WWAI(x)			ww_acquire_init(x, &ww_lockdep)
2041de99445SMaarten Lankhorst #else
2051de99445SMaarten Lankhorst #define WWAI(x)			do { ww_acquire_init(x, &ww_lockdep); (x)->deadlock_inject_countdown = ~0U; } while (0)
2061de99445SMaarten Lankhorst #endif
2071de99445SMaarten Lankhorst #define WWAD(x)			ww_acquire_done(x)
2081de99445SMaarten Lankhorst #define WWAF(x)			ww_acquire_fini(x)
2091de99445SMaarten Lankhorst 
2101de99445SMaarten Lankhorst #define WWL(x, c)		ww_mutex_lock(x, c)
2111de99445SMaarten Lankhorst #define WWT(x)			ww_mutex_trylock(x)
2121de99445SMaarten Lankhorst #define WWL1(x)			ww_mutex_lock(x, NULL)
2131de99445SMaarten Lankhorst #define WWU(x)			ww_mutex_unlock(x)
2141de99445SMaarten Lankhorst 
2151de99445SMaarten Lankhorst 
216cae2ed9aSIngo Molnar #define LOCK_UNLOCK_2(x,y)	LOCK(x); LOCK(y); UNLOCK(y); UNLOCK(x)
217cae2ed9aSIngo Molnar 
218cae2ed9aSIngo Molnar /*
219cae2ed9aSIngo Molnar  * Generate different permutations of the same testcase, using
220cae2ed9aSIngo Molnar  * the same basic lock-dependency/state events:
221cae2ed9aSIngo Molnar  */
222cae2ed9aSIngo Molnar 
223cae2ed9aSIngo Molnar #define GENERATE_TESTCASE(name)			\
224cae2ed9aSIngo Molnar 						\
225cae2ed9aSIngo Molnar static void name(void) { E(); }
226cae2ed9aSIngo Molnar 
227cae2ed9aSIngo Molnar #define GENERATE_PERMUTATIONS_2_EVENTS(name)	\
228cae2ed9aSIngo Molnar 						\
229cae2ed9aSIngo Molnar static void name##_12(void) { E1(); E2(); }	\
230cae2ed9aSIngo Molnar static void name##_21(void) { E2(); E1(); }
231cae2ed9aSIngo Molnar 
232cae2ed9aSIngo Molnar #define GENERATE_PERMUTATIONS_3_EVENTS(name)		\
233cae2ed9aSIngo Molnar 							\
234cae2ed9aSIngo Molnar static void name##_123(void) { E1(); E2(); E3(); }	\
235cae2ed9aSIngo Molnar static void name##_132(void) { E1(); E3(); E2(); }	\
236cae2ed9aSIngo Molnar static void name##_213(void) { E2(); E1(); E3(); }	\
237cae2ed9aSIngo Molnar static void name##_231(void) { E2(); E3(); E1(); }	\
238cae2ed9aSIngo Molnar static void name##_312(void) { E3(); E1(); E2(); }	\
239cae2ed9aSIngo Molnar static void name##_321(void) { E3(); E2(); E1(); }
240cae2ed9aSIngo Molnar 
241cae2ed9aSIngo Molnar /*
242cae2ed9aSIngo Molnar  * AA deadlock:
243cae2ed9aSIngo Molnar  */
244cae2ed9aSIngo Molnar 
245cae2ed9aSIngo Molnar #define E()					\
246cae2ed9aSIngo Molnar 						\
247cae2ed9aSIngo Molnar 	LOCK(X1);				\
248cae2ed9aSIngo Molnar 	LOCK(X2); /* this one should fail */
249cae2ed9aSIngo Molnar 
250cae2ed9aSIngo Molnar /*
251cae2ed9aSIngo Molnar  * 6 testcases:
252cae2ed9aSIngo Molnar  */
253cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
254cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_spin)
255cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
256cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_wlock)
257cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
258cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_rlock)
259cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
260cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_mutex)
261cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
262cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_wsem)
263cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
264cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_rsem)
265cae2ed9aSIngo Molnar 
266cae2ed9aSIngo Molnar #undef E
267cae2ed9aSIngo Molnar 
268cae2ed9aSIngo Molnar /*
269cae2ed9aSIngo Molnar  * Special-case for read-locking, they are
2706c9076ecSIngo Molnar  * allowed to recurse on the same lock class:
271cae2ed9aSIngo Molnar  */
272cae2ed9aSIngo Molnar static void rlock_AA1(void)
273cae2ed9aSIngo Molnar {
274cae2ed9aSIngo Molnar 	RL(X1);
275cae2ed9aSIngo Molnar 	RL(X1); // this one should NOT fail
276cae2ed9aSIngo Molnar }
277cae2ed9aSIngo Molnar 
278cae2ed9aSIngo Molnar static void rlock_AA1B(void)
279cae2ed9aSIngo Molnar {
280cae2ed9aSIngo Molnar 	RL(X1);
2816c9076ecSIngo Molnar 	RL(X2); // this one should NOT fail
282cae2ed9aSIngo Molnar }
283cae2ed9aSIngo Molnar 
284cae2ed9aSIngo Molnar static void rsem_AA1(void)
285cae2ed9aSIngo Molnar {
286cae2ed9aSIngo Molnar 	RSL(X1);
287cae2ed9aSIngo Molnar 	RSL(X1); // this one should fail
288cae2ed9aSIngo Molnar }
289cae2ed9aSIngo Molnar 
290cae2ed9aSIngo Molnar static void rsem_AA1B(void)
291cae2ed9aSIngo Molnar {
292cae2ed9aSIngo Molnar 	RSL(X1);
293cae2ed9aSIngo Molnar 	RSL(X2); // this one should fail
294cae2ed9aSIngo Molnar }
295cae2ed9aSIngo Molnar /*
296cae2ed9aSIngo Molnar  * The mixing of read and write locks is not allowed:
297cae2ed9aSIngo Molnar  */
298cae2ed9aSIngo Molnar static void rlock_AA2(void)
299cae2ed9aSIngo Molnar {
300cae2ed9aSIngo Molnar 	RL(X1);
301cae2ed9aSIngo Molnar 	WL(X2); // this one should fail
302cae2ed9aSIngo Molnar }
303cae2ed9aSIngo Molnar 
304cae2ed9aSIngo Molnar static void rsem_AA2(void)
305cae2ed9aSIngo Molnar {
306cae2ed9aSIngo Molnar 	RSL(X1);
307cae2ed9aSIngo Molnar 	WSL(X2); // this one should fail
308cae2ed9aSIngo Molnar }
309cae2ed9aSIngo Molnar 
310cae2ed9aSIngo Molnar static void rlock_AA3(void)
311cae2ed9aSIngo Molnar {
312cae2ed9aSIngo Molnar 	WL(X1);
313cae2ed9aSIngo Molnar 	RL(X2); // this one should fail
314cae2ed9aSIngo Molnar }
315cae2ed9aSIngo Molnar 
316cae2ed9aSIngo Molnar static void rsem_AA3(void)
317cae2ed9aSIngo Molnar {
318cae2ed9aSIngo Molnar 	WSL(X1);
319cae2ed9aSIngo Molnar 	RSL(X2); // this one should fail
320cae2ed9aSIngo Molnar }
321cae2ed9aSIngo Molnar 
322cae2ed9aSIngo Molnar /*
323cae2ed9aSIngo Molnar  * ABBA deadlock:
324cae2ed9aSIngo Molnar  */
325cae2ed9aSIngo Molnar 
326cae2ed9aSIngo Molnar #define E()					\
327cae2ed9aSIngo Molnar 						\
328cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
329cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, A); /* fail */
330cae2ed9aSIngo Molnar 
331cae2ed9aSIngo Molnar /*
332cae2ed9aSIngo Molnar  * 6 testcases:
333cae2ed9aSIngo Molnar  */
334cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
335cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_spin)
336cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
337cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_wlock)
338cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
339cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_rlock)
340cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
341cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_mutex)
342cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
343cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_wsem)
344cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
345cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_rsem)
346cae2ed9aSIngo Molnar 
347cae2ed9aSIngo Molnar #undef E
348cae2ed9aSIngo Molnar 
349cae2ed9aSIngo Molnar /*
350cae2ed9aSIngo Molnar  * AB BC CA deadlock:
351cae2ed9aSIngo Molnar  */
352cae2ed9aSIngo Molnar 
353cae2ed9aSIngo Molnar #define E()					\
354cae2ed9aSIngo Molnar 						\
355cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
356cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, C);			\
357cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, A); /* fail */
358cae2ed9aSIngo Molnar 
359cae2ed9aSIngo Molnar /*
360cae2ed9aSIngo Molnar  * 6 testcases:
361cae2ed9aSIngo Molnar  */
362cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
363cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_spin)
364cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
365cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_wlock)
366cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
367cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_rlock)
368cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
369cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_mutex)
370cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
371cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_wsem)
372cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
373cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_rsem)
374cae2ed9aSIngo Molnar 
375cae2ed9aSIngo Molnar #undef E
376cae2ed9aSIngo Molnar 
377cae2ed9aSIngo Molnar /*
378cae2ed9aSIngo Molnar  * AB CA BC deadlock:
379cae2ed9aSIngo Molnar  */
380cae2ed9aSIngo Molnar 
381cae2ed9aSIngo Molnar #define E()					\
382cae2ed9aSIngo Molnar 						\
383cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
384cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, A);			\
385cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, C); /* fail */
386cae2ed9aSIngo Molnar 
387cae2ed9aSIngo Molnar /*
388cae2ed9aSIngo Molnar  * 6 testcases:
389cae2ed9aSIngo Molnar  */
390cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
391cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_spin)
392cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
393cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_wlock)
394cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
395cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_rlock)
396cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
397cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_mutex)
398cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
399cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_wsem)
400cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
401cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_rsem)
402cae2ed9aSIngo Molnar 
403cae2ed9aSIngo Molnar #undef E
404cae2ed9aSIngo Molnar 
405cae2ed9aSIngo Molnar /*
406cae2ed9aSIngo Molnar  * AB BC CD DA deadlock:
407cae2ed9aSIngo Molnar  */
408cae2ed9aSIngo Molnar 
409cae2ed9aSIngo Molnar #define E()					\
410cae2ed9aSIngo Molnar 						\
411cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
412cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, C);			\
413cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, D);			\
414cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(D, A); /* fail */
415cae2ed9aSIngo Molnar 
416cae2ed9aSIngo Molnar /*
417cae2ed9aSIngo Molnar  * 6 testcases:
418cae2ed9aSIngo Molnar  */
419cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
420cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_spin)
421cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
422cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_wlock)
423cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
424cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_rlock)
425cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
426cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_mutex)
427cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
428cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_wsem)
429cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
430cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_rsem)
431cae2ed9aSIngo Molnar 
432cae2ed9aSIngo Molnar #undef E
433cae2ed9aSIngo Molnar 
434cae2ed9aSIngo Molnar /*
435cae2ed9aSIngo Molnar  * AB CD BD DA deadlock:
436cae2ed9aSIngo Molnar  */
437cae2ed9aSIngo Molnar #define E()					\
438cae2ed9aSIngo Molnar 						\
439cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
440cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, D);			\
441cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, D);			\
442cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(D, A); /* fail */
443cae2ed9aSIngo Molnar 
444cae2ed9aSIngo Molnar /*
445cae2ed9aSIngo Molnar  * 6 testcases:
446cae2ed9aSIngo Molnar  */
447cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
448cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_spin)
449cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
450cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_wlock)
451cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
452cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_rlock)
453cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
454cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_mutex)
455cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
456cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_wsem)
457cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
458cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_rsem)
459cae2ed9aSIngo Molnar 
460cae2ed9aSIngo Molnar #undef E
461cae2ed9aSIngo Molnar 
462cae2ed9aSIngo Molnar /*
463cae2ed9aSIngo Molnar  * AB CD BC DA deadlock:
464cae2ed9aSIngo Molnar  */
465cae2ed9aSIngo Molnar #define E()					\
466cae2ed9aSIngo Molnar 						\
467cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
468cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, D);			\
469cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, C);			\
470cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(D, A); /* fail */
471cae2ed9aSIngo Molnar 
472cae2ed9aSIngo Molnar /*
473cae2ed9aSIngo Molnar  * 6 testcases:
474cae2ed9aSIngo Molnar  */
475cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
476cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_spin)
477cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
478cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_wlock)
479cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
480cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_rlock)
481cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
482cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_mutex)
483cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
484cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_wsem)
485cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
486cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_rsem)
487cae2ed9aSIngo Molnar 
488cae2ed9aSIngo Molnar #undef E
489cae2ed9aSIngo Molnar 
490cae2ed9aSIngo Molnar /*
491cae2ed9aSIngo Molnar  * Double unlock:
492cae2ed9aSIngo Molnar  */
493cae2ed9aSIngo Molnar #define E()					\
494cae2ed9aSIngo Molnar 						\
495cae2ed9aSIngo Molnar 	LOCK(A);				\
496cae2ed9aSIngo Molnar 	UNLOCK(A);				\
497cae2ed9aSIngo Molnar 	UNLOCK(A); /* fail */
498cae2ed9aSIngo Molnar 
499cae2ed9aSIngo Molnar /*
500cae2ed9aSIngo Molnar  * 6 testcases:
501cae2ed9aSIngo Molnar  */
502cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
503cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_spin)
504cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
505cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_wlock)
506cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
507cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_rlock)
508cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
509cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_mutex)
510cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
511cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_wsem)
512cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
513cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_rsem)
514cae2ed9aSIngo Molnar 
515cae2ed9aSIngo Molnar #undef E
516cae2ed9aSIngo Molnar 
517cae2ed9aSIngo Molnar /*
518cae2ed9aSIngo Molnar  * Bad unlock ordering:
519cae2ed9aSIngo Molnar  */
520cae2ed9aSIngo Molnar #define E()					\
521cae2ed9aSIngo Molnar 						\
522cae2ed9aSIngo Molnar 	LOCK(A);				\
523cae2ed9aSIngo Molnar 	LOCK(B);				\
524cae2ed9aSIngo Molnar 	UNLOCK(A); /* fail */			\
525cae2ed9aSIngo Molnar 	UNLOCK(B);
526cae2ed9aSIngo Molnar 
527cae2ed9aSIngo Molnar /*
528cae2ed9aSIngo Molnar  * 6 testcases:
529cae2ed9aSIngo Molnar  */
530cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
531cae2ed9aSIngo Molnar GENERATE_TESTCASE(bad_unlock_order_spin)
532cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
533cae2ed9aSIngo Molnar GENERATE_TESTCASE(bad_unlock_order_wlock)
534cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
535cae2ed9aSIngo Molnar GENERATE_TESTCASE(bad_unlock_order_rlock)
536cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
537cae2ed9aSIngo Molnar GENERATE_TESTCASE(bad_unlock_order_mutex)
538cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
539cae2ed9aSIngo Molnar GENERATE_TESTCASE(bad_unlock_order_wsem)
540cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
541cae2ed9aSIngo Molnar GENERATE_TESTCASE(bad_unlock_order_rsem)
542cae2ed9aSIngo Molnar 
543cae2ed9aSIngo Molnar #undef E
544cae2ed9aSIngo Molnar 
545cae2ed9aSIngo Molnar /*
546cae2ed9aSIngo Molnar  * initializing a held lock:
547cae2ed9aSIngo Molnar  */
548cae2ed9aSIngo Molnar #define E()					\
549cae2ed9aSIngo Molnar 						\
550cae2ed9aSIngo Molnar 	LOCK(A);				\
551cae2ed9aSIngo Molnar 	INIT(A); /* fail */
552cae2ed9aSIngo Molnar 
553cae2ed9aSIngo Molnar /*
554cae2ed9aSIngo Molnar  * 6 testcases:
555cae2ed9aSIngo Molnar  */
556cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
557cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_spin)
558cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
559cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_wlock)
560cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
561cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_rlock)
562cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
563cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_mutex)
564cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
565cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_wsem)
566cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
567cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_rsem)
568cae2ed9aSIngo Molnar 
569cae2ed9aSIngo Molnar #undef E
570cae2ed9aSIngo Molnar 
571cae2ed9aSIngo Molnar /*
572cae2ed9aSIngo Molnar  * locking an irq-safe lock with irqs enabled:
573cae2ed9aSIngo Molnar  */
574cae2ed9aSIngo Molnar #define E1()				\
575cae2ed9aSIngo Molnar 					\
576cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
577cae2ed9aSIngo Molnar 	LOCK(A);			\
578cae2ed9aSIngo Molnar 	UNLOCK(A);			\
579cae2ed9aSIngo Molnar 	IRQ_EXIT();
580cae2ed9aSIngo Molnar 
581cae2ed9aSIngo Molnar #define E2()				\
582cae2ed9aSIngo Molnar 					\
583cae2ed9aSIngo Molnar 	LOCK(A);			\
584cae2ed9aSIngo Molnar 	UNLOCK(A);
585cae2ed9aSIngo Molnar 
586cae2ed9aSIngo Molnar /*
587cae2ed9aSIngo Molnar  * Generate 24 testcases:
588cae2ed9aSIngo Molnar  */
589cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
590cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_spin)
591cae2ed9aSIngo Molnar 
592cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
593cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_rlock)
594cae2ed9aSIngo Molnar 
595cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
596cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_wlock)
597cae2ed9aSIngo Molnar 
598cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
599cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_spin)
600cae2ed9aSIngo Molnar 
601cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
602cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_rlock)
603cae2ed9aSIngo Molnar 
604cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
605cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_wlock)
606cae2ed9aSIngo Molnar 
607cae2ed9aSIngo Molnar #undef E1
608cae2ed9aSIngo Molnar #undef E2
609cae2ed9aSIngo Molnar 
610cae2ed9aSIngo Molnar /*
611cae2ed9aSIngo Molnar  * Enabling hardirqs with a softirq-safe lock held:
612cae2ed9aSIngo Molnar  */
613cae2ed9aSIngo Molnar #define E1()				\
614cae2ed9aSIngo Molnar 					\
615cae2ed9aSIngo Molnar 	SOFTIRQ_ENTER();		\
616cae2ed9aSIngo Molnar 	LOCK(A);			\
617cae2ed9aSIngo Molnar 	UNLOCK(A);			\
618cae2ed9aSIngo Molnar 	SOFTIRQ_EXIT();
619cae2ed9aSIngo Molnar 
620cae2ed9aSIngo Molnar #define E2()				\
621cae2ed9aSIngo Molnar 					\
622cae2ed9aSIngo Molnar 	HARDIRQ_DISABLE();		\
623cae2ed9aSIngo Molnar 	LOCK(A);			\
624cae2ed9aSIngo Molnar 	HARDIRQ_ENABLE();		\
625cae2ed9aSIngo Molnar 	UNLOCK(A);
626cae2ed9aSIngo Molnar 
627cae2ed9aSIngo Molnar /*
628cae2ed9aSIngo Molnar  * Generate 12 testcases:
629cae2ed9aSIngo Molnar  */
630cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
631cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_spin)
632cae2ed9aSIngo Molnar 
633cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
634cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_wlock)
635cae2ed9aSIngo Molnar 
636cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
637cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_rlock)
638cae2ed9aSIngo Molnar 
639cae2ed9aSIngo Molnar #undef E1
640cae2ed9aSIngo Molnar #undef E2
641cae2ed9aSIngo Molnar 
642cae2ed9aSIngo Molnar /*
643cae2ed9aSIngo Molnar  * Enabling irqs with an irq-safe lock held:
644cae2ed9aSIngo Molnar  */
645cae2ed9aSIngo Molnar #define E1()				\
646cae2ed9aSIngo Molnar 					\
647cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
648cae2ed9aSIngo Molnar 	LOCK(A);			\
649cae2ed9aSIngo Molnar 	UNLOCK(A);			\
650cae2ed9aSIngo Molnar 	IRQ_EXIT();
651cae2ed9aSIngo Molnar 
652cae2ed9aSIngo Molnar #define E2()				\
653cae2ed9aSIngo Molnar 					\
654cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
655cae2ed9aSIngo Molnar 	LOCK(A);			\
656cae2ed9aSIngo Molnar 	IRQ_ENABLE();			\
657cae2ed9aSIngo Molnar 	UNLOCK(A);
658cae2ed9aSIngo Molnar 
659cae2ed9aSIngo Molnar /*
660cae2ed9aSIngo Molnar  * Generate 24 testcases:
661cae2ed9aSIngo Molnar  */
662cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
663cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_spin)
664cae2ed9aSIngo Molnar 
665cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
666cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_rlock)
667cae2ed9aSIngo Molnar 
668cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
669cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_wlock)
670cae2ed9aSIngo Molnar 
671cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
672cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_spin)
673cae2ed9aSIngo Molnar 
674cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
675cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_rlock)
676cae2ed9aSIngo Molnar 
677cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
678cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock)
679cae2ed9aSIngo Molnar 
680cae2ed9aSIngo Molnar #undef E1
681cae2ed9aSIngo Molnar #undef E2
682cae2ed9aSIngo Molnar 
683cae2ed9aSIngo Molnar /*
684cae2ed9aSIngo Molnar  * Acquiring a irq-unsafe lock while holding an irq-safe-lock:
685cae2ed9aSIngo Molnar  */
686cae2ed9aSIngo Molnar #define E1()				\
687cae2ed9aSIngo Molnar 					\
688cae2ed9aSIngo Molnar 	LOCK(A);			\
689cae2ed9aSIngo Molnar 	LOCK(B);			\
690cae2ed9aSIngo Molnar 	UNLOCK(B);			\
691cae2ed9aSIngo Molnar 	UNLOCK(A);			\
692cae2ed9aSIngo Molnar 
693cae2ed9aSIngo Molnar #define E2()				\
694cae2ed9aSIngo Molnar 					\
695cae2ed9aSIngo Molnar 	LOCK(B);			\
696cae2ed9aSIngo Molnar 	UNLOCK(B);
697cae2ed9aSIngo Molnar 
698cae2ed9aSIngo Molnar #define E3()				\
699cae2ed9aSIngo Molnar 					\
700cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
701cae2ed9aSIngo Molnar 	LOCK(A);			\
702cae2ed9aSIngo Molnar 	UNLOCK(A);			\
703cae2ed9aSIngo Molnar 	IRQ_EXIT();
704cae2ed9aSIngo Molnar 
705cae2ed9aSIngo Molnar /*
706cae2ed9aSIngo Molnar  * Generate 36 testcases:
707cae2ed9aSIngo Molnar  */
708cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
709cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_spin)
710cae2ed9aSIngo Molnar 
711cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
712cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_rlock)
713cae2ed9aSIngo Molnar 
714cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
715cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_wlock)
716cae2ed9aSIngo Molnar 
717cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
718cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_spin)
719cae2ed9aSIngo Molnar 
720cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
721cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_rlock)
722cae2ed9aSIngo Molnar 
723cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
724cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock)
725cae2ed9aSIngo Molnar 
726cae2ed9aSIngo Molnar #undef E1
727cae2ed9aSIngo Molnar #undef E2
728cae2ed9aSIngo Molnar #undef E3
729cae2ed9aSIngo Molnar 
730cae2ed9aSIngo Molnar /*
731cae2ed9aSIngo Molnar  * If a lock turns into softirq-safe, but earlier it took
732cae2ed9aSIngo Molnar  * a softirq-unsafe lock:
733cae2ed9aSIngo Molnar  */
734cae2ed9aSIngo Molnar 
735cae2ed9aSIngo Molnar #define E1()				\
736cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
737cae2ed9aSIngo Molnar 	LOCK(A);			\
738cae2ed9aSIngo Molnar 	LOCK(B);			\
739cae2ed9aSIngo Molnar 	UNLOCK(B);			\
740cae2ed9aSIngo Molnar 	UNLOCK(A);			\
741cae2ed9aSIngo Molnar 	IRQ_ENABLE();
742cae2ed9aSIngo Molnar 
743cae2ed9aSIngo Molnar #define E2()				\
744cae2ed9aSIngo Molnar 	LOCK(B);			\
745cae2ed9aSIngo Molnar 	UNLOCK(B);
746cae2ed9aSIngo Molnar 
747cae2ed9aSIngo Molnar #define E3()				\
748cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
749cae2ed9aSIngo Molnar 	LOCK(A);			\
750cae2ed9aSIngo Molnar 	UNLOCK(A);			\
751cae2ed9aSIngo Molnar 	IRQ_EXIT();
752cae2ed9aSIngo Molnar 
753cae2ed9aSIngo Molnar /*
754cae2ed9aSIngo Molnar  * Generate 36 testcases:
755cae2ed9aSIngo Molnar  */
756cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
757cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_spin)
758cae2ed9aSIngo Molnar 
759cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
760cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_rlock)
761cae2ed9aSIngo Molnar 
762cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
763cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_wlock)
764cae2ed9aSIngo Molnar 
765cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
766cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_spin)
767cae2ed9aSIngo Molnar 
768cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
769cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_rlock)
770cae2ed9aSIngo Molnar 
771cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
772cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_wlock)
773cae2ed9aSIngo Molnar 
774cae2ed9aSIngo Molnar #undef E1
775cae2ed9aSIngo Molnar #undef E2
776cae2ed9aSIngo Molnar #undef E3
777cae2ed9aSIngo Molnar 
778cae2ed9aSIngo Molnar /*
779cae2ed9aSIngo Molnar  * read-lock / write-lock irq inversion.
780cae2ed9aSIngo Molnar  *
781cae2ed9aSIngo Molnar  * Deadlock scenario:
782cae2ed9aSIngo Molnar  *
783cae2ed9aSIngo Molnar  * CPU#1 is at #1, i.e. it has write-locked A, but has not
784cae2ed9aSIngo Molnar  * taken B yet.
785cae2ed9aSIngo Molnar  *
786cae2ed9aSIngo Molnar  * CPU#2 is at #2, i.e. it has locked B.
787cae2ed9aSIngo Molnar  *
788cae2ed9aSIngo Molnar  * Hardirq hits CPU#2 at point #2 and is trying to read-lock A.
789cae2ed9aSIngo Molnar  *
790cae2ed9aSIngo Molnar  * The deadlock occurs because CPU#1 will spin on B, and CPU#2
791cae2ed9aSIngo Molnar  * will spin on A.
792cae2ed9aSIngo Molnar  */
793cae2ed9aSIngo Molnar 
794cae2ed9aSIngo Molnar #define E1()				\
795cae2ed9aSIngo Molnar 					\
796cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
797cae2ed9aSIngo Molnar 	WL(A);				\
798cae2ed9aSIngo Molnar 	LOCK(B);			\
799cae2ed9aSIngo Molnar 	UNLOCK(B);			\
800cae2ed9aSIngo Molnar 	WU(A);				\
801cae2ed9aSIngo Molnar 	IRQ_ENABLE();
802cae2ed9aSIngo Molnar 
803cae2ed9aSIngo Molnar #define E2()				\
804cae2ed9aSIngo Molnar 					\
805cae2ed9aSIngo Molnar 	LOCK(B);			\
806cae2ed9aSIngo Molnar 	UNLOCK(B);
807cae2ed9aSIngo Molnar 
808cae2ed9aSIngo Molnar #define E3()				\
809cae2ed9aSIngo Molnar 					\
810cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
811cae2ed9aSIngo Molnar 	RL(A);				\
812cae2ed9aSIngo Molnar 	RU(A);				\
813cae2ed9aSIngo Molnar 	IRQ_EXIT();
814cae2ed9aSIngo Molnar 
815cae2ed9aSIngo Molnar /*
816cae2ed9aSIngo Molnar  * Generate 36 testcases:
817cae2ed9aSIngo Molnar  */
818cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
819cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_spin)
820cae2ed9aSIngo Molnar 
821cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
822cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_rlock)
823cae2ed9aSIngo Molnar 
824cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
825cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_wlock)
826cae2ed9aSIngo Molnar 
827cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
828cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_spin)
829cae2ed9aSIngo Molnar 
830cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
831cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_rlock)
832cae2ed9aSIngo Molnar 
833cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
834cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_wlock)
835cae2ed9aSIngo Molnar 
836cae2ed9aSIngo Molnar #undef E1
837cae2ed9aSIngo Molnar #undef E2
838cae2ed9aSIngo Molnar #undef E3
839cae2ed9aSIngo Molnar 
840cae2ed9aSIngo Molnar /*
841cae2ed9aSIngo Molnar  * read-lock / write-lock recursion that is actually safe.
842cae2ed9aSIngo Molnar  */
843cae2ed9aSIngo Molnar 
844cae2ed9aSIngo Molnar #define E1()				\
845cae2ed9aSIngo Molnar 					\
846cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
847cae2ed9aSIngo Molnar 	WL(A);				\
848cae2ed9aSIngo Molnar 	WU(A);				\
849cae2ed9aSIngo Molnar 	IRQ_ENABLE();
850cae2ed9aSIngo Molnar 
851cae2ed9aSIngo Molnar #define E2()				\
852cae2ed9aSIngo Molnar 					\
853cae2ed9aSIngo Molnar 	RL(A);				\
854cae2ed9aSIngo Molnar 	RU(A);				\
855cae2ed9aSIngo Molnar 
856cae2ed9aSIngo Molnar #define E3()				\
857cae2ed9aSIngo Molnar 					\
858cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
859cae2ed9aSIngo Molnar 	RL(A);				\
860cae2ed9aSIngo Molnar 	L(B);				\
861cae2ed9aSIngo Molnar 	U(B);				\
862cae2ed9aSIngo Molnar 	RU(A);				\
863cae2ed9aSIngo Molnar 	IRQ_EXIT();
864cae2ed9aSIngo Molnar 
865cae2ed9aSIngo Molnar /*
866cae2ed9aSIngo Molnar  * Generate 12 testcases:
867cae2ed9aSIngo Molnar  */
868cae2ed9aSIngo Molnar #include "locking-selftest-hardirq.h"
869cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard)
870cae2ed9aSIngo Molnar 
871cae2ed9aSIngo Molnar #include "locking-selftest-softirq.h"
872cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft)
873cae2ed9aSIngo Molnar 
874cae2ed9aSIngo Molnar #undef E1
875cae2ed9aSIngo Molnar #undef E2
876cae2ed9aSIngo Molnar #undef E3
877cae2ed9aSIngo Molnar 
878cae2ed9aSIngo Molnar /*
879cae2ed9aSIngo Molnar  * read-lock / write-lock recursion that is unsafe.
880cae2ed9aSIngo Molnar  */
881cae2ed9aSIngo Molnar 
882cae2ed9aSIngo Molnar #define E1()				\
883cae2ed9aSIngo Molnar 					\
884cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
885cae2ed9aSIngo Molnar 	L(B);				\
886cae2ed9aSIngo Molnar 	WL(A);				\
887cae2ed9aSIngo Molnar 	WU(A);				\
888cae2ed9aSIngo Molnar 	U(B);				\
889cae2ed9aSIngo Molnar 	IRQ_ENABLE();
890cae2ed9aSIngo Molnar 
891cae2ed9aSIngo Molnar #define E2()				\
892cae2ed9aSIngo Molnar 					\
893cae2ed9aSIngo Molnar 	RL(A);				\
894cae2ed9aSIngo Molnar 	RU(A);				\
895cae2ed9aSIngo Molnar 
896cae2ed9aSIngo Molnar #define E3()				\
897cae2ed9aSIngo Molnar 					\
898cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
899cae2ed9aSIngo Molnar 	L(B);				\
900cae2ed9aSIngo Molnar 	U(B);				\
901cae2ed9aSIngo Molnar 	IRQ_EXIT();
902cae2ed9aSIngo Molnar 
903cae2ed9aSIngo Molnar /*
904cae2ed9aSIngo Molnar  * Generate 12 testcases:
905cae2ed9aSIngo Molnar  */
906cae2ed9aSIngo Molnar #include "locking-selftest-hardirq.h"
907cae2ed9aSIngo Molnar // GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard)
908cae2ed9aSIngo Molnar 
909cae2ed9aSIngo Molnar #include "locking-selftest-softirq.h"
910cae2ed9aSIngo Molnar // GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft)
911cae2ed9aSIngo Molnar 
912cae2ed9aSIngo Molnar #ifdef CONFIG_DEBUG_LOCK_ALLOC
913cae2ed9aSIngo Molnar # define I_SPINLOCK(x)	lockdep_reset_lock(&lock_##x.dep_map)
914cae2ed9aSIngo Molnar # define I_RWLOCK(x)	lockdep_reset_lock(&rwlock_##x.dep_map)
915cae2ed9aSIngo Molnar # define I_MUTEX(x)	lockdep_reset_lock(&mutex_##x.dep_map)
916cae2ed9aSIngo Molnar # define I_RWSEM(x)	lockdep_reset_lock(&rwsem_##x.dep_map)
9171de99445SMaarten Lankhorst # define I_WW(x)	lockdep_reset_lock(&x.dep_map)
918cae2ed9aSIngo Molnar #else
919cae2ed9aSIngo Molnar # define I_SPINLOCK(x)
920cae2ed9aSIngo Molnar # define I_RWLOCK(x)
921cae2ed9aSIngo Molnar # define I_MUTEX(x)
922cae2ed9aSIngo Molnar # define I_RWSEM(x)
9231de99445SMaarten Lankhorst # define I_WW(x)
924cae2ed9aSIngo Molnar #endif
925cae2ed9aSIngo Molnar 
926cae2ed9aSIngo Molnar #define I1(x)					\
927cae2ed9aSIngo Molnar 	do {					\
928cae2ed9aSIngo Molnar 		I_SPINLOCK(x);			\
929cae2ed9aSIngo Molnar 		I_RWLOCK(x);			\
930cae2ed9aSIngo Molnar 		I_MUTEX(x);			\
931cae2ed9aSIngo Molnar 		I_RWSEM(x);			\
932cae2ed9aSIngo Molnar 	} while (0)
933cae2ed9aSIngo Molnar 
934cae2ed9aSIngo Molnar #define I2(x)					\
935cae2ed9aSIngo Molnar 	do {					\
9369fb1b90cSYong Zhang 		raw_spin_lock_init(&lock_##x);	\
937cae2ed9aSIngo Molnar 		rwlock_init(&rwlock_##x);	\
938cae2ed9aSIngo Molnar 		mutex_init(&mutex_##x);		\
939cae2ed9aSIngo Molnar 		init_rwsem(&rwsem_##x);		\
940cae2ed9aSIngo Molnar 	} while (0)
941cae2ed9aSIngo Molnar 
942cae2ed9aSIngo Molnar static void reset_locks(void)
943cae2ed9aSIngo Molnar {
944cae2ed9aSIngo Molnar 	local_irq_disable();
9451de99445SMaarten Lankhorst 	lockdep_free_key_range(&ww_lockdep.acquire_key, 1);
9461de99445SMaarten Lankhorst 	lockdep_free_key_range(&ww_lockdep.mutex_key, 1);
9471de99445SMaarten Lankhorst 
948cae2ed9aSIngo Molnar 	I1(A); I1(B); I1(C); I1(D);
949cae2ed9aSIngo Molnar 	I1(X1); I1(X2); I1(Y1); I1(Y2); I1(Z1); I1(Z2);
950f3cf139eSMaarten Lankhorst 	I_WW(t); I_WW(t2); I_WW(o.base); I_WW(o2.base); I_WW(o3.base);
951cae2ed9aSIngo Molnar 	lockdep_reset();
952cae2ed9aSIngo Molnar 	I2(A); I2(B); I2(C); I2(D);
953cae2ed9aSIngo Molnar 	init_shared_classes();
9541de99445SMaarten Lankhorst 
955f3cf139eSMaarten Lankhorst 	ww_mutex_init(&o, &ww_lockdep); ww_mutex_init(&o2, &ww_lockdep); ww_mutex_init(&o3, &ww_lockdep);
9561de99445SMaarten Lankhorst 	memset(&t, 0, sizeof(t)); memset(&t2, 0, sizeof(t2));
9571de99445SMaarten Lankhorst 	memset(&ww_lockdep.acquire_key, 0, sizeof(ww_lockdep.acquire_key));
9581de99445SMaarten Lankhorst 	memset(&ww_lockdep.mutex_key, 0, sizeof(ww_lockdep.mutex_key));
959cae2ed9aSIngo Molnar 	local_irq_enable();
960cae2ed9aSIngo Molnar }
961cae2ed9aSIngo Molnar 
962cae2ed9aSIngo Molnar #undef I
963cae2ed9aSIngo Molnar 
964cae2ed9aSIngo Molnar static int testcase_total;
965cae2ed9aSIngo Molnar static int testcase_successes;
966cae2ed9aSIngo Molnar static int expected_testcase_failures;
967cae2ed9aSIngo Molnar static int unexpected_testcase_failures;
968cae2ed9aSIngo Molnar 
969cae2ed9aSIngo Molnar static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask)
970cae2ed9aSIngo Molnar {
971cae2ed9aSIngo Molnar 	unsigned long saved_preempt_count = preempt_count();
972cae2ed9aSIngo Molnar 
973cae2ed9aSIngo Molnar 	WARN_ON(irqs_disabled());
974cae2ed9aSIngo Molnar 
975cae2ed9aSIngo Molnar 	testcase_fn();
976cae2ed9aSIngo Molnar 	/*
977cae2ed9aSIngo Molnar 	 * Filter out expected failures:
978cae2ed9aSIngo Molnar 	 */
9791de99445SMaarten Lankhorst #ifndef CONFIG_PROVE_LOCKING
980*166989e3SMaarten Lankhorst 	if (expected == FAILURE && debug_locks) {
981cae2ed9aSIngo Molnar 		expected_testcase_failures++;
982cae2ed9aSIngo Molnar 		printk("failed|");
983*166989e3SMaarten Lankhorst 	}
984*166989e3SMaarten Lankhorst 	else
985*166989e3SMaarten Lankhorst #endif
986*166989e3SMaarten Lankhorst 	if (debug_locks != expected) {
987cae2ed9aSIngo Molnar 		unexpected_testcase_failures++;
988cae2ed9aSIngo Molnar 		printk("FAILED|");
9891de99445SMaarten Lankhorst 
9902ee91f19SIngo Molnar 		dump_stack();
991cae2ed9aSIngo Molnar 	} else {
992cae2ed9aSIngo Molnar 		testcase_successes++;
993cae2ed9aSIngo Molnar 		printk("  ok  |");
994cae2ed9aSIngo Molnar 	}
995cae2ed9aSIngo Molnar 	testcase_total++;
996cae2ed9aSIngo Molnar 
997cae2ed9aSIngo Molnar 	if (debug_locks_verbose)
998cae2ed9aSIngo Molnar 		printk(" lockclass mask: %x, debug_locks: %d, expected: %d\n",
999cae2ed9aSIngo Molnar 			lockclass_mask, debug_locks, expected);
1000cae2ed9aSIngo Molnar 	/*
1001cae2ed9aSIngo Molnar 	 * Some tests (e.g. double-unlock) might corrupt the preemption
1002cae2ed9aSIngo Molnar 	 * count, so restore it:
1003cae2ed9aSIngo Molnar 	 */
1004cae2ed9aSIngo Molnar 	preempt_count() = saved_preempt_count;
1005cae2ed9aSIngo Molnar #ifdef CONFIG_TRACE_IRQFLAGS
1006cae2ed9aSIngo Molnar 	if (softirq_count())
1007cae2ed9aSIngo Molnar 		current->softirqs_enabled = 0;
1008cae2ed9aSIngo Molnar 	else
1009cae2ed9aSIngo Molnar 		current->softirqs_enabled = 1;
1010cae2ed9aSIngo Molnar #endif
1011cae2ed9aSIngo Molnar 
1012cae2ed9aSIngo Molnar 	reset_locks();
1013cae2ed9aSIngo Molnar }
1014cae2ed9aSIngo Molnar 
1015cae2ed9aSIngo Molnar static inline void print_testname(const char *testname)
1016cae2ed9aSIngo Molnar {
1017cae2ed9aSIngo Molnar 	printk("%33s:", testname);
1018cae2ed9aSIngo Molnar }
1019cae2ed9aSIngo Molnar 
1020cae2ed9aSIngo Molnar #define DO_TESTCASE_1(desc, name, nr)				\
1021cae2ed9aSIngo Molnar 	print_testname(desc"/"#nr);				\
1022cae2ed9aSIngo Molnar 	dotest(name##_##nr, SUCCESS, LOCKTYPE_RWLOCK);		\
1023cae2ed9aSIngo Molnar 	printk("\n");
1024cae2ed9aSIngo Molnar 
1025cae2ed9aSIngo Molnar #define DO_TESTCASE_1B(desc, name, nr)				\
1026cae2ed9aSIngo Molnar 	print_testname(desc"/"#nr);				\
1027cae2ed9aSIngo Molnar 	dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK);		\
1028cae2ed9aSIngo Molnar 	printk("\n");
1029cae2ed9aSIngo Molnar 
1030cae2ed9aSIngo Molnar #define DO_TESTCASE_3(desc, name, nr)				\
1031cae2ed9aSIngo Molnar 	print_testname(desc"/"#nr);				\
1032cae2ed9aSIngo Molnar 	dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN);	\
1033cae2ed9aSIngo Molnar 	dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK);	\
1034cae2ed9aSIngo Molnar 	dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK);	\
1035cae2ed9aSIngo Molnar 	printk("\n");
1036cae2ed9aSIngo Molnar 
1037cae2ed9aSIngo Molnar #define DO_TESTCASE_3RW(desc, name, nr)				\
1038cae2ed9aSIngo Molnar 	print_testname(desc"/"#nr);				\
1039cae2ed9aSIngo Molnar 	dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN|LOCKTYPE_RWLOCK);\
1040cae2ed9aSIngo Molnar 	dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK);	\
1041cae2ed9aSIngo Molnar 	dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK);	\
1042cae2ed9aSIngo Molnar 	printk("\n");
1043cae2ed9aSIngo Molnar 
1044cae2ed9aSIngo Molnar #define DO_TESTCASE_6(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, FAILURE, 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_6_SUCCESS(desc, name)			\
1055cae2ed9aSIngo Molnar 	print_testname(desc);					\
1056cae2ed9aSIngo Molnar 	dotest(name##_spin, SUCCESS, LOCKTYPE_SPIN);		\
1057cae2ed9aSIngo Molnar 	dotest(name##_wlock, SUCCESS, LOCKTYPE_RWLOCK);		\
1058cae2ed9aSIngo Molnar 	dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK);		\
1059cae2ed9aSIngo Molnar 	dotest(name##_mutex, SUCCESS, LOCKTYPE_MUTEX);		\
1060cae2ed9aSIngo Molnar 	dotest(name##_wsem, SUCCESS, LOCKTYPE_RWSEM);		\
1061cae2ed9aSIngo Molnar 	dotest(name##_rsem, SUCCESS, LOCKTYPE_RWSEM);		\
1062cae2ed9aSIngo Molnar 	printk("\n");
1063cae2ed9aSIngo Molnar 
1064cae2ed9aSIngo Molnar /*
1065cae2ed9aSIngo Molnar  * 'read' variant: rlocks must not trigger.
1066cae2ed9aSIngo Molnar  */
1067cae2ed9aSIngo Molnar #define DO_TESTCASE_6R(desc, name)				\
1068cae2ed9aSIngo Molnar 	print_testname(desc);					\
1069cae2ed9aSIngo Molnar 	dotest(name##_spin, FAILURE, LOCKTYPE_SPIN);		\
1070cae2ed9aSIngo Molnar 	dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK);		\
1071cae2ed9aSIngo Molnar 	dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK);		\
1072cae2ed9aSIngo Molnar 	dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX);		\
1073cae2ed9aSIngo Molnar 	dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM);		\
1074cae2ed9aSIngo Molnar 	dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM);		\
1075cae2ed9aSIngo Molnar 	printk("\n");
1076cae2ed9aSIngo Molnar 
1077cae2ed9aSIngo Molnar #define DO_TESTCASE_2I(desc, name, nr)				\
1078cae2ed9aSIngo Molnar 	DO_TESTCASE_1("hard-"desc, name##_hard, nr);		\
1079cae2ed9aSIngo Molnar 	DO_TESTCASE_1("soft-"desc, name##_soft, nr);
1080cae2ed9aSIngo Molnar 
1081cae2ed9aSIngo Molnar #define DO_TESTCASE_2IB(desc, name, nr)				\
1082cae2ed9aSIngo Molnar 	DO_TESTCASE_1B("hard-"desc, name##_hard, nr);		\
1083cae2ed9aSIngo Molnar 	DO_TESTCASE_1B("soft-"desc, name##_soft, nr);
1084cae2ed9aSIngo Molnar 
1085cae2ed9aSIngo Molnar #define DO_TESTCASE_6I(desc, name, nr)				\
1086cae2ed9aSIngo Molnar 	DO_TESTCASE_3("hard-"desc, name##_hard, nr);		\
1087cae2ed9aSIngo Molnar 	DO_TESTCASE_3("soft-"desc, name##_soft, nr);
1088cae2ed9aSIngo Molnar 
1089cae2ed9aSIngo Molnar #define DO_TESTCASE_6IRW(desc, name, nr)			\
1090cae2ed9aSIngo Molnar 	DO_TESTCASE_3RW("hard-"desc, name##_hard, nr);		\
1091cae2ed9aSIngo Molnar 	DO_TESTCASE_3RW("soft-"desc, name##_soft, nr);
1092cae2ed9aSIngo Molnar 
1093cae2ed9aSIngo Molnar #define DO_TESTCASE_2x3(desc, name)				\
1094cae2ed9aSIngo Molnar 	DO_TESTCASE_3(desc, name, 12);				\
1095cae2ed9aSIngo Molnar 	DO_TESTCASE_3(desc, name, 21);
1096cae2ed9aSIngo Molnar 
1097cae2ed9aSIngo Molnar #define DO_TESTCASE_2x6(desc, name)				\
1098cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 12);				\
1099cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 21);
1100cae2ed9aSIngo Molnar 
1101cae2ed9aSIngo Molnar #define DO_TESTCASE_6x2(desc, name)				\
1102cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 123);			\
1103cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 132);			\
1104cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 213);			\
1105cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 231);			\
1106cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 312);			\
1107cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 321);
1108cae2ed9aSIngo Molnar 
1109cae2ed9aSIngo Molnar #define DO_TESTCASE_6x2B(desc, name)				\
1110cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 123);			\
1111cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 132);			\
1112cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 213);			\
1113cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 231);			\
1114cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 312);			\
1115cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 321);
1116cae2ed9aSIngo Molnar 
1117cae2ed9aSIngo Molnar #define DO_TESTCASE_6x6(desc, name)				\
1118cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 123);			\
1119cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 132);			\
1120cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 213);			\
1121cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 231);			\
1122cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 312);			\
1123cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 321);
1124cae2ed9aSIngo Molnar 
1125cae2ed9aSIngo Molnar #define DO_TESTCASE_6x6RW(desc, name)				\
1126cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 123);			\
1127cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 132);			\
1128cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 213);			\
1129cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 231);			\
1130cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 312);			\
1131cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 321);
1132cae2ed9aSIngo Molnar 
11331de99445SMaarten Lankhorst static void ww_test_fail_acquire(void)
11341de99445SMaarten Lankhorst {
11351de99445SMaarten Lankhorst 	int ret;
11361de99445SMaarten Lankhorst 
11371de99445SMaarten Lankhorst 	WWAI(&t);
11381de99445SMaarten Lankhorst 	t.stamp++;
11391de99445SMaarten Lankhorst 
11401de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
11411de99445SMaarten Lankhorst 
11421de99445SMaarten Lankhorst 	if (WARN_ON(!o.ctx) ||
11431de99445SMaarten Lankhorst 	    WARN_ON(ret))
11441de99445SMaarten Lankhorst 		return;
11451de99445SMaarten Lankhorst 
11461de99445SMaarten Lankhorst 	/* No lockdep test, pure API */
11471de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
11481de99445SMaarten Lankhorst 	WARN_ON(ret != -EALREADY);
11491de99445SMaarten Lankhorst 
11501de99445SMaarten Lankhorst 	ret = WWT(&o);
11511de99445SMaarten Lankhorst 	WARN_ON(ret);
11521de99445SMaarten Lankhorst 
11531de99445SMaarten Lankhorst 	t2 = t;
11541de99445SMaarten Lankhorst 	t2.stamp++;
11551de99445SMaarten Lankhorst 	ret = WWL(&o, &t2);
11561de99445SMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
11571de99445SMaarten Lankhorst 	WWU(&o);
11581de99445SMaarten Lankhorst 
11591de99445SMaarten Lankhorst 	if (WWT(&o))
11601de99445SMaarten Lankhorst 		WWU(&o);
11611de99445SMaarten Lankhorst #ifdef CONFIG_DEBUG_LOCK_ALLOC
11621de99445SMaarten Lankhorst 	else
11631de99445SMaarten Lankhorst 		DEBUG_LOCKS_WARN_ON(1);
11641de99445SMaarten Lankhorst #endif
11651de99445SMaarten Lankhorst }
11661de99445SMaarten Lankhorst 
11672fe3d4b1SMaarten Lankhorst static void ww_test_normal(void)
11682fe3d4b1SMaarten Lankhorst {
11692fe3d4b1SMaarten Lankhorst 	int ret;
11702fe3d4b1SMaarten Lankhorst 
11712fe3d4b1SMaarten Lankhorst 	WWAI(&t);
11722fe3d4b1SMaarten Lankhorst 
11732fe3d4b1SMaarten Lankhorst 	/*
11742fe3d4b1SMaarten Lankhorst 	 * None of the ww_mutex codepaths should be taken in the 'normal'
11752fe3d4b1SMaarten Lankhorst 	 * mutex calls. The easiest way to verify this is by using the
11762fe3d4b1SMaarten Lankhorst 	 * normal mutex calls, and making sure o.ctx is unmodified.
11772fe3d4b1SMaarten Lankhorst 	 */
11782fe3d4b1SMaarten Lankhorst 
11792fe3d4b1SMaarten Lankhorst 	/* mutex_lock (and indirectly, mutex_lock_nested) */
11802fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
11812fe3d4b1SMaarten Lankhorst 	mutex_lock(&o.base);
11822fe3d4b1SMaarten Lankhorst 	mutex_unlock(&o.base);
11832fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
11842fe3d4b1SMaarten Lankhorst 
11852fe3d4b1SMaarten Lankhorst 	/* mutex_lock_interruptible (and *_nested) */
11862fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
11872fe3d4b1SMaarten Lankhorst 	ret = mutex_lock_interruptible(&o.base);
11882fe3d4b1SMaarten Lankhorst 	if (!ret)
11892fe3d4b1SMaarten Lankhorst 		mutex_unlock(&o.base);
11902fe3d4b1SMaarten Lankhorst 	else
11912fe3d4b1SMaarten Lankhorst 		WARN_ON(1);
11922fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
11932fe3d4b1SMaarten Lankhorst 
11942fe3d4b1SMaarten Lankhorst 	/* mutex_lock_killable (and *_nested) */
11952fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
11962fe3d4b1SMaarten Lankhorst 	ret = mutex_lock_killable(&o.base);
11972fe3d4b1SMaarten Lankhorst 	if (!ret)
11982fe3d4b1SMaarten Lankhorst 		mutex_unlock(&o.base);
11992fe3d4b1SMaarten Lankhorst 	else
12002fe3d4b1SMaarten Lankhorst 		WARN_ON(1);
12012fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
12022fe3d4b1SMaarten Lankhorst 
12032fe3d4b1SMaarten Lankhorst 	/* trylock, succeeding */
12042fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
12052fe3d4b1SMaarten Lankhorst 	ret = mutex_trylock(&o.base);
12062fe3d4b1SMaarten Lankhorst 	WARN_ON(!ret);
12072fe3d4b1SMaarten Lankhorst 	if (ret)
12082fe3d4b1SMaarten Lankhorst 		mutex_unlock(&o.base);
12092fe3d4b1SMaarten Lankhorst 	else
12102fe3d4b1SMaarten Lankhorst 		WARN_ON(1);
12112fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
12122fe3d4b1SMaarten Lankhorst 
12132fe3d4b1SMaarten Lankhorst 	/* trylock, failing */
12142fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
12152fe3d4b1SMaarten Lankhorst 	mutex_lock(&o.base);
12162fe3d4b1SMaarten Lankhorst 	ret = mutex_trylock(&o.base);
12172fe3d4b1SMaarten Lankhorst 	WARN_ON(ret);
12182fe3d4b1SMaarten Lankhorst 	mutex_unlock(&o.base);
12192fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
12202fe3d4b1SMaarten Lankhorst 
12212fe3d4b1SMaarten Lankhorst 	/* nest_lock */
12222fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
12232fe3d4b1SMaarten Lankhorst 	mutex_lock_nest_lock(&o.base, &t);
12242fe3d4b1SMaarten Lankhorst 	mutex_unlock(&o.base);
12252fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
12262fe3d4b1SMaarten Lankhorst }
12272fe3d4b1SMaarten Lankhorst 
12281de99445SMaarten Lankhorst static void ww_test_two_contexts(void)
12291de99445SMaarten Lankhorst {
12301de99445SMaarten Lankhorst 	WWAI(&t);
12311de99445SMaarten Lankhorst 	WWAI(&t2);
12321de99445SMaarten Lankhorst }
12331de99445SMaarten Lankhorst 
12341de99445SMaarten Lankhorst static void ww_test_diff_class(void)
12351de99445SMaarten Lankhorst {
12361de99445SMaarten Lankhorst 	WWAI(&t);
12371de99445SMaarten Lankhorst #ifdef CONFIG_DEBUG_MUTEXES
12381de99445SMaarten Lankhorst 	t.ww_class = NULL;
12391de99445SMaarten Lankhorst #endif
12401de99445SMaarten Lankhorst 	WWL(&o, &t);
12411de99445SMaarten Lankhorst }
12421de99445SMaarten Lankhorst 
12431de99445SMaarten Lankhorst static void ww_test_context_done_twice(void)
12441de99445SMaarten Lankhorst {
12451de99445SMaarten Lankhorst 	WWAI(&t);
12461de99445SMaarten Lankhorst 	WWAD(&t);
12471de99445SMaarten Lankhorst 	WWAD(&t);
12481de99445SMaarten Lankhorst 	WWAF(&t);
12491de99445SMaarten Lankhorst }
12501de99445SMaarten Lankhorst 
12511de99445SMaarten Lankhorst static void ww_test_context_unlock_twice(void)
12521de99445SMaarten Lankhorst {
12531de99445SMaarten Lankhorst 	WWAI(&t);
12541de99445SMaarten Lankhorst 	WWAD(&t);
12551de99445SMaarten Lankhorst 	WWAF(&t);
12561de99445SMaarten Lankhorst 	WWAF(&t);
12571de99445SMaarten Lankhorst }
12581de99445SMaarten Lankhorst 
12591de99445SMaarten Lankhorst static void ww_test_context_fini_early(void)
12601de99445SMaarten Lankhorst {
12611de99445SMaarten Lankhorst 	WWAI(&t);
12621de99445SMaarten Lankhorst 	WWL(&o, &t);
12631de99445SMaarten Lankhorst 	WWAD(&t);
12641de99445SMaarten Lankhorst 	WWAF(&t);
12651de99445SMaarten Lankhorst }
12661de99445SMaarten Lankhorst 
12671de99445SMaarten Lankhorst static void ww_test_context_lock_after_done(void)
12681de99445SMaarten Lankhorst {
12691de99445SMaarten Lankhorst 	WWAI(&t);
12701de99445SMaarten Lankhorst 	WWAD(&t);
12711de99445SMaarten Lankhorst 	WWL(&o, &t);
12721de99445SMaarten Lankhorst }
12731de99445SMaarten Lankhorst 
12741de99445SMaarten Lankhorst static void ww_test_object_unlock_twice(void)
12751de99445SMaarten Lankhorst {
12761de99445SMaarten Lankhorst 	WWL1(&o);
12771de99445SMaarten Lankhorst 	WWU(&o);
12781de99445SMaarten Lankhorst 	WWU(&o);
12791de99445SMaarten Lankhorst }
12801de99445SMaarten Lankhorst 
12811de99445SMaarten Lankhorst static void ww_test_object_lock_unbalanced(void)
12821de99445SMaarten Lankhorst {
12831de99445SMaarten Lankhorst 	WWAI(&t);
12841de99445SMaarten Lankhorst 	WWL(&o, &t);
12851de99445SMaarten Lankhorst 	t.acquired = 0;
12861de99445SMaarten Lankhorst 	WWU(&o);
12871de99445SMaarten Lankhorst 	WWAF(&t);
12881de99445SMaarten Lankhorst }
12891de99445SMaarten Lankhorst 
12901de99445SMaarten Lankhorst static void ww_test_object_lock_stale_context(void)
12911de99445SMaarten Lankhorst {
12921de99445SMaarten Lankhorst 	WWAI(&t);
12931de99445SMaarten Lankhorst 	o.ctx = &t2;
12941de99445SMaarten Lankhorst 	WWL(&o, &t);
12951de99445SMaarten Lankhorst }
12961de99445SMaarten Lankhorst 
1297f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_normal(void)
1298f3cf139eSMaarten Lankhorst {
1299f3cf139eSMaarten Lankhorst 	int ret;
1300f3cf139eSMaarten Lankhorst 
1301f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
1302f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1303f3cf139eSMaarten Lankhorst 	mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1304f3cf139eSMaarten Lankhorst 
1305f3cf139eSMaarten Lankhorst 	WWAI(&t);
1306f3cf139eSMaarten Lankhorst 	t2 = t;
1307f3cf139eSMaarten Lankhorst 	t2.stamp--;
1308f3cf139eSMaarten Lankhorst 
1309f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1310f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1311f3cf139eSMaarten Lankhorst 
1312f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1313f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1314f3cf139eSMaarten Lankhorst 
1315f3cf139eSMaarten Lankhorst 	o2.ctx = NULL;
1316f3cf139eSMaarten Lankhorst 	mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
1317f3cf139eSMaarten Lankhorst 	mutex_unlock(&o2.base);
1318f3cf139eSMaarten Lankhorst 	WWU(&o);
1319f3cf139eSMaarten Lankhorst 
1320f3cf139eSMaarten Lankhorst 	WWL(&o2, &t);
1321f3cf139eSMaarten Lankhorst }
1322f3cf139eSMaarten Lankhorst 
1323f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_normal_slow(void)
1324f3cf139eSMaarten Lankhorst {
1325f3cf139eSMaarten Lankhorst 	int ret;
1326f3cf139eSMaarten Lankhorst 
1327f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
1328f3cf139eSMaarten Lankhorst 	mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1329f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1330f3cf139eSMaarten Lankhorst 
1331f3cf139eSMaarten Lankhorst 	WWAI(&t);
1332f3cf139eSMaarten Lankhorst 	t2 = t;
1333f3cf139eSMaarten Lankhorst 	t2.stamp--;
1334f3cf139eSMaarten Lankhorst 
1335f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1336f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1337f3cf139eSMaarten Lankhorst 
1338f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1339f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1340f3cf139eSMaarten Lankhorst 
1341f3cf139eSMaarten Lankhorst 	o2.ctx = NULL;
1342f3cf139eSMaarten Lankhorst 	mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
1343f3cf139eSMaarten Lankhorst 	mutex_unlock(&o2.base);
1344f3cf139eSMaarten Lankhorst 	WWU(&o);
1345f3cf139eSMaarten Lankhorst 
1346f3cf139eSMaarten Lankhorst 	ww_mutex_lock_slow(&o2, &t);
1347f3cf139eSMaarten Lankhorst }
1348f3cf139eSMaarten Lankhorst 
1349f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_no_unlock(void)
1350f3cf139eSMaarten Lankhorst {
1351f3cf139eSMaarten Lankhorst 	int ret;
1352f3cf139eSMaarten Lankhorst 
1353f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
1354f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1355f3cf139eSMaarten Lankhorst 	mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1356f3cf139eSMaarten Lankhorst 
1357f3cf139eSMaarten Lankhorst 	WWAI(&t);
1358f3cf139eSMaarten Lankhorst 	t2 = t;
1359f3cf139eSMaarten Lankhorst 	t2.stamp--;
1360f3cf139eSMaarten Lankhorst 
1361f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1362f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1363f3cf139eSMaarten Lankhorst 
1364f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1365f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1366f3cf139eSMaarten Lankhorst 
1367f3cf139eSMaarten Lankhorst 	o2.ctx = NULL;
1368f3cf139eSMaarten Lankhorst 	mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
1369f3cf139eSMaarten Lankhorst 	mutex_unlock(&o2.base);
1370f3cf139eSMaarten Lankhorst 
1371f3cf139eSMaarten Lankhorst 	WWL(&o2, &t);
1372f3cf139eSMaarten Lankhorst }
1373f3cf139eSMaarten Lankhorst 
1374f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_no_unlock_slow(void)
1375f3cf139eSMaarten Lankhorst {
1376f3cf139eSMaarten Lankhorst 	int ret;
1377f3cf139eSMaarten Lankhorst 
1378f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
1379f3cf139eSMaarten Lankhorst 	mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1380f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1381f3cf139eSMaarten Lankhorst 
1382f3cf139eSMaarten Lankhorst 	WWAI(&t);
1383f3cf139eSMaarten Lankhorst 	t2 = t;
1384f3cf139eSMaarten Lankhorst 	t2.stamp--;
1385f3cf139eSMaarten Lankhorst 
1386f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1387f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1388f3cf139eSMaarten Lankhorst 
1389f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1390f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1391f3cf139eSMaarten Lankhorst 
1392f3cf139eSMaarten Lankhorst 	o2.ctx = NULL;
1393f3cf139eSMaarten Lankhorst 	mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
1394f3cf139eSMaarten Lankhorst 	mutex_unlock(&o2.base);
1395f3cf139eSMaarten Lankhorst 
1396f3cf139eSMaarten Lankhorst 	ww_mutex_lock_slow(&o2, &t);
1397f3cf139eSMaarten Lankhorst }
1398f3cf139eSMaarten Lankhorst 
1399f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_more(void)
1400f3cf139eSMaarten Lankhorst {
1401f3cf139eSMaarten Lankhorst 	int ret;
1402f3cf139eSMaarten Lankhorst 
1403f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
1404f3cf139eSMaarten Lankhorst 	mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1405f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1406f3cf139eSMaarten Lankhorst 
1407f3cf139eSMaarten Lankhorst 	WWAI(&t);
1408f3cf139eSMaarten Lankhorst 	t2 = t;
1409f3cf139eSMaarten Lankhorst 	t2.stamp--;
1410f3cf139eSMaarten Lankhorst 
1411f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1412f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1413f3cf139eSMaarten Lankhorst 
1414f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1415f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1416f3cf139eSMaarten Lankhorst 
1417f3cf139eSMaarten Lankhorst 	ret = WWL(&o3, &t);
1418f3cf139eSMaarten Lankhorst }
1419f3cf139eSMaarten Lankhorst 
1420f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_more_slow(void)
1421f3cf139eSMaarten Lankhorst {
1422f3cf139eSMaarten Lankhorst 	int ret;
1423f3cf139eSMaarten Lankhorst 
1424f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
1425f3cf139eSMaarten Lankhorst 	mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1426f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1427f3cf139eSMaarten Lankhorst 
1428f3cf139eSMaarten Lankhorst 	WWAI(&t);
1429f3cf139eSMaarten Lankhorst 	t2 = t;
1430f3cf139eSMaarten Lankhorst 	t2.stamp--;
1431f3cf139eSMaarten Lankhorst 
1432f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1433f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1434f3cf139eSMaarten Lankhorst 
1435f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1436f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1437f3cf139eSMaarten Lankhorst 
1438f3cf139eSMaarten Lankhorst 	ww_mutex_lock_slow(&o3, &t);
1439f3cf139eSMaarten Lankhorst }
1440f3cf139eSMaarten Lankhorst 
1441f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_more_edeadlk(void)
1442f3cf139eSMaarten Lankhorst {
1443f3cf139eSMaarten Lankhorst 	int ret;
1444f3cf139eSMaarten Lankhorst 
1445f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
1446f3cf139eSMaarten Lankhorst 	mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1447f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1448f3cf139eSMaarten Lankhorst 
1449f3cf139eSMaarten Lankhorst 	mutex_lock(&o3.base);
1450f3cf139eSMaarten Lankhorst 	mutex_release(&o3.base.dep_map, 1, _THIS_IP_);
1451f3cf139eSMaarten Lankhorst 	o3.ctx = &t2;
1452f3cf139eSMaarten Lankhorst 
1453f3cf139eSMaarten Lankhorst 	WWAI(&t);
1454f3cf139eSMaarten Lankhorst 	t2 = t;
1455f3cf139eSMaarten Lankhorst 	t2.stamp--;
1456f3cf139eSMaarten Lankhorst 
1457f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1458f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1459f3cf139eSMaarten Lankhorst 
1460f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1461f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1462f3cf139eSMaarten Lankhorst 
1463f3cf139eSMaarten Lankhorst 	ret = WWL(&o3, &t);
1464f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1465f3cf139eSMaarten Lankhorst }
1466f3cf139eSMaarten Lankhorst 
1467f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_more_edeadlk_slow(void)
1468f3cf139eSMaarten Lankhorst {
1469f3cf139eSMaarten Lankhorst 	int ret;
1470f3cf139eSMaarten Lankhorst 
1471f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
1472f3cf139eSMaarten Lankhorst 	mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1473f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1474f3cf139eSMaarten Lankhorst 
1475f3cf139eSMaarten Lankhorst 	mutex_lock(&o3.base);
1476f3cf139eSMaarten Lankhorst 	mutex_release(&o3.base.dep_map, 1, _THIS_IP_);
1477f3cf139eSMaarten Lankhorst 	o3.ctx = &t2;
1478f3cf139eSMaarten Lankhorst 
1479f3cf139eSMaarten Lankhorst 	WWAI(&t);
1480f3cf139eSMaarten Lankhorst 	t2 = t;
1481f3cf139eSMaarten Lankhorst 	t2.stamp--;
1482f3cf139eSMaarten Lankhorst 
1483f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1484f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1485f3cf139eSMaarten Lankhorst 
1486f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1487f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1488f3cf139eSMaarten Lankhorst 
1489f3cf139eSMaarten Lankhorst 	ww_mutex_lock_slow(&o3, &t);
1490f3cf139eSMaarten Lankhorst }
1491f3cf139eSMaarten Lankhorst 
1492f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_wrong(void)
1493f3cf139eSMaarten Lankhorst {
1494f3cf139eSMaarten Lankhorst 	int ret;
1495f3cf139eSMaarten Lankhorst 
1496f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
1497f3cf139eSMaarten Lankhorst 	mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1498f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1499f3cf139eSMaarten Lankhorst 
1500f3cf139eSMaarten Lankhorst 	WWAI(&t);
1501f3cf139eSMaarten Lankhorst 	t2 = t;
1502f3cf139eSMaarten Lankhorst 	t2.stamp--;
1503f3cf139eSMaarten Lankhorst 
1504f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1505f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1506f3cf139eSMaarten Lankhorst 
1507f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1508f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1509f3cf139eSMaarten Lankhorst 	if (!ret)
1510f3cf139eSMaarten Lankhorst 		WWU(&o2);
1511f3cf139eSMaarten Lankhorst 
1512f3cf139eSMaarten Lankhorst 	WWU(&o);
1513f3cf139eSMaarten Lankhorst 
1514f3cf139eSMaarten Lankhorst 	ret = WWL(&o3, &t);
1515f3cf139eSMaarten Lankhorst }
1516f3cf139eSMaarten Lankhorst 
1517f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_wrong_slow(void)
1518f3cf139eSMaarten Lankhorst {
1519f3cf139eSMaarten Lankhorst 	int ret;
1520f3cf139eSMaarten Lankhorst 
1521f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
1522f3cf139eSMaarten Lankhorst 	mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1523f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1524f3cf139eSMaarten Lankhorst 
1525f3cf139eSMaarten Lankhorst 	WWAI(&t);
1526f3cf139eSMaarten Lankhorst 	t2 = t;
1527f3cf139eSMaarten Lankhorst 	t2.stamp--;
1528f3cf139eSMaarten Lankhorst 
1529f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1530f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1531f3cf139eSMaarten Lankhorst 
1532f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1533f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1534f3cf139eSMaarten Lankhorst 	if (!ret)
1535f3cf139eSMaarten Lankhorst 		WWU(&o2);
1536f3cf139eSMaarten Lankhorst 
1537f3cf139eSMaarten Lankhorst 	WWU(&o);
1538f3cf139eSMaarten Lankhorst 
1539f3cf139eSMaarten Lankhorst 	ww_mutex_lock_slow(&o3, &t);
1540f3cf139eSMaarten Lankhorst }
1541f3cf139eSMaarten Lankhorst 
15421de99445SMaarten Lankhorst static void ww_test_spin_nest_unlocked(void)
15431de99445SMaarten Lankhorst {
15441de99445SMaarten Lankhorst 	raw_spin_lock_nest_lock(&lock_A, &o.base);
15451de99445SMaarten Lankhorst 	U(A);
15461de99445SMaarten Lankhorst }
15471de99445SMaarten Lankhorst 
15481de99445SMaarten Lankhorst static void ww_test_unneeded_slow(void)
15491de99445SMaarten Lankhorst {
15501de99445SMaarten Lankhorst 	WWAI(&t);
15511de99445SMaarten Lankhorst 
15521de99445SMaarten Lankhorst 	ww_mutex_lock_slow(&o, &t);
15531de99445SMaarten Lankhorst }
15541de99445SMaarten Lankhorst 
15551de99445SMaarten Lankhorst static void ww_test_context_block(void)
15561de99445SMaarten Lankhorst {
15571de99445SMaarten Lankhorst 	int ret;
15581de99445SMaarten Lankhorst 
15591de99445SMaarten Lankhorst 	WWAI(&t);
15601de99445SMaarten Lankhorst 
15611de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
15621de99445SMaarten Lankhorst 	WARN_ON(ret);
15631de99445SMaarten Lankhorst 	WWL1(&o2);
15641de99445SMaarten Lankhorst }
15651de99445SMaarten Lankhorst 
15661de99445SMaarten Lankhorst static void ww_test_context_try(void)
15671de99445SMaarten Lankhorst {
15681de99445SMaarten Lankhorst 	int ret;
15691de99445SMaarten Lankhorst 
15701de99445SMaarten Lankhorst 	WWAI(&t);
15711de99445SMaarten Lankhorst 
15721de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
15731de99445SMaarten Lankhorst 	WARN_ON(ret);
15741de99445SMaarten Lankhorst 
15751de99445SMaarten Lankhorst 	ret = WWT(&o2);
15761de99445SMaarten Lankhorst 	WARN_ON(!ret);
15771de99445SMaarten Lankhorst 	WWU(&o2);
15781de99445SMaarten Lankhorst 	WWU(&o);
15791de99445SMaarten Lankhorst }
15801de99445SMaarten Lankhorst 
15811de99445SMaarten Lankhorst static void ww_test_context_context(void)
15821de99445SMaarten Lankhorst {
15831de99445SMaarten Lankhorst 	int ret;
15841de99445SMaarten Lankhorst 
15851de99445SMaarten Lankhorst 	WWAI(&t);
15861de99445SMaarten Lankhorst 
15871de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
15881de99445SMaarten Lankhorst 	WARN_ON(ret);
15891de99445SMaarten Lankhorst 
15901de99445SMaarten Lankhorst 	ret = WWL(&o2, &t);
15911de99445SMaarten Lankhorst 	WARN_ON(ret);
15921de99445SMaarten Lankhorst 
15931de99445SMaarten Lankhorst 	WWU(&o2);
15941de99445SMaarten Lankhorst 	WWU(&o);
15951de99445SMaarten Lankhorst }
15961de99445SMaarten Lankhorst 
15971de99445SMaarten Lankhorst static void ww_test_try_block(void)
15981de99445SMaarten Lankhorst {
15991de99445SMaarten Lankhorst 	bool ret;
16001de99445SMaarten Lankhorst 
16011de99445SMaarten Lankhorst 	ret = WWT(&o);
16021de99445SMaarten Lankhorst 	WARN_ON(!ret);
16031de99445SMaarten Lankhorst 
16041de99445SMaarten Lankhorst 	WWL1(&o2);
16051de99445SMaarten Lankhorst 	WWU(&o2);
16061de99445SMaarten Lankhorst 	WWU(&o);
16071de99445SMaarten Lankhorst }
16081de99445SMaarten Lankhorst 
16091de99445SMaarten Lankhorst static void ww_test_try_try(void)
16101de99445SMaarten Lankhorst {
16111de99445SMaarten Lankhorst 	bool ret;
16121de99445SMaarten Lankhorst 
16131de99445SMaarten Lankhorst 	ret = WWT(&o);
16141de99445SMaarten Lankhorst 	WARN_ON(!ret);
16151de99445SMaarten Lankhorst 	ret = WWT(&o2);
16161de99445SMaarten Lankhorst 	WARN_ON(!ret);
16171de99445SMaarten Lankhorst 	WWU(&o2);
16181de99445SMaarten Lankhorst 	WWU(&o);
16191de99445SMaarten Lankhorst }
16201de99445SMaarten Lankhorst 
16211de99445SMaarten Lankhorst static void ww_test_try_context(void)
16221de99445SMaarten Lankhorst {
16231de99445SMaarten Lankhorst 	int ret;
16241de99445SMaarten Lankhorst 
16251de99445SMaarten Lankhorst 	ret = WWT(&o);
16261de99445SMaarten Lankhorst 	WARN_ON(!ret);
16271de99445SMaarten Lankhorst 
16281de99445SMaarten Lankhorst 	WWAI(&t);
16291de99445SMaarten Lankhorst 
16301de99445SMaarten Lankhorst 	ret = WWL(&o2, &t);
16311de99445SMaarten Lankhorst 	WARN_ON(ret);
16321de99445SMaarten Lankhorst }
16331de99445SMaarten Lankhorst 
16341de99445SMaarten Lankhorst static void ww_test_block_block(void)
16351de99445SMaarten Lankhorst {
16361de99445SMaarten Lankhorst 	WWL1(&o);
16371de99445SMaarten Lankhorst 	WWL1(&o2);
16381de99445SMaarten Lankhorst }
16391de99445SMaarten Lankhorst 
16401de99445SMaarten Lankhorst static void ww_test_block_try(void)
16411de99445SMaarten Lankhorst {
16421de99445SMaarten Lankhorst 	bool ret;
16431de99445SMaarten Lankhorst 
16441de99445SMaarten Lankhorst 	WWL1(&o);
16451de99445SMaarten Lankhorst 	ret = WWT(&o2);
16461de99445SMaarten Lankhorst 	WARN_ON(!ret);
16471de99445SMaarten Lankhorst }
16481de99445SMaarten Lankhorst 
16491de99445SMaarten Lankhorst static void ww_test_block_context(void)
16501de99445SMaarten Lankhorst {
16511de99445SMaarten Lankhorst 	int ret;
16521de99445SMaarten Lankhorst 
16531de99445SMaarten Lankhorst 	WWL1(&o);
16541de99445SMaarten Lankhorst 	WWAI(&t);
16551de99445SMaarten Lankhorst 
16561de99445SMaarten Lankhorst 	ret = WWL(&o2, &t);
16571de99445SMaarten Lankhorst 	WARN_ON(ret);
16581de99445SMaarten Lankhorst }
16591de99445SMaarten Lankhorst 
16601de99445SMaarten Lankhorst static void ww_test_spin_block(void)
16611de99445SMaarten Lankhorst {
16621de99445SMaarten Lankhorst 	L(A);
16631de99445SMaarten Lankhorst 	U(A);
16641de99445SMaarten Lankhorst 
16651de99445SMaarten Lankhorst 	WWL1(&o);
16661de99445SMaarten Lankhorst 	L(A);
16671de99445SMaarten Lankhorst 	U(A);
16681de99445SMaarten Lankhorst 	WWU(&o);
16691de99445SMaarten Lankhorst 
16701de99445SMaarten Lankhorst 	L(A);
16711de99445SMaarten Lankhorst 	WWL1(&o);
16721de99445SMaarten Lankhorst 	WWU(&o);
16731de99445SMaarten Lankhorst 	U(A);
16741de99445SMaarten Lankhorst }
16751de99445SMaarten Lankhorst 
16761de99445SMaarten Lankhorst static void ww_test_spin_try(void)
16771de99445SMaarten Lankhorst {
16781de99445SMaarten Lankhorst 	bool ret;
16791de99445SMaarten Lankhorst 
16801de99445SMaarten Lankhorst 	L(A);
16811de99445SMaarten Lankhorst 	U(A);
16821de99445SMaarten Lankhorst 
16831de99445SMaarten Lankhorst 	ret = WWT(&o);
16841de99445SMaarten Lankhorst 	WARN_ON(!ret);
16851de99445SMaarten Lankhorst 	L(A);
16861de99445SMaarten Lankhorst 	U(A);
16871de99445SMaarten Lankhorst 	WWU(&o);
16881de99445SMaarten Lankhorst 
16891de99445SMaarten Lankhorst 	L(A);
16901de99445SMaarten Lankhorst 	ret = WWT(&o);
16911de99445SMaarten Lankhorst 	WARN_ON(!ret);
16921de99445SMaarten Lankhorst 	WWU(&o);
16931de99445SMaarten Lankhorst 	U(A);
16941de99445SMaarten Lankhorst }
16951de99445SMaarten Lankhorst 
16961de99445SMaarten Lankhorst static void ww_test_spin_context(void)
16971de99445SMaarten Lankhorst {
16981de99445SMaarten Lankhorst 	int ret;
16991de99445SMaarten Lankhorst 
17001de99445SMaarten Lankhorst 	L(A);
17011de99445SMaarten Lankhorst 	U(A);
17021de99445SMaarten Lankhorst 
17031de99445SMaarten Lankhorst 	WWAI(&t);
17041de99445SMaarten Lankhorst 
17051de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
17061de99445SMaarten Lankhorst 	WARN_ON(ret);
17071de99445SMaarten Lankhorst 	L(A);
17081de99445SMaarten Lankhorst 	U(A);
17091de99445SMaarten Lankhorst 	WWU(&o);
17101de99445SMaarten Lankhorst 
17111de99445SMaarten Lankhorst 	L(A);
17121de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
17131de99445SMaarten Lankhorst 	WARN_ON(ret);
17141de99445SMaarten Lankhorst 	WWU(&o);
17151de99445SMaarten Lankhorst 	U(A);
17161de99445SMaarten Lankhorst }
17171de99445SMaarten Lankhorst 
17181de99445SMaarten Lankhorst static void ww_tests(void)
17191de99445SMaarten Lankhorst {
17201de99445SMaarten Lankhorst 	printk("  --------------------------------------------------------------------------\n");
17211de99445SMaarten Lankhorst 	printk("  | Wound/wait tests |\n");
17221de99445SMaarten Lankhorst 	printk("  ---------------------\n");
17231de99445SMaarten Lankhorst 
17241de99445SMaarten Lankhorst 	print_testname("ww api failures");
17251de99445SMaarten Lankhorst 	dotest(ww_test_fail_acquire, SUCCESS, LOCKTYPE_WW);
17262fe3d4b1SMaarten Lankhorst 	dotest(ww_test_normal, SUCCESS, LOCKTYPE_WW);
17271de99445SMaarten Lankhorst 	dotest(ww_test_unneeded_slow, FAILURE, LOCKTYPE_WW);
17281de99445SMaarten Lankhorst 	printk("\n");
17291de99445SMaarten Lankhorst 
17301de99445SMaarten Lankhorst 	print_testname("ww contexts mixing");
17311de99445SMaarten Lankhorst 	dotest(ww_test_two_contexts, FAILURE, LOCKTYPE_WW);
17321de99445SMaarten Lankhorst 	dotest(ww_test_diff_class, FAILURE, LOCKTYPE_WW);
17331de99445SMaarten Lankhorst 	printk("\n");
17341de99445SMaarten Lankhorst 
17351de99445SMaarten Lankhorst 	print_testname("finishing ww context");
17361de99445SMaarten Lankhorst 	dotest(ww_test_context_done_twice, FAILURE, LOCKTYPE_WW);
17371de99445SMaarten Lankhorst 	dotest(ww_test_context_unlock_twice, FAILURE, LOCKTYPE_WW);
17381de99445SMaarten Lankhorst 	dotest(ww_test_context_fini_early, FAILURE, LOCKTYPE_WW);
17391de99445SMaarten Lankhorst 	dotest(ww_test_context_lock_after_done, FAILURE, LOCKTYPE_WW);
17401de99445SMaarten Lankhorst 	printk("\n");
17411de99445SMaarten Lankhorst 
17421de99445SMaarten Lankhorst 	print_testname("locking mismatches");
17431de99445SMaarten Lankhorst 	dotest(ww_test_object_unlock_twice, FAILURE, LOCKTYPE_WW);
17441de99445SMaarten Lankhorst 	dotest(ww_test_object_lock_unbalanced, FAILURE, LOCKTYPE_WW);
17451de99445SMaarten Lankhorst 	dotest(ww_test_object_lock_stale_context, FAILURE, LOCKTYPE_WW);
17461de99445SMaarten Lankhorst 	printk("\n");
17471de99445SMaarten Lankhorst 
1748f3cf139eSMaarten Lankhorst 	print_testname("EDEADLK handling");
1749f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_normal, SUCCESS, LOCKTYPE_WW);
1750f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_normal_slow, SUCCESS, LOCKTYPE_WW);
1751f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_no_unlock, FAILURE, LOCKTYPE_WW);
1752f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_no_unlock_slow, FAILURE, LOCKTYPE_WW);
1753f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_more, FAILURE, LOCKTYPE_WW);
1754f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_more_slow, FAILURE, LOCKTYPE_WW);
1755f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_more_edeadlk, FAILURE, LOCKTYPE_WW);
1756f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_more_edeadlk_slow, FAILURE, LOCKTYPE_WW);
1757f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_wrong, FAILURE, LOCKTYPE_WW);
1758f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_wrong_slow, FAILURE, LOCKTYPE_WW);
1759f3cf139eSMaarten Lankhorst 	printk("\n");
1760f3cf139eSMaarten Lankhorst 
17611de99445SMaarten Lankhorst 	print_testname("spinlock nest unlocked");
17621de99445SMaarten Lankhorst 	dotest(ww_test_spin_nest_unlocked, FAILURE, LOCKTYPE_WW);
17631de99445SMaarten Lankhorst 	printk("\n");
17641de99445SMaarten Lankhorst 
17651de99445SMaarten Lankhorst 	printk("  -----------------------------------------------------\n");
17661de99445SMaarten Lankhorst 	printk("                                 |block | try  |context|\n");
17671de99445SMaarten Lankhorst 	printk("  -----------------------------------------------------\n");
17681de99445SMaarten Lankhorst 
17691de99445SMaarten Lankhorst 	print_testname("context");
17701de99445SMaarten Lankhorst 	dotest(ww_test_context_block, FAILURE, LOCKTYPE_WW);
17711de99445SMaarten Lankhorst 	dotest(ww_test_context_try, SUCCESS, LOCKTYPE_WW);
17721de99445SMaarten Lankhorst 	dotest(ww_test_context_context, SUCCESS, LOCKTYPE_WW);
17731de99445SMaarten Lankhorst 	printk("\n");
17741de99445SMaarten Lankhorst 
17751de99445SMaarten Lankhorst 	print_testname("try");
17761de99445SMaarten Lankhorst 	dotest(ww_test_try_block, FAILURE, LOCKTYPE_WW);
17771de99445SMaarten Lankhorst 	dotest(ww_test_try_try, SUCCESS, LOCKTYPE_WW);
17781de99445SMaarten Lankhorst 	dotest(ww_test_try_context, FAILURE, LOCKTYPE_WW);
17791de99445SMaarten Lankhorst 	printk("\n");
17801de99445SMaarten Lankhorst 
17811de99445SMaarten Lankhorst 	print_testname("block");
17821de99445SMaarten Lankhorst 	dotest(ww_test_block_block, FAILURE, LOCKTYPE_WW);
17831de99445SMaarten Lankhorst 	dotest(ww_test_block_try, SUCCESS, LOCKTYPE_WW);
17841de99445SMaarten Lankhorst 	dotest(ww_test_block_context, FAILURE, LOCKTYPE_WW);
17851de99445SMaarten Lankhorst 	printk("\n");
17861de99445SMaarten Lankhorst 
17871de99445SMaarten Lankhorst 	print_testname("spinlock");
17881de99445SMaarten Lankhorst 	dotest(ww_test_spin_block, FAILURE, LOCKTYPE_WW);
17891de99445SMaarten Lankhorst 	dotest(ww_test_spin_try, SUCCESS, LOCKTYPE_WW);
17901de99445SMaarten Lankhorst 	dotest(ww_test_spin_context, FAILURE, LOCKTYPE_WW);
17911de99445SMaarten Lankhorst 	printk("\n");
17921de99445SMaarten Lankhorst }
1793cae2ed9aSIngo Molnar 
1794cae2ed9aSIngo Molnar void locking_selftest(void)
1795cae2ed9aSIngo Molnar {
1796cae2ed9aSIngo Molnar 	/*
1797cae2ed9aSIngo Molnar 	 * Got a locking failure before the selftest ran?
1798cae2ed9aSIngo Molnar 	 */
1799cae2ed9aSIngo Molnar 	if (!debug_locks) {
1800cae2ed9aSIngo Molnar 		printk("----------------------------------\n");
1801cae2ed9aSIngo Molnar 		printk("| Locking API testsuite disabled |\n");
1802cae2ed9aSIngo Molnar 		printk("----------------------------------\n");
1803cae2ed9aSIngo Molnar 		return;
1804cae2ed9aSIngo Molnar 	}
1805cae2ed9aSIngo Molnar 
1806cae2ed9aSIngo Molnar 	/*
1807cae2ed9aSIngo Molnar 	 * Run the testsuite:
1808cae2ed9aSIngo Molnar 	 */
1809cae2ed9aSIngo Molnar 	printk("------------------------\n");
1810cae2ed9aSIngo Molnar 	printk("| Locking API testsuite:\n");
1811cae2ed9aSIngo Molnar 	printk("----------------------------------------------------------------------------\n");
1812cae2ed9aSIngo Molnar 	printk("                                 | spin |wlock |rlock |mutex | wsem | rsem |\n");
1813cae2ed9aSIngo Molnar 	printk("  --------------------------------------------------------------------------\n");
1814cae2ed9aSIngo Molnar 
1815cae2ed9aSIngo Molnar 	init_shared_classes();
1816cae2ed9aSIngo Molnar 	debug_locks_silent = !debug_locks_verbose;
1817cae2ed9aSIngo Molnar 
18186c9076ecSIngo Molnar 	DO_TESTCASE_6R("A-A deadlock", AA);
1819cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-B-A deadlock", ABBA);
1820cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-B-C-C-A deadlock", ABBCCA);
1821cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-C-A-B-C deadlock", ABCABC);
1822cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-B-C-C-D-D-A deadlock", ABBCCDDA);
1823cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-C-D-B-D-D-A deadlock", ABCDBDDA);
1824cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-C-D-B-C-D-A deadlock", ABCDBCDA);
1825cae2ed9aSIngo Molnar 	DO_TESTCASE_6("double unlock", double_unlock);
1826cae2ed9aSIngo Molnar 	DO_TESTCASE_6("initialize held", init_held);
1827cae2ed9aSIngo Molnar 	DO_TESTCASE_6_SUCCESS("bad unlock order", bad_unlock_order);
1828cae2ed9aSIngo Molnar 
1829cae2ed9aSIngo Molnar 	printk("  --------------------------------------------------------------------------\n");
1830cae2ed9aSIngo Molnar 	print_testname("recursive read-lock");
1831cae2ed9aSIngo Molnar 	printk("             |");
1832cae2ed9aSIngo Molnar 	dotest(rlock_AA1, SUCCESS, LOCKTYPE_RWLOCK);
1833cae2ed9aSIngo Molnar 	printk("             |");
1834cae2ed9aSIngo Molnar 	dotest(rsem_AA1, FAILURE, LOCKTYPE_RWSEM);
1835cae2ed9aSIngo Molnar 	printk("\n");
1836cae2ed9aSIngo Molnar 
1837cae2ed9aSIngo Molnar 	print_testname("recursive read-lock #2");
1838cae2ed9aSIngo Molnar 	printk("             |");
18396c9076ecSIngo Molnar 	dotest(rlock_AA1B, SUCCESS, LOCKTYPE_RWLOCK);
1840cae2ed9aSIngo Molnar 	printk("             |");
1841cae2ed9aSIngo Molnar 	dotest(rsem_AA1B, FAILURE, LOCKTYPE_RWSEM);
1842cae2ed9aSIngo Molnar 	printk("\n");
1843cae2ed9aSIngo Molnar 
1844cae2ed9aSIngo Molnar 	print_testname("mixed read-write-lock");
1845cae2ed9aSIngo Molnar 	printk("             |");
1846cae2ed9aSIngo Molnar 	dotest(rlock_AA2, FAILURE, LOCKTYPE_RWLOCK);
1847cae2ed9aSIngo Molnar 	printk("             |");
1848cae2ed9aSIngo Molnar 	dotest(rsem_AA2, FAILURE, LOCKTYPE_RWSEM);
1849cae2ed9aSIngo Molnar 	printk("\n");
1850cae2ed9aSIngo Molnar 
1851cae2ed9aSIngo Molnar 	print_testname("mixed write-read-lock");
1852cae2ed9aSIngo Molnar 	printk("             |");
1853cae2ed9aSIngo Molnar 	dotest(rlock_AA3, FAILURE, LOCKTYPE_RWLOCK);
1854cae2ed9aSIngo Molnar 	printk("             |");
1855cae2ed9aSIngo Molnar 	dotest(rsem_AA3, FAILURE, LOCKTYPE_RWSEM);
1856cae2ed9aSIngo Molnar 	printk("\n");
1857cae2ed9aSIngo Molnar 
1858cae2ed9aSIngo Molnar 	printk("  --------------------------------------------------------------------------\n");
1859cae2ed9aSIngo Molnar 
1860cae2ed9aSIngo Molnar 	/*
1861cae2ed9aSIngo Molnar 	 * irq-context testcases:
1862cae2ed9aSIngo Molnar 	 */
1863cae2ed9aSIngo Molnar 	DO_TESTCASE_2x6("irqs-on + irq-safe-A", irqsafe1);
1864cae2ed9aSIngo Molnar 	DO_TESTCASE_2x3("sirq-safe-A => hirqs-on", irqsafe2A);
1865cae2ed9aSIngo Molnar 	DO_TESTCASE_2x6("safe-A + irqs-on", irqsafe2B);
1866cae2ed9aSIngo Molnar 	DO_TESTCASE_6x6("safe-A + unsafe-B #1", irqsafe3);
1867cae2ed9aSIngo Molnar 	DO_TESTCASE_6x6("safe-A + unsafe-B #2", irqsafe4);
1868cae2ed9aSIngo Molnar 	DO_TESTCASE_6x6RW("irq lock-inversion", irq_inversion);
1869cae2ed9aSIngo Molnar 
1870cae2ed9aSIngo Molnar 	DO_TESTCASE_6x2("irq read-recursion", irq_read_recursion);
1871cae2ed9aSIngo Molnar //	DO_TESTCASE_6x2B("irq read-recursion #2", irq_read_recursion2);
1872cae2ed9aSIngo Molnar 
18731de99445SMaarten Lankhorst 	ww_tests();
18741de99445SMaarten Lankhorst 
1875cae2ed9aSIngo Molnar 	if (unexpected_testcase_failures) {
1876cae2ed9aSIngo Molnar 		printk("-----------------------------------------------------------------\n");
1877cae2ed9aSIngo Molnar 		debug_locks = 0;
1878cae2ed9aSIngo Molnar 		printk("BUG: %3d unexpected failures (out of %3d) - debugging disabled! |\n",
1879cae2ed9aSIngo Molnar 			unexpected_testcase_failures, testcase_total);
1880cae2ed9aSIngo Molnar 		printk("-----------------------------------------------------------------\n");
1881cae2ed9aSIngo Molnar 	} else if (expected_testcase_failures && testcase_successes) {
1882cae2ed9aSIngo Molnar 		printk("--------------------------------------------------------\n");
1883cae2ed9aSIngo Molnar 		printk("%3d out of %3d testcases failed, as expected. |\n",
1884cae2ed9aSIngo Molnar 			expected_testcase_failures, testcase_total);
1885cae2ed9aSIngo Molnar 		printk("----------------------------------------------------\n");
1886cae2ed9aSIngo Molnar 		debug_locks = 1;
1887cae2ed9aSIngo Molnar 	} else if (expected_testcase_failures && !testcase_successes) {
1888cae2ed9aSIngo Molnar 		printk("--------------------------------------------------------\n");
1889cae2ed9aSIngo Molnar 		printk("All %3d testcases failed, as expected. |\n",
1890cae2ed9aSIngo Molnar 			expected_testcase_failures);
1891cae2ed9aSIngo Molnar 		printk("----------------------------------------\n");
1892cae2ed9aSIngo Molnar 		debug_locks = 1;
1893cae2ed9aSIngo Molnar 	} else {
1894cae2ed9aSIngo Molnar 		printk("-------------------------------------------------------\n");
1895cae2ed9aSIngo Molnar 		printk("Good, all %3d testcases passed! |\n",
1896cae2ed9aSIngo Molnar 			testcase_successes);
1897cae2ed9aSIngo Molnar 		printk("---------------------------------\n");
1898cae2ed9aSIngo Molnar 		debug_locks = 1;
1899cae2ed9aSIngo Molnar 	}
1900cae2ed9aSIngo Molnar 	debug_locks_silent = 0;
1901cae2ed9aSIngo Molnar }
1902