xref: /linux-6.15/lib/locking-selftest.c (revision a2e9ae58)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2cae2ed9aSIngo Molnar /*
3cae2ed9aSIngo Molnar  * lib/locking-selftest.c
4cae2ed9aSIngo Molnar  *
5cae2ed9aSIngo Molnar  * Testsuite for various locking APIs: spinlocks, rwlocks,
6cae2ed9aSIngo Molnar  * mutexes and rw-semaphores.
7cae2ed9aSIngo Molnar  *
8cae2ed9aSIngo Molnar  * It is checking both false positives and false negatives.
9cae2ed9aSIngo Molnar  *
10cae2ed9aSIngo Molnar  * Started by Ingo Molnar:
11cae2ed9aSIngo Molnar  *
12cae2ed9aSIngo Molnar  *  Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <[email protected]>
13cae2ed9aSIngo Molnar  */
14cae2ed9aSIngo Molnar #include <linux/rwsem.h>
15cae2ed9aSIngo Molnar #include <linux/mutex.h>
161b375dc3SMaarten Lankhorst #include <linux/ww_mutex.h>
17cae2ed9aSIngo Molnar #include <linux/sched.h>
18cae2ed9aSIngo Molnar #include <linux/delay.h>
19fbb9ce95SIngo Molnar #include <linux/lockdep.h>
20cae2ed9aSIngo Molnar #include <linux/spinlock.h>
21cae2ed9aSIngo Molnar #include <linux/kallsyms.h>
22cae2ed9aSIngo Molnar #include <linux/interrupt.h>
23cae2ed9aSIngo Molnar #include <linux/debug_locks.h>
24cae2ed9aSIngo Molnar #include <linux/irqflags.h>
25018956d6SPeter Zijlstra #include <linux/rtmutex.h>
26cae2ed9aSIngo Molnar 
27cae2ed9aSIngo Molnar /*
28cae2ed9aSIngo Molnar  * Change this to 1 if you want to see the failure printouts:
29cae2ed9aSIngo Molnar  */
30cae2ed9aSIngo Molnar static unsigned int debug_locks_verbose;
31e9181886SBoqun Feng unsigned int force_read_lock_recursive;
32cae2ed9aSIngo Molnar 
3308295b3bSThomas Hellstrom static DEFINE_WD_CLASS(ww_lockdep);
341de99445SMaarten Lankhorst 
35cae2ed9aSIngo Molnar static int __init setup_debug_locks_verbose(char *str)
36cae2ed9aSIngo Molnar {
37cae2ed9aSIngo Molnar 	get_option(&str, &debug_locks_verbose);
38cae2ed9aSIngo Molnar 
39cae2ed9aSIngo Molnar 	return 1;
40cae2ed9aSIngo Molnar }
41cae2ed9aSIngo Molnar 
42cae2ed9aSIngo Molnar __setup("debug_locks_verbose=", setup_debug_locks_verbose);
43cae2ed9aSIngo Molnar 
44cae2ed9aSIngo Molnar #define FAILURE		0
45cae2ed9aSIngo Molnar #define SUCCESS		1
46cae2ed9aSIngo Molnar 
47cae2ed9aSIngo Molnar #define LOCKTYPE_SPIN	0x1
48cae2ed9aSIngo Molnar #define LOCKTYPE_RWLOCK	0x2
49cae2ed9aSIngo Molnar #define LOCKTYPE_MUTEX	0x4
50cae2ed9aSIngo Molnar #define LOCKTYPE_RWSEM	0x8
511de99445SMaarten Lankhorst #define LOCKTYPE_WW	0x10
52018956d6SPeter Zijlstra #define LOCKTYPE_RTMUTEX 0x20
531de99445SMaarten Lankhorst 
541de99445SMaarten Lankhorst static struct ww_acquire_ctx t, t2;
55f3cf139eSMaarten Lankhorst static struct ww_mutex o, o2, o3;
56cae2ed9aSIngo Molnar 
57cae2ed9aSIngo Molnar /*
58cae2ed9aSIngo Molnar  * Normal standalone locks, for the circular and irq-context
59cae2ed9aSIngo Molnar  * dependency tests:
60cae2ed9aSIngo Molnar  */
61*a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_A);
62*a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_B);
63*a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_C);
64*a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_D);
65cae2ed9aSIngo Molnar 
66cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_A);
67cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_B);
68cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_C);
69cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_D);
70cae2ed9aSIngo Molnar 
71cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_A);
72cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_B);
73cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_C);
74cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_D);
75cae2ed9aSIngo Molnar 
76cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_A);
77cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_B);
78cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_C);
79cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_D);
80cae2ed9aSIngo Molnar 
81018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
82018956d6SPeter Zijlstra 
83018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_A);
84018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_B);
85018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_C);
86018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_D);
87018956d6SPeter Zijlstra 
88018956d6SPeter Zijlstra #endif
89018956d6SPeter Zijlstra 
90cae2ed9aSIngo Molnar /*
91cae2ed9aSIngo Molnar  * Locks that we initialize dynamically as well so that
92cae2ed9aSIngo Molnar  * e.g. X1 and X2 becomes two instances of the same class,
93cae2ed9aSIngo Molnar  * but X* and Y* are different classes. We do this so that
94cae2ed9aSIngo Molnar  * we do not trigger a real lockup:
95cae2ed9aSIngo Molnar  */
96*a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_X1);
97*a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_X2);
98*a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_Y1);
99*a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_Y2);
100*a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_Z1);
101*a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_Z2);
102cae2ed9aSIngo Molnar 
103cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_X1);
104cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_X2);
105cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Y1);
106cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Y2);
107cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Z1);
108cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Z2);
109cae2ed9aSIngo Molnar 
110cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_X1);
111cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_X2);
112cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Y1);
113cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Y2);
114cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Z1);
115cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Z2);
116cae2ed9aSIngo Molnar 
117cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_X1);
118cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_X2);
119cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Y1);
120cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Y2);
121cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Z1);
122cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Z2);
123cae2ed9aSIngo Molnar 
124018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
125018956d6SPeter Zijlstra 
126018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_X1);
127018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_X2);
128018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_Y1);
129018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_Y2);
130018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_Z1);
131018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_Z2);
132018956d6SPeter Zijlstra 
133018956d6SPeter Zijlstra #endif
134018956d6SPeter Zijlstra 
135cae2ed9aSIngo Molnar /*
136cae2ed9aSIngo Molnar  * non-inlined runtime initializers, to let separate locks share
137cae2ed9aSIngo Molnar  * the same lock-class:
138cae2ed9aSIngo Molnar  */
139cae2ed9aSIngo Molnar #define INIT_CLASS_FUNC(class) 				\
140cae2ed9aSIngo Molnar static noinline void					\
141*a2e9ae58SPeter Zijlstra init_class_##class(spinlock_t *lock, rwlock_t *rwlock, \
1429fb1b90cSYong Zhang 	struct mutex *mutex, struct rw_semaphore *rwsem)\
143cae2ed9aSIngo Molnar {							\
144*a2e9ae58SPeter Zijlstra 	spin_lock_init(lock);			\
145cae2ed9aSIngo Molnar 	rwlock_init(rwlock);				\
146cae2ed9aSIngo Molnar 	mutex_init(mutex);				\
147cae2ed9aSIngo Molnar 	init_rwsem(rwsem);				\
148cae2ed9aSIngo Molnar }
149cae2ed9aSIngo Molnar 
150cae2ed9aSIngo Molnar INIT_CLASS_FUNC(X)
151cae2ed9aSIngo Molnar INIT_CLASS_FUNC(Y)
152cae2ed9aSIngo Molnar INIT_CLASS_FUNC(Z)
153cae2ed9aSIngo Molnar 
154cae2ed9aSIngo Molnar static void init_shared_classes(void)
155cae2ed9aSIngo Molnar {
156018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
157018956d6SPeter Zijlstra 	static struct lock_class_key rt_X, rt_Y, rt_Z;
158018956d6SPeter Zijlstra 
159018956d6SPeter Zijlstra 	__rt_mutex_init(&rtmutex_X1, __func__, &rt_X);
160018956d6SPeter Zijlstra 	__rt_mutex_init(&rtmutex_X2, __func__, &rt_X);
161018956d6SPeter Zijlstra 	__rt_mutex_init(&rtmutex_Y1, __func__, &rt_Y);
162018956d6SPeter Zijlstra 	__rt_mutex_init(&rtmutex_Y2, __func__, &rt_Y);
163018956d6SPeter Zijlstra 	__rt_mutex_init(&rtmutex_Z1, __func__, &rt_Z);
164018956d6SPeter Zijlstra 	__rt_mutex_init(&rtmutex_Z2, __func__, &rt_Z);
165018956d6SPeter Zijlstra #endif
166018956d6SPeter Zijlstra 
167cae2ed9aSIngo Molnar 	init_class_X(&lock_X1, &rwlock_X1, &mutex_X1, &rwsem_X1);
168cae2ed9aSIngo Molnar 	init_class_X(&lock_X2, &rwlock_X2, &mutex_X2, &rwsem_X2);
169cae2ed9aSIngo Molnar 
170cae2ed9aSIngo Molnar 	init_class_Y(&lock_Y1, &rwlock_Y1, &mutex_Y1, &rwsem_Y1);
171cae2ed9aSIngo Molnar 	init_class_Y(&lock_Y2, &rwlock_Y2, &mutex_Y2, &rwsem_Y2);
172cae2ed9aSIngo Molnar 
173cae2ed9aSIngo Molnar 	init_class_Z(&lock_Z1, &rwlock_Z1, &mutex_Z1, &rwsem_Z1);
174cae2ed9aSIngo Molnar 	init_class_Z(&lock_Z2, &rwlock_Z2, &mutex_Z2, &rwsem_Z2);
175cae2ed9aSIngo Molnar }
176cae2ed9aSIngo Molnar 
177cae2ed9aSIngo Molnar /*
178cae2ed9aSIngo Molnar  * For spinlocks and rwlocks we also do hardirq-safe / softirq-safe tests.
179cae2ed9aSIngo Molnar  * The following functions use a lock from a simulated hardirq/softirq
180cae2ed9aSIngo Molnar  * context, causing the locks to be marked as hardirq-safe/softirq-safe:
181cae2ed9aSIngo Molnar  */
182cae2ed9aSIngo Molnar 
183cae2ed9aSIngo Molnar #define HARDIRQ_DISABLE		local_irq_disable
184cae2ed9aSIngo Molnar #define HARDIRQ_ENABLE		local_irq_enable
185cae2ed9aSIngo Molnar 
186cae2ed9aSIngo Molnar #define HARDIRQ_ENTER()				\
187cae2ed9aSIngo Molnar 	local_irq_disable();			\
188ba9f207cSFrederic Weisbecker 	__irq_enter();				\
189cae2ed9aSIngo Molnar 	WARN_ON(!in_irq());
190cae2ed9aSIngo Molnar 
191cae2ed9aSIngo Molnar #define HARDIRQ_EXIT()				\
192cae2ed9aSIngo Molnar 	__irq_exit();				\
193cae2ed9aSIngo Molnar 	local_irq_enable();
194cae2ed9aSIngo Molnar 
195cae2ed9aSIngo Molnar #define SOFTIRQ_DISABLE		local_bh_disable
196cae2ed9aSIngo Molnar #define SOFTIRQ_ENABLE		local_bh_enable
197cae2ed9aSIngo Molnar 
198cae2ed9aSIngo Molnar #define SOFTIRQ_ENTER()				\
199cae2ed9aSIngo Molnar 		local_bh_disable();		\
200cae2ed9aSIngo Molnar 		local_irq_disable();		\
201d820ac4cSIngo Molnar 		lockdep_softirq_enter();	\
202cae2ed9aSIngo Molnar 		WARN_ON(!in_softirq());
203cae2ed9aSIngo Molnar 
204cae2ed9aSIngo Molnar #define SOFTIRQ_EXIT()				\
205d820ac4cSIngo Molnar 		lockdep_softirq_exit();		\
206cae2ed9aSIngo Molnar 		local_irq_enable();		\
207cae2ed9aSIngo Molnar 		local_bh_enable();
208cae2ed9aSIngo Molnar 
209cae2ed9aSIngo Molnar /*
210cae2ed9aSIngo Molnar  * Shortcuts for lock/unlock API variants, to keep
211cae2ed9aSIngo Molnar  * the testcases compact:
212cae2ed9aSIngo Molnar  */
213*a2e9ae58SPeter Zijlstra #define L(x)			spin_lock(&lock_##x)
214*a2e9ae58SPeter Zijlstra #define U(x)			spin_unlock(&lock_##x)
215cae2ed9aSIngo Molnar #define LU(x)			L(x); U(x)
216*a2e9ae58SPeter Zijlstra #define SI(x)			spin_lock_init(&lock_##x)
217cae2ed9aSIngo Molnar 
218cae2ed9aSIngo Molnar #define WL(x)			write_lock(&rwlock_##x)
219cae2ed9aSIngo Molnar #define WU(x)			write_unlock(&rwlock_##x)
220cae2ed9aSIngo Molnar #define WLU(x)			WL(x); WU(x)
221cae2ed9aSIngo Molnar 
222cae2ed9aSIngo Molnar #define RL(x)			read_lock(&rwlock_##x)
223cae2ed9aSIngo Molnar #define RU(x)			read_unlock(&rwlock_##x)
224cae2ed9aSIngo Molnar #define RLU(x)			RL(x); RU(x)
225cae2ed9aSIngo Molnar #define RWI(x)			rwlock_init(&rwlock_##x)
226cae2ed9aSIngo Molnar 
227cae2ed9aSIngo Molnar #define ML(x)			mutex_lock(&mutex_##x)
228cae2ed9aSIngo Molnar #define MU(x)			mutex_unlock(&mutex_##x)
229cae2ed9aSIngo Molnar #define MI(x)			mutex_init(&mutex_##x)
230cae2ed9aSIngo Molnar 
231018956d6SPeter Zijlstra #define RTL(x)			rt_mutex_lock(&rtmutex_##x)
232018956d6SPeter Zijlstra #define RTU(x)			rt_mutex_unlock(&rtmutex_##x)
233018956d6SPeter Zijlstra #define RTI(x)			rt_mutex_init(&rtmutex_##x)
234018956d6SPeter Zijlstra 
235cae2ed9aSIngo Molnar #define WSL(x)			down_write(&rwsem_##x)
236cae2ed9aSIngo Molnar #define WSU(x)			up_write(&rwsem_##x)
237cae2ed9aSIngo Molnar 
238cae2ed9aSIngo Molnar #define RSL(x)			down_read(&rwsem_##x)
239cae2ed9aSIngo Molnar #define RSU(x)			up_read(&rwsem_##x)
240cae2ed9aSIngo Molnar #define RWSI(x)			init_rwsem(&rwsem_##x)
241cae2ed9aSIngo Molnar 
2421de99445SMaarten Lankhorst #ifndef CONFIG_DEBUG_WW_MUTEX_SLOWPATH
2431de99445SMaarten Lankhorst #define WWAI(x)			ww_acquire_init(x, &ww_lockdep)
2441de99445SMaarten Lankhorst #else
2451de99445SMaarten Lankhorst #define WWAI(x)			do { ww_acquire_init(x, &ww_lockdep); (x)->deadlock_inject_countdown = ~0U; } while (0)
2461de99445SMaarten Lankhorst #endif
2471de99445SMaarten Lankhorst #define WWAD(x)			ww_acquire_done(x)
2481de99445SMaarten Lankhorst #define WWAF(x)			ww_acquire_fini(x)
2491de99445SMaarten Lankhorst 
2501de99445SMaarten Lankhorst #define WWL(x, c)		ww_mutex_lock(x, c)
2511de99445SMaarten Lankhorst #define WWT(x)			ww_mutex_trylock(x)
2521de99445SMaarten Lankhorst #define WWL1(x)			ww_mutex_lock(x, NULL)
2531de99445SMaarten Lankhorst #define WWU(x)			ww_mutex_unlock(x)
2541de99445SMaarten Lankhorst 
2551de99445SMaarten Lankhorst 
256cae2ed9aSIngo Molnar #define LOCK_UNLOCK_2(x,y)	LOCK(x); LOCK(y); UNLOCK(y); UNLOCK(x)
257cae2ed9aSIngo Molnar 
258cae2ed9aSIngo Molnar /*
259cae2ed9aSIngo Molnar  * Generate different permutations of the same testcase, using
260cae2ed9aSIngo Molnar  * the same basic lock-dependency/state events:
261cae2ed9aSIngo Molnar  */
262cae2ed9aSIngo Molnar 
263cae2ed9aSIngo Molnar #define GENERATE_TESTCASE(name)			\
264cae2ed9aSIngo Molnar 						\
265cae2ed9aSIngo Molnar static void name(void) { E(); }
266cae2ed9aSIngo Molnar 
267cae2ed9aSIngo Molnar #define GENERATE_PERMUTATIONS_2_EVENTS(name)	\
268cae2ed9aSIngo Molnar 						\
269cae2ed9aSIngo Molnar static void name##_12(void) { E1(); E2(); }	\
270cae2ed9aSIngo Molnar static void name##_21(void) { E2(); E1(); }
271cae2ed9aSIngo Molnar 
272cae2ed9aSIngo Molnar #define GENERATE_PERMUTATIONS_3_EVENTS(name)		\
273cae2ed9aSIngo Molnar 							\
274cae2ed9aSIngo Molnar static void name##_123(void) { E1(); E2(); E3(); }	\
275cae2ed9aSIngo Molnar static void name##_132(void) { E1(); E3(); E2(); }	\
276cae2ed9aSIngo Molnar static void name##_213(void) { E2(); E1(); E3(); }	\
277cae2ed9aSIngo Molnar static void name##_231(void) { E2(); E3(); E1(); }	\
278cae2ed9aSIngo Molnar static void name##_312(void) { E3(); E1(); E2(); }	\
279cae2ed9aSIngo Molnar static void name##_321(void) { E3(); E2(); E1(); }
280cae2ed9aSIngo Molnar 
281cae2ed9aSIngo Molnar /*
282cae2ed9aSIngo Molnar  * AA deadlock:
283cae2ed9aSIngo Molnar  */
284cae2ed9aSIngo Molnar 
285cae2ed9aSIngo Molnar #define E()					\
286cae2ed9aSIngo Molnar 						\
287cae2ed9aSIngo Molnar 	LOCK(X1);				\
288cae2ed9aSIngo Molnar 	LOCK(X2); /* this one should fail */
289cae2ed9aSIngo Molnar 
290cae2ed9aSIngo Molnar /*
291cae2ed9aSIngo Molnar  * 6 testcases:
292cae2ed9aSIngo Molnar  */
293cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
294cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_spin)
295cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
296cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_wlock)
297cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
298cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_rlock)
299cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
300cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_mutex)
301cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
302cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_wsem)
303cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
304cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_rsem)
305cae2ed9aSIngo Molnar 
306018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
307018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
308018956d6SPeter Zijlstra GENERATE_TESTCASE(AA_rtmutex);
309018956d6SPeter Zijlstra #endif
310018956d6SPeter Zijlstra 
311cae2ed9aSIngo Molnar #undef E
312cae2ed9aSIngo Molnar 
313cae2ed9aSIngo Molnar /*
314cae2ed9aSIngo Molnar  * Special-case for read-locking, they are
3156c9076ecSIngo Molnar  * allowed to recurse on the same lock class:
316cae2ed9aSIngo Molnar  */
317cae2ed9aSIngo Molnar static void rlock_AA1(void)
318cae2ed9aSIngo Molnar {
319cae2ed9aSIngo Molnar 	RL(X1);
320cae2ed9aSIngo Molnar 	RL(X1); // this one should NOT fail
321cae2ed9aSIngo Molnar }
322cae2ed9aSIngo Molnar 
323cae2ed9aSIngo Molnar static void rlock_AA1B(void)
324cae2ed9aSIngo Molnar {
325cae2ed9aSIngo Molnar 	RL(X1);
3266c9076ecSIngo Molnar 	RL(X2); // this one should NOT fail
327cae2ed9aSIngo Molnar }
328cae2ed9aSIngo Molnar 
329cae2ed9aSIngo Molnar static void rsem_AA1(void)
330cae2ed9aSIngo Molnar {
331cae2ed9aSIngo Molnar 	RSL(X1);
332cae2ed9aSIngo Molnar 	RSL(X1); // this one should fail
333cae2ed9aSIngo Molnar }
334cae2ed9aSIngo Molnar 
335cae2ed9aSIngo Molnar static void rsem_AA1B(void)
336cae2ed9aSIngo Molnar {
337cae2ed9aSIngo Molnar 	RSL(X1);
338cae2ed9aSIngo Molnar 	RSL(X2); // this one should fail
339cae2ed9aSIngo Molnar }
340cae2ed9aSIngo Molnar /*
341cae2ed9aSIngo Molnar  * The mixing of read and write locks is not allowed:
342cae2ed9aSIngo Molnar  */
343cae2ed9aSIngo Molnar static void rlock_AA2(void)
344cae2ed9aSIngo Molnar {
345cae2ed9aSIngo Molnar 	RL(X1);
346cae2ed9aSIngo Molnar 	WL(X2); // this one should fail
347cae2ed9aSIngo Molnar }
348cae2ed9aSIngo Molnar 
349cae2ed9aSIngo Molnar static void rsem_AA2(void)
350cae2ed9aSIngo Molnar {
351cae2ed9aSIngo Molnar 	RSL(X1);
352cae2ed9aSIngo Molnar 	WSL(X2); // this one should fail
353cae2ed9aSIngo Molnar }
354cae2ed9aSIngo Molnar 
355cae2ed9aSIngo Molnar static void rlock_AA3(void)
356cae2ed9aSIngo Molnar {
357cae2ed9aSIngo Molnar 	WL(X1);
358cae2ed9aSIngo Molnar 	RL(X2); // this one should fail
359cae2ed9aSIngo Molnar }
360cae2ed9aSIngo Molnar 
361cae2ed9aSIngo Molnar static void rsem_AA3(void)
362cae2ed9aSIngo Molnar {
363cae2ed9aSIngo Molnar 	WSL(X1);
364cae2ed9aSIngo Molnar 	RSL(X2); // this one should fail
365cae2ed9aSIngo Molnar }
366cae2ed9aSIngo Molnar 
367cae2ed9aSIngo Molnar /*
368e9149858SPeter Zijlstra  * read_lock(A)
369e9149858SPeter Zijlstra  * spin_lock(B)
370e9149858SPeter Zijlstra  *		spin_lock(B)
371e9149858SPeter Zijlstra  *		write_lock(A)
372e9149858SPeter Zijlstra  */
373e9149858SPeter Zijlstra static void rlock_ABBA1(void)
374e9149858SPeter Zijlstra {
375e9149858SPeter Zijlstra 	RL(X1);
376e9149858SPeter Zijlstra 	L(Y1);
377e9149858SPeter Zijlstra 	U(Y1);
378e9149858SPeter Zijlstra 	RU(X1);
379e9149858SPeter Zijlstra 
380e9149858SPeter Zijlstra 	L(Y1);
381e9149858SPeter Zijlstra 	WL(X1);
382e9149858SPeter Zijlstra 	WU(X1);
383e9149858SPeter Zijlstra 	U(Y1); // should fail
384e9149858SPeter Zijlstra }
385e9149858SPeter Zijlstra 
386e9149858SPeter Zijlstra static void rwsem_ABBA1(void)
387e9149858SPeter Zijlstra {
388e9149858SPeter Zijlstra 	RSL(X1);
389e9149858SPeter Zijlstra 	ML(Y1);
390e9149858SPeter Zijlstra 	MU(Y1);
391e9149858SPeter Zijlstra 	RSU(X1);
392e9149858SPeter Zijlstra 
393e9149858SPeter Zijlstra 	ML(Y1);
394e9149858SPeter Zijlstra 	WSL(X1);
395e9149858SPeter Zijlstra 	WSU(X1);
396e9149858SPeter Zijlstra 	MU(Y1); // should fail
397e9149858SPeter Zijlstra }
398e9149858SPeter Zijlstra 
399e9149858SPeter Zijlstra /*
400e9149858SPeter Zijlstra  * read_lock(A)
401e9149858SPeter Zijlstra  * spin_lock(B)
402e9149858SPeter Zijlstra  *		spin_lock(B)
403d4f200e5SBoqun Feng  *		write_lock(A)
404d4f200e5SBoqun Feng  *
405d4f200e5SBoqun Feng  * This test case is aimed at poking whether the chain cache prevents us from
406d4f200e5SBoqun Feng  * detecting a read-lock/lock-write deadlock: if the chain cache doesn't differ
407d4f200e5SBoqun Feng  * read/write locks, the following case may happen
408d4f200e5SBoqun Feng  *
409d4f200e5SBoqun Feng  * 	{ read_lock(A)->lock(B) dependency exists }
410d4f200e5SBoqun Feng  *
411d4f200e5SBoqun Feng  * 	P0:
412d4f200e5SBoqun Feng  * 	lock(B);
413d4f200e5SBoqun Feng  * 	read_lock(A);
414d4f200e5SBoqun Feng  *
415d4f200e5SBoqun Feng  *	{ Not a deadlock, B -> A is added in the chain cache }
416d4f200e5SBoqun Feng  *
417d4f200e5SBoqun Feng  *	P1:
418d4f200e5SBoqun Feng  *	lock(B);
419d4f200e5SBoqun Feng  *	write_lock(A);
420d4f200e5SBoqun Feng  *
421d4f200e5SBoqun Feng  *	{ B->A found in chain cache, not reported as a deadlock }
422d4f200e5SBoqun Feng  *
423d4f200e5SBoqun Feng  */
424d4f200e5SBoqun Feng static void rlock_chaincache_ABBA1(void)
425d4f200e5SBoqun Feng {
426d4f200e5SBoqun Feng 	RL(X1);
427d4f200e5SBoqun Feng 	L(Y1);
428d4f200e5SBoqun Feng 	U(Y1);
429d4f200e5SBoqun Feng 	RU(X1);
430d4f200e5SBoqun Feng 
431d4f200e5SBoqun Feng 	L(Y1);
432d4f200e5SBoqun Feng 	RL(X1);
433d4f200e5SBoqun Feng 	RU(X1);
434d4f200e5SBoqun Feng 	U(Y1);
435d4f200e5SBoqun Feng 
436d4f200e5SBoqun Feng 	L(Y1);
437d4f200e5SBoqun Feng 	WL(X1);
438d4f200e5SBoqun Feng 	WU(X1);
439d4f200e5SBoqun Feng 	U(Y1); // should fail
440d4f200e5SBoqun Feng }
441d4f200e5SBoqun Feng 
442d4f200e5SBoqun Feng /*
443d4f200e5SBoqun Feng  * read_lock(A)
444d4f200e5SBoqun Feng  * spin_lock(B)
445d4f200e5SBoqun Feng  *		spin_lock(B)
446e9149858SPeter Zijlstra  *		read_lock(A)
447e9149858SPeter Zijlstra  */
448e9149858SPeter Zijlstra static void rlock_ABBA2(void)
449e9149858SPeter Zijlstra {
450e9149858SPeter Zijlstra 	RL(X1);
451e9149858SPeter Zijlstra 	L(Y1);
452e9149858SPeter Zijlstra 	U(Y1);
453e9149858SPeter Zijlstra 	RU(X1);
454e9149858SPeter Zijlstra 
455e9149858SPeter Zijlstra 	L(Y1);
456e9149858SPeter Zijlstra 	RL(X1);
457e9149858SPeter Zijlstra 	RU(X1);
458e9149858SPeter Zijlstra 	U(Y1); // should NOT fail
459e9149858SPeter Zijlstra }
460e9149858SPeter Zijlstra 
461e9149858SPeter Zijlstra static void rwsem_ABBA2(void)
462e9149858SPeter Zijlstra {
463e9149858SPeter Zijlstra 	RSL(X1);
464e9149858SPeter Zijlstra 	ML(Y1);
465e9149858SPeter Zijlstra 	MU(Y1);
466e9149858SPeter Zijlstra 	RSU(X1);
467e9149858SPeter Zijlstra 
468e9149858SPeter Zijlstra 	ML(Y1);
469e9149858SPeter Zijlstra 	RSL(X1);
470e9149858SPeter Zijlstra 	RSU(X1);
471e9149858SPeter Zijlstra 	MU(Y1); // should fail
472e9149858SPeter Zijlstra }
473e9149858SPeter Zijlstra 
474e9149858SPeter Zijlstra 
475e9149858SPeter Zijlstra /*
476e9149858SPeter Zijlstra  * write_lock(A)
477e9149858SPeter Zijlstra  * spin_lock(B)
478e9149858SPeter Zijlstra  *		spin_lock(B)
479e9149858SPeter Zijlstra  *		write_lock(A)
480e9149858SPeter Zijlstra  */
481e9149858SPeter Zijlstra static void rlock_ABBA3(void)
482e9149858SPeter Zijlstra {
483e9149858SPeter Zijlstra 	WL(X1);
484e9149858SPeter Zijlstra 	L(Y1);
485e9149858SPeter Zijlstra 	U(Y1);
486e9149858SPeter Zijlstra 	WU(X1);
487e9149858SPeter Zijlstra 
488e9149858SPeter Zijlstra 	L(Y1);
489e9149858SPeter Zijlstra 	WL(X1);
490e9149858SPeter Zijlstra 	WU(X1);
491e9149858SPeter Zijlstra 	U(Y1); // should fail
492e9149858SPeter Zijlstra }
493e9149858SPeter Zijlstra 
494e9149858SPeter Zijlstra static void rwsem_ABBA3(void)
495e9149858SPeter Zijlstra {
496e9149858SPeter Zijlstra 	WSL(X1);
497e9149858SPeter Zijlstra 	ML(Y1);
498e9149858SPeter Zijlstra 	MU(Y1);
499e9149858SPeter Zijlstra 	WSU(X1);
500e9149858SPeter Zijlstra 
501e9149858SPeter Zijlstra 	ML(Y1);
502e9149858SPeter Zijlstra 	WSL(X1);
503e9149858SPeter Zijlstra 	WSU(X1);
504e9149858SPeter Zijlstra 	MU(Y1); // should fail
505e9149858SPeter Zijlstra }
506e9149858SPeter Zijlstra 
507e9149858SPeter Zijlstra /*
508cae2ed9aSIngo Molnar  * ABBA deadlock:
509cae2ed9aSIngo Molnar  */
510cae2ed9aSIngo Molnar 
511cae2ed9aSIngo Molnar #define E()					\
512cae2ed9aSIngo Molnar 						\
513cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
514cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, A); /* fail */
515cae2ed9aSIngo Molnar 
516cae2ed9aSIngo Molnar /*
517cae2ed9aSIngo Molnar  * 6 testcases:
518cae2ed9aSIngo Molnar  */
519cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
520cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_spin)
521cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
522cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_wlock)
523cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
524cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_rlock)
525cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
526cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_mutex)
527cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
528cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_wsem)
529cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
530cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_rsem)
531cae2ed9aSIngo Molnar 
532018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
533018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
534018956d6SPeter Zijlstra GENERATE_TESTCASE(ABBA_rtmutex);
535018956d6SPeter Zijlstra #endif
536018956d6SPeter Zijlstra 
537cae2ed9aSIngo Molnar #undef E
538cae2ed9aSIngo Molnar 
539cae2ed9aSIngo Molnar /*
540cae2ed9aSIngo Molnar  * AB BC CA deadlock:
541cae2ed9aSIngo Molnar  */
542cae2ed9aSIngo Molnar 
543cae2ed9aSIngo Molnar #define E()					\
544cae2ed9aSIngo Molnar 						\
545cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
546cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, C);			\
547cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, A); /* fail */
548cae2ed9aSIngo Molnar 
549cae2ed9aSIngo Molnar /*
550cae2ed9aSIngo Molnar  * 6 testcases:
551cae2ed9aSIngo Molnar  */
552cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
553cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_spin)
554cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
555cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_wlock)
556cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
557cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_rlock)
558cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
559cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_mutex)
560cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
561cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_wsem)
562cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
563cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_rsem)
564cae2ed9aSIngo Molnar 
565018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
566018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
567018956d6SPeter Zijlstra GENERATE_TESTCASE(ABBCCA_rtmutex);
568018956d6SPeter Zijlstra #endif
569018956d6SPeter Zijlstra 
570cae2ed9aSIngo Molnar #undef E
571cae2ed9aSIngo Molnar 
572cae2ed9aSIngo Molnar /*
573cae2ed9aSIngo Molnar  * AB CA BC deadlock:
574cae2ed9aSIngo Molnar  */
575cae2ed9aSIngo Molnar 
576cae2ed9aSIngo Molnar #define E()					\
577cae2ed9aSIngo Molnar 						\
578cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
579cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, A);			\
580cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, C); /* fail */
581cae2ed9aSIngo Molnar 
582cae2ed9aSIngo Molnar /*
583cae2ed9aSIngo Molnar  * 6 testcases:
584cae2ed9aSIngo Molnar  */
585cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
586cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_spin)
587cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
588cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_wlock)
589cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
590cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_rlock)
591cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
592cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_mutex)
593cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
594cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_wsem)
595cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
596cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_rsem)
597cae2ed9aSIngo Molnar 
598018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
599018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
600018956d6SPeter Zijlstra GENERATE_TESTCASE(ABCABC_rtmutex);
601018956d6SPeter Zijlstra #endif
602018956d6SPeter Zijlstra 
603cae2ed9aSIngo Molnar #undef E
604cae2ed9aSIngo Molnar 
605cae2ed9aSIngo Molnar /*
606cae2ed9aSIngo Molnar  * AB BC CD DA deadlock:
607cae2ed9aSIngo Molnar  */
608cae2ed9aSIngo Molnar 
609cae2ed9aSIngo Molnar #define E()					\
610cae2ed9aSIngo Molnar 						\
611cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
612cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, C);			\
613cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, D);			\
614cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(D, A); /* fail */
615cae2ed9aSIngo Molnar 
616cae2ed9aSIngo Molnar /*
617cae2ed9aSIngo Molnar  * 6 testcases:
618cae2ed9aSIngo Molnar  */
619cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
620cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_spin)
621cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
622cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_wlock)
623cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
624cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_rlock)
625cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
626cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_mutex)
627cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
628cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_wsem)
629cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
630cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_rsem)
631cae2ed9aSIngo Molnar 
632018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
633018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
634018956d6SPeter Zijlstra GENERATE_TESTCASE(ABBCCDDA_rtmutex);
635018956d6SPeter Zijlstra #endif
636018956d6SPeter Zijlstra 
637cae2ed9aSIngo Molnar #undef E
638cae2ed9aSIngo Molnar 
639cae2ed9aSIngo Molnar /*
640cae2ed9aSIngo Molnar  * AB CD BD DA deadlock:
641cae2ed9aSIngo Molnar  */
642cae2ed9aSIngo Molnar #define E()					\
643cae2ed9aSIngo Molnar 						\
644cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
645cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, D);			\
646cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, D);			\
647cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(D, A); /* fail */
648cae2ed9aSIngo Molnar 
649cae2ed9aSIngo Molnar /*
650cae2ed9aSIngo Molnar  * 6 testcases:
651cae2ed9aSIngo Molnar  */
652cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
653cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_spin)
654cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
655cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_wlock)
656cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
657cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_rlock)
658cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
659cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_mutex)
660cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
661cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_wsem)
662cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
663cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_rsem)
664cae2ed9aSIngo Molnar 
665018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
666018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
667018956d6SPeter Zijlstra GENERATE_TESTCASE(ABCDBDDA_rtmutex);
668018956d6SPeter Zijlstra #endif
669018956d6SPeter Zijlstra 
670cae2ed9aSIngo Molnar #undef E
671cae2ed9aSIngo Molnar 
672cae2ed9aSIngo Molnar /*
673cae2ed9aSIngo Molnar  * AB CD BC DA deadlock:
674cae2ed9aSIngo Molnar  */
675cae2ed9aSIngo Molnar #define E()					\
676cae2ed9aSIngo Molnar 						\
677cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
678cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, D);			\
679cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, C);			\
680cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(D, A); /* fail */
681cae2ed9aSIngo Molnar 
682cae2ed9aSIngo Molnar /*
683cae2ed9aSIngo Molnar  * 6 testcases:
684cae2ed9aSIngo Molnar  */
685cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
686cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_spin)
687cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
688cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_wlock)
689cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
690cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_rlock)
691cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
692cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_mutex)
693cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
694cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_wsem)
695cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
696cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_rsem)
697cae2ed9aSIngo Molnar 
698018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
699018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
700018956d6SPeter Zijlstra GENERATE_TESTCASE(ABCDBCDA_rtmutex);
701018956d6SPeter Zijlstra #endif
702018956d6SPeter Zijlstra 
703cae2ed9aSIngo Molnar #undef E
704cae2ed9aSIngo Molnar 
705cae2ed9aSIngo Molnar /*
706cae2ed9aSIngo Molnar  * Double unlock:
707cae2ed9aSIngo Molnar  */
708cae2ed9aSIngo Molnar #define E()					\
709cae2ed9aSIngo Molnar 						\
710cae2ed9aSIngo Molnar 	LOCK(A);				\
711cae2ed9aSIngo Molnar 	UNLOCK(A);				\
712cae2ed9aSIngo Molnar 	UNLOCK(A); /* fail */
713cae2ed9aSIngo Molnar 
714cae2ed9aSIngo Molnar /*
715cae2ed9aSIngo Molnar  * 6 testcases:
716cae2ed9aSIngo Molnar  */
717cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
718cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_spin)
719cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
720cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_wlock)
721cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
722cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_rlock)
723cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
724cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_mutex)
725cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
726cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_wsem)
727cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
728cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_rsem)
729cae2ed9aSIngo Molnar 
730018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
731018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
732018956d6SPeter Zijlstra GENERATE_TESTCASE(double_unlock_rtmutex);
733018956d6SPeter Zijlstra #endif
734018956d6SPeter Zijlstra 
735cae2ed9aSIngo Molnar #undef E
736cae2ed9aSIngo Molnar 
737cae2ed9aSIngo Molnar /*
738cae2ed9aSIngo Molnar  * initializing a held lock:
739cae2ed9aSIngo Molnar  */
740cae2ed9aSIngo Molnar #define E()					\
741cae2ed9aSIngo Molnar 						\
742cae2ed9aSIngo Molnar 	LOCK(A);				\
743cae2ed9aSIngo Molnar 	INIT(A); /* fail */
744cae2ed9aSIngo Molnar 
745cae2ed9aSIngo Molnar /*
746cae2ed9aSIngo Molnar  * 6 testcases:
747cae2ed9aSIngo Molnar  */
748cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
749cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_spin)
750cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
751cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_wlock)
752cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
753cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_rlock)
754cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
755cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_mutex)
756cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
757cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_wsem)
758cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
759cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_rsem)
760cae2ed9aSIngo Molnar 
761018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
762018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
763018956d6SPeter Zijlstra GENERATE_TESTCASE(init_held_rtmutex);
764018956d6SPeter Zijlstra #endif
765018956d6SPeter Zijlstra 
766cae2ed9aSIngo Molnar #undef E
767cae2ed9aSIngo Molnar 
768cae2ed9aSIngo Molnar /*
769cae2ed9aSIngo Molnar  * locking an irq-safe lock with irqs enabled:
770cae2ed9aSIngo Molnar  */
771cae2ed9aSIngo Molnar #define E1()				\
772cae2ed9aSIngo Molnar 					\
773cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
774cae2ed9aSIngo Molnar 	LOCK(A);			\
775cae2ed9aSIngo Molnar 	UNLOCK(A);			\
776cae2ed9aSIngo Molnar 	IRQ_EXIT();
777cae2ed9aSIngo Molnar 
778cae2ed9aSIngo Molnar #define E2()				\
779cae2ed9aSIngo Molnar 					\
780cae2ed9aSIngo Molnar 	LOCK(A);			\
781cae2ed9aSIngo Molnar 	UNLOCK(A);
782cae2ed9aSIngo Molnar 
783cae2ed9aSIngo Molnar /*
784cae2ed9aSIngo Molnar  * Generate 24 testcases:
785cae2ed9aSIngo Molnar  */
786cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
787cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_spin)
788cae2ed9aSIngo Molnar 
789cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
790cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_rlock)
791cae2ed9aSIngo Molnar 
792cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
793cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_wlock)
794cae2ed9aSIngo Molnar 
795cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
796cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_spin)
797cae2ed9aSIngo Molnar 
798cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
799cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_rlock)
800cae2ed9aSIngo Molnar 
801cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
802cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_wlock)
803cae2ed9aSIngo Molnar 
804cae2ed9aSIngo Molnar #undef E1
805cae2ed9aSIngo Molnar #undef E2
806cae2ed9aSIngo Molnar 
807cae2ed9aSIngo Molnar /*
808cae2ed9aSIngo Molnar  * Enabling hardirqs with a softirq-safe lock held:
809cae2ed9aSIngo Molnar  */
810cae2ed9aSIngo Molnar #define E1()				\
811cae2ed9aSIngo Molnar 					\
812cae2ed9aSIngo Molnar 	SOFTIRQ_ENTER();		\
813cae2ed9aSIngo Molnar 	LOCK(A);			\
814cae2ed9aSIngo Molnar 	UNLOCK(A);			\
815cae2ed9aSIngo Molnar 	SOFTIRQ_EXIT();
816cae2ed9aSIngo Molnar 
817cae2ed9aSIngo Molnar #define E2()				\
818cae2ed9aSIngo Molnar 					\
819cae2ed9aSIngo Molnar 	HARDIRQ_DISABLE();		\
820cae2ed9aSIngo Molnar 	LOCK(A);			\
821cae2ed9aSIngo Molnar 	HARDIRQ_ENABLE();		\
822cae2ed9aSIngo Molnar 	UNLOCK(A);
823cae2ed9aSIngo Molnar 
824cae2ed9aSIngo Molnar /*
825cae2ed9aSIngo Molnar  * Generate 12 testcases:
826cae2ed9aSIngo Molnar  */
827cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
828cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_spin)
829cae2ed9aSIngo Molnar 
830cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
831cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_wlock)
832cae2ed9aSIngo Molnar 
833cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
834cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_rlock)
835cae2ed9aSIngo Molnar 
836cae2ed9aSIngo Molnar #undef E1
837cae2ed9aSIngo Molnar #undef E2
838cae2ed9aSIngo Molnar 
839cae2ed9aSIngo Molnar /*
840cae2ed9aSIngo Molnar  * Enabling irqs with an irq-safe lock held:
841cae2ed9aSIngo Molnar  */
842cae2ed9aSIngo Molnar #define E1()				\
843cae2ed9aSIngo Molnar 					\
844cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
845cae2ed9aSIngo Molnar 	LOCK(A);			\
846cae2ed9aSIngo Molnar 	UNLOCK(A);			\
847cae2ed9aSIngo Molnar 	IRQ_EXIT();
848cae2ed9aSIngo Molnar 
849cae2ed9aSIngo Molnar #define E2()				\
850cae2ed9aSIngo Molnar 					\
851cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
852cae2ed9aSIngo Molnar 	LOCK(A);			\
853cae2ed9aSIngo Molnar 	IRQ_ENABLE();			\
854cae2ed9aSIngo Molnar 	UNLOCK(A);
855cae2ed9aSIngo Molnar 
856cae2ed9aSIngo Molnar /*
857cae2ed9aSIngo Molnar  * Generate 24 testcases:
858cae2ed9aSIngo Molnar  */
859cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
860cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_spin)
861cae2ed9aSIngo Molnar 
862cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
863cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_rlock)
864cae2ed9aSIngo Molnar 
865cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
866cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_wlock)
867cae2ed9aSIngo Molnar 
868cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
869cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_spin)
870cae2ed9aSIngo Molnar 
871cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
872cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_rlock)
873cae2ed9aSIngo Molnar 
874cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
875cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock)
876cae2ed9aSIngo Molnar 
877cae2ed9aSIngo Molnar #undef E1
878cae2ed9aSIngo Molnar #undef E2
879cae2ed9aSIngo Molnar 
880cae2ed9aSIngo Molnar /*
881cae2ed9aSIngo Molnar  * Acquiring a irq-unsafe lock while holding an irq-safe-lock:
882cae2ed9aSIngo Molnar  */
883cae2ed9aSIngo Molnar #define E1()				\
884cae2ed9aSIngo Molnar 					\
885cae2ed9aSIngo Molnar 	LOCK(A);			\
886cae2ed9aSIngo Molnar 	LOCK(B);			\
887cae2ed9aSIngo Molnar 	UNLOCK(B);			\
888cae2ed9aSIngo Molnar 	UNLOCK(A);			\
889cae2ed9aSIngo Molnar 
890cae2ed9aSIngo Molnar #define E2()				\
891cae2ed9aSIngo Molnar 					\
892cae2ed9aSIngo Molnar 	LOCK(B);			\
893cae2ed9aSIngo Molnar 	UNLOCK(B);
894cae2ed9aSIngo Molnar 
895cae2ed9aSIngo Molnar #define E3()				\
896cae2ed9aSIngo Molnar 					\
897cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
898cae2ed9aSIngo Molnar 	LOCK(A);			\
899cae2ed9aSIngo Molnar 	UNLOCK(A);			\
900cae2ed9aSIngo Molnar 	IRQ_EXIT();
901cae2ed9aSIngo Molnar 
902cae2ed9aSIngo Molnar /*
903cae2ed9aSIngo Molnar  * Generate 36 testcases:
904cae2ed9aSIngo Molnar  */
905cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
906cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_spin)
907cae2ed9aSIngo Molnar 
908cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
909cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_rlock)
910cae2ed9aSIngo Molnar 
911cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
912cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_wlock)
913cae2ed9aSIngo Molnar 
914cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
915cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_spin)
916cae2ed9aSIngo Molnar 
917cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
918cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_rlock)
919cae2ed9aSIngo Molnar 
920cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
921cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock)
922cae2ed9aSIngo Molnar 
923cae2ed9aSIngo Molnar #undef E1
924cae2ed9aSIngo Molnar #undef E2
925cae2ed9aSIngo Molnar #undef E3
926cae2ed9aSIngo Molnar 
927cae2ed9aSIngo Molnar /*
928cae2ed9aSIngo Molnar  * If a lock turns into softirq-safe, but earlier it took
929cae2ed9aSIngo Molnar  * a softirq-unsafe lock:
930cae2ed9aSIngo Molnar  */
931cae2ed9aSIngo Molnar 
932cae2ed9aSIngo Molnar #define E1()				\
933cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
934cae2ed9aSIngo Molnar 	LOCK(A);			\
935cae2ed9aSIngo Molnar 	LOCK(B);			\
936cae2ed9aSIngo Molnar 	UNLOCK(B);			\
937cae2ed9aSIngo Molnar 	UNLOCK(A);			\
938cae2ed9aSIngo Molnar 	IRQ_ENABLE();
939cae2ed9aSIngo Molnar 
940cae2ed9aSIngo Molnar #define E2()				\
941cae2ed9aSIngo Molnar 	LOCK(B);			\
942cae2ed9aSIngo Molnar 	UNLOCK(B);
943cae2ed9aSIngo Molnar 
944cae2ed9aSIngo Molnar #define E3()				\
945cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
946cae2ed9aSIngo Molnar 	LOCK(A);			\
947cae2ed9aSIngo Molnar 	UNLOCK(A);			\
948cae2ed9aSIngo Molnar 	IRQ_EXIT();
949cae2ed9aSIngo Molnar 
950cae2ed9aSIngo Molnar /*
951cae2ed9aSIngo Molnar  * Generate 36 testcases:
952cae2ed9aSIngo Molnar  */
953cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
954cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_spin)
955cae2ed9aSIngo Molnar 
956cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
957cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_rlock)
958cae2ed9aSIngo Molnar 
959cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
960cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_wlock)
961cae2ed9aSIngo Molnar 
962cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
963cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_spin)
964cae2ed9aSIngo Molnar 
965cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
966cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_rlock)
967cae2ed9aSIngo Molnar 
968cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
969cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_wlock)
970cae2ed9aSIngo Molnar 
971cae2ed9aSIngo Molnar #undef E1
972cae2ed9aSIngo Molnar #undef E2
973cae2ed9aSIngo Molnar #undef E3
974cae2ed9aSIngo Molnar 
975cae2ed9aSIngo Molnar /*
976cae2ed9aSIngo Molnar  * read-lock / write-lock irq inversion.
977cae2ed9aSIngo Molnar  *
978cae2ed9aSIngo Molnar  * Deadlock scenario:
979cae2ed9aSIngo Molnar  *
980cae2ed9aSIngo Molnar  * CPU#1 is at #1, i.e. it has write-locked A, but has not
981cae2ed9aSIngo Molnar  * taken B yet.
982cae2ed9aSIngo Molnar  *
983cae2ed9aSIngo Molnar  * CPU#2 is at #2, i.e. it has locked B.
984cae2ed9aSIngo Molnar  *
985cae2ed9aSIngo Molnar  * Hardirq hits CPU#2 at point #2 and is trying to read-lock A.
986cae2ed9aSIngo Molnar  *
987cae2ed9aSIngo Molnar  * The deadlock occurs because CPU#1 will spin on B, and CPU#2
988cae2ed9aSIngo Molnar  * will spin on A.
989cae2ed9aSIngo Molnar  */
990cae2ed9aSIngo Molnar 
991cae2ed9aSIngo Molnar #define E1()				\
992cae2ed9aSIngo Molnar 					\
993cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
994cae2ed9aSIngo Molnar 	WL(A);				\
995cae2ed9aSIngo Molnar 	LOCK(B);			\
996cae2ed9aSIngo Molnar 	UNLOCK(B);			\
997cae2ed9aSIngo Molnar 	WU(A);				\
998cae2ed9aSIngo Molnar 	IRQ_ENABLE();
999cae2ed9aSIngo Molnar 
1000cae2ed9aSIngo Molnar #define E2()				\
1001cae2ed9aSIngo Molnar 					\
1002cae2ed9aSIngo Molnar 	LOCK(B);			\
1003cae2ed9aSIngo Molnar 	UNLOCK(B);
1004cae2ed9aSIngo Molnar 
1005cae2ed9aSIngo Molnar #define E3()				\
1006cae2ed9aSIngo Molnar 					\
1007cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
1008cae2ed9aSIngo Molnar 	RL(A);				\
1009cae2ed9aSIngo Molnar 	RU(A);				\
1010cae2ed9aSIngo Molnar 	IRQ_EXIT();
1011cae2ed9aSIngo Molnar 
1012cae2ed9aSIngo Molnar /*
1013cae2ed9aSIngo Molnar  * Generate 36 testcases:
1014cae2ed9aSIngo Molnar  */
1015cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
1016cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_spin)
1017cae2ed9aSIngo Molnar 
1018cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
1019cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_rlock)
1020cae2ed9aSIngo Molnar 
1021cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
1022cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_wlock)
1023cae2ed9aSIngo Molnar 
1024cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
1025cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_spin)
1026cae2ed9aSIngo Molnar 
1027cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
1028cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_rlock)
1029cae2ed9aSIngo Molnar 
1030cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
1031cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_wlock)
1032cae2ed9aSIngo Molnar 
1033cae2ed9aSIngo Molnar #undef E1
1034cae2ed9aSIngo Molnar #undef E2
1035cae2ed9aSIngo Molnar #undef E3
1036cae2ed9aSIngo Molnar 
1037cae2ed9aSIngo Molnar /*
10388ef7ca75SBoqun Feng  * write-read / write-read / write-read deadlock even if read is recursive
10398ef7ca75SBoqun Feng  */
10408ef7ca75SBoqun Feng 
10418ef7ca75SBoqun Feng #define E1()				\
10428ef7ca75SBoqun Feng 					\
10438ef7ca75SBoqun Feng 	WL(X1);				\
10448ef7ca75SBoqun Feng 	RL(Y1);				\
10458ef7ca75SBoqun Feng 	RU(Y1);				\
10468ef7ca75SBoqun Feng 	WU(X1);
10478ef7ca75SBoqun Feng 
10488ef7ca75SBoqun Feng #define E2()				\
10498ef7ca75SBoqun Feng 					\
10508ef7ca75SBoqun Feng 	WL(Y1);				\
10518ef7ca75SBoqun Feng 	RL(Z1);				\
10528ef7ca75SBoqun Feng 	RU(Z1);				\
10538ef7ca75SBoqun Feng 	WU(Y1);
10548ef7ca75SBoqun Feng 
10558ef7ca75SBoqun Feng #define E3()				\
10568ef7ca75SBoqun Feng 					\
10578ef7ca75SBoqun Feng 	WL(Z1);				\
10588ef7ca75SBoqun Feng 	RL(X1);				\
10598ef7ca75SBoqun Feng 	RU(X1);				\
10608ef7ca75SBoqun Feng 	WU(Z1);
10618ef7ca75SBoqun Feng 
10628ef7ca75SBoqun Feng #include "locking-selftest-rlock.h"
10638ef7ca75SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(W1R2_W2R3_W3R1)
10648ef7ca75SBoqun Feng 
10658ef7ca75SBoqun Feng #undef E1
10668ef7ca75SBoqun Feng #undef E2
10678ef7ca75SBoqun Feng #undef E3
10688ef7ca75SBoqun Feng 
10698ef7ca75SBoqun Feng /*
10708ef7ca75SBoqun Feng  * write-write / read-read / write-read deadlock even if read is recursive
10718ef7ca75SBoqun Feng  */
10728ef7ca75SBoqun Feng 
10738ef7ca75SBoqun Feng #define E1()				\
10748ef7ca75SBoqun Feng 					\
10758ef7ca75SBoqun Feng 	WL(X1);				\
10768ef7ca75SBoqun Feng 	WL(Y1);				\
10778ef7ca75SBoqun Feng 	WU(Y1);				\
10788ef7ca75SBoqun Feng 	WU(X1);
10798ef7ca75SBoqun Feng 
10808ef7ca75SBoqun Feng #define E2()				\
10818ef7ca75SBoqun Feng 					\
10828ef7ca75SBoqun Feng 	RL(Y1);				\
10838ef7ca75SBoqun Feng 	RL(Z1);				\
10848ef7ca75SBoqun Feng 	RU(Z1);				\
10858ef7ca75SBoqun Feng 	RU(Y1);
10868ef7ca75SBoqun Feng 
10878ef7ca75SBoqun Feng #define E3()				\
10888ef7ca75SBoqun Feng 					\
10898ef7ca75SBoqun Feng 	WL(Z1);				\
10908ef7ca75SBoqun Feng 	RL(X1);				\
10918ef7ca75SBoqun Feng 	RU(X1);				\
10928ef7ca75SBoqun Feng 	WU(Z1);
10938ef7ca75SBoqun Feng 
10948ef7ca75SBoqun Feng #include "locking-selftest-rlock.h"
10958ef7ca75SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(W1W2_R2R3_W3R1)
10968ef7ca75SBoqun Feng 
10978ef7ca75SBoqun Feng #undef E1
10988ef7ca75SBoqun Feng #undef E2
10998ef7ca75SBoqun Feng #undef E3
11008ef7ca75SBoqun Feng 
11018ef7ca75SBoqun Feng /*
11028ef7ca75SBoqun Feng  * write-write / read-read / read-write is not deadlock when read is recursive
11038ef7ca75SBoqun Feng  */
11048ef7ca75SBoqun Feng 
11058ef7ca75SBoqun Feng #define E1()				\
11068ef7ca75SBoqun Feng 					\
11078ef7ca75SBoqun Feng 	WL(X1);				\
11088ef7ca75SBoqun Feng 	WL(Y1);				\
11098ef7ca75SBoqun Feng 	WU(Y1);				\
11108ef7ca75SBoqun Feng 	WU(X1);
11118ef7ca75SBoqun Feng 
11128ef7ca75SBoqun Feng #define E2()				\
11138ef7ca75SBoqun Feng 					\
11148ef7ca75SBoqun Feng 	RL(Y1);				\
11158ef7ca75SBoqun Feng 	RL(Z1);				\
11168ef7ca75SBoqun Feng 	RU(Z1);				\
11178ef7ca75SBoqun Feng 	RU(Y1);
11188ef7ca75SBoqun Feng 
11198ef7ca75SBoqun Feng #define E3()				\
11208ef7ca75SBoqun Feng 					\
11218ef7ca75SBoqun Feng 	RL(Z1);				\
11228ef7ca75SBoqun Feng 	WL(X1);				\
11238ef7ca75SBoqun Feng 	WU(X1);				\
11248ef7ca75SBoqun Feng 	RU(Z1);
11258ef7ca75SBoqun Feng 
11268ef7ca75SBoqun Feng #include "locking-selftest-rlock.h"
11278ef7ca75SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(W1R2_R2R3_W3W1)
11288ef7ca75SBoqun Feng 
11298ef7ca75SBoqun Feng #undef E1
11308ef7ca75SBoqun Feng #undef E2
11318ef7ca75SBoqun Feng #undef E3
11328ef7ca75SBoqun Feng 
11338ef7ca75SBoqun Feng /*
11348ef7ca75SBoqun Feng  * write-read / read-read / write-write is not deadlock when read is recursive
11358ef7ca75SBoqun Feng  */
11368ef7ca75SBoqun Feng 
11378ef7ca75SBoqun Feng #define E1()				\
11388ef7ca75SBoqun Feng 					\
11398ef7ca75SBoqun Feng 	WL(X1);				\
11408ef7ca75SBoqun Feng 	RL(Y1);				\
11418ef7ca75SBoqun Feng 	RU(Y1);				\
11428ef7ca75SBoqun Feng 	WU(X1);
11438ef7ca75SBoqun Feng 
11448ef7ca75SBoqun Feng #define E2()				\
11458ef7ca75SBoqun Feng 					\
11468ef7ca75SBoqun Feng 	RL(Y1);				\
11478ef7ca75SBoqun Feng 	RL(Z1);				\
11488ef7ca75SBoqun Feng 	RU(Z1);				\
11498ef7ca75SBoqun Feng 	RU(Y1);
11508ef7ca75SBoqun Feng 
11518ef7ca75SBoqun Feng #define E3()				\
11528ef7ca75SBoqun Feng 					\
11538ef7ca75SBoqun Feng 	WL(Z1);				\
11548ef7ca75SBoqun Feng 	WL(X1);				\
11558ef7ca75SBoqun Feng 	WU(X1);				\
11568ef7ca75SBoqun Feng 	WU(Z1);
11578ef7ca75SBoqun Feng 
11588ef7ca75SBoqun Feng #include "locking-selftest-rlock.h"
11598ef7ca75SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(W1W2_R2R3_R3W1)
11608ef7ca75SBoqun Feng 
11618ef7ca75SBoqun Feng #undef E1
11628ef7ca75SBoqun Feng #undef E2
11638ef7ca75SBoqun Feng #undef E3
11648ef7ca75SBoqun Feng /*
1165cae2ed9aSIngo Molnar  * read-lock / write-lock recursion that is actually safe.
1166cae2ed9aSIngo Molnar  */
1167cae2ed9aSIngo Molnar 
1168cae2ed9aSIngo Molnar #define E1()				\
1169cae2ed9aSIngo Molnar 					\
1170cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
1171cae2ed9aSIngo Molnar 	WL(A);				\
1172cae2ed9aSIngo Molnar 	WU(A);				\
1173cae2ed9aSIngo Molnar 	IRQ_ENABLE();
1174cae2ed9aSIngo Molnar 
1175cae2ed9aSIngo Molnar #define E2()				\
1176cae2ed9aSIngo Molnar 					\
1177cae2ed9aSIngo Molnar 	RL(A);				\
1178cae2ed9aSIngo Molnar 	RU(A);				\
1179cae2ed9aSIngo Molnar 
1180cae2ed9aSIngo Molnar #define E3()				\
1181cae2ed9aSIngo Molnar 					\
1182cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
118331e0d747SBoqun Feng 	LOCK(A);			\
1184cae2ed9aSIngo Molnar 	L(B);				\
1185cae2ed9aSIngo Molnar 	U(B);				\
118631e0d747SBoqun Feng 	UNLOCK(A);			\
1187cae2ed9aSIngo Molnar 	IRQ_EXIT();
1188cae2ed9aSIngo Molnar 
1189cae2ed9aSIngo Molnar /*
119031e0d747SBoqun Feng  * Generate 24 testcases:
1191cae2ed9aSIngo Molnar  */
1192cae2ed9aSIngo Molnar #include "locking-selftest-hardirq.h"
119331e0d747SBoqun Feng #include "locking-selftest-rlock.h"
119431e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard_rlock)
119531e0d747SBoqun Feng 
119631e0d747SBoqun Feng #include "locking-selftest-wlock.h"
119731e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard_wlock)
1198cae2ed9aSIngo Molnar 
1199cae2ed9aSIngo Molnar #include "locking-selftest-softirq.h"
120031e0d747SBoqun Feng #include "locking-selftest-rlock.h"
120131e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft_rlock)
120231e0d747SBoqun Feng 
120331e0d747SBoqun Feng #include "locking-selftest-wlock.h"
120431e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft_wlock)
1205cae2ed9aSIngo Molnar 
1206cae2ed9aSIngo Molnar #undef E1
1207cae2ed9aSIngo Molnar #undef E2
1208cae2ed9aSIngo Molnar #undef E3
1209cae2ed9aSIngo Molnar 
1210cae2ed9aSIngo Molnar /*
1211cae2ed9aSIngo Molnar  * read-lock / write-lock recursion that is unsafe.
1212cae2ed9aSIngo Molnar  */
1213cae2ed9aSIngo Molnar 
1214cae2ed9aSIngo Molnar #define E1()				\
1215cae2ed9aSIngo Molnar 					\
1216cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
1217cae2ed9aSIngo Molnar 	L(B);				\
121831e0d747SBoqun Feng 	LOCK(A);			\
121931e0d747SBoqun Feng 	UNLOCK(A);			\
1220cae2ed9aSIngo Molnar 	U(B);				\
1221cae2ed9aSIngo Molnar 	IRQ_ENABLE();
1222cae2ed9aSIngo Molnar 
1223cae2ed9aSIngo Molnar #define E2()				\
1224cae2ed9aSIngo Molnar 					\
1225cae2ed9aSIngo Molnar 	RL(A);				\
1226cae2ed9aSIngo Molnar 	RU(A);				\
1227cae2ed9aSIngo Molnar 
1228cae2ed9aSIngo Molnar #define E3()				\
1229cae2ed9aSIngo Molnar 					\
1230cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
1231cae2ed9aSIngo Molnar 	L(B);				\
1232cae2ed9aSIngo Molnar 	U(B);				\
1233cae2ed9aSIngo Molnar 	IRQ_EXIT();
1234cae2ed9aSIngo Molnar 
1235cae2ed9aSIngo Molnar /*
123631e0d747SBoqun Feng  * Generate 24 testcases:
1237cae2ed9aSIngo Molnar  */
1238cae2ed9aSIngo Molnar #include "locking-selftest-hardirq.h"
123931e0d747SBoqun Feng #include "locking-selftest-rlock.h"
124031e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard_rlock)
124131e0d747SBoqun Feng 
124231e0d747SBoqun Feng #include "locking-selftest-wlock.h"
124331e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard_wlock)
1244cae2ed9aSIngo Molnar 
1245cae2ed9aSIngo Molnar #include "locking-selftest-softirq.h"
124631e0d747SBoqun Feng #include "locking-selftest-rlock.h"
124731e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft_rlock)
124831e0d747SBoqun Feng 
124931e0d747SBoqun Feng #include "locking-selftest-wlock.h"
125031e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft_wlock)
1251cae2ed9aSIngo Molnar 
125296a16f45SBoqun Feng #undef E1
125396a16f45SBoqun Feng #undef E2
125496a16f45SBoqun Feng #undef E3
125596a16f45SBoqun Feng /*
125696a16f45SBoqun Feng  * read-lock / write-lock recursion that is unsafe.
125796a16f45SBoqun Feng  *
125896a16f45SBoqun Feng  * A is a ENABLED_*_READ lock
125996a16f45SBoqun Feng  * B is a USED_IN_*_READ lock
126096a16f45SBoqun Feng  *
126196a16f45SBoqun Feng  * read_lock(A);
126296a16f45SBoqun Feng  *			write_lock(B);
126396a16f45SBoqun Feng  * <interrupt>
126496a16f45SBoqun Feng  * read_lock(B);
126596a16f45SBoqun Feng  * 			write_lock(A); // if this one is read_lock(), no deadlock
126696a16f45SBoqun Feng  */
126796a16f45SBoqun Feng 
126896a16f45SBoqun Feng #define E1()				\
126996a16f45SBoqun Feng 					\
127096a16f45SBoqun Feng 	IRQ_DISABLE();			\
127196a16f45SBoqun Feng 	WL(B);				\
127296a16f45SBoqun Feng 	LOCK(A);			\
127396a16f45SBoqun Feng 	UNLOCK(A);			\
127496a16f45SBoqun Feng 	WU(B);				\
127596a16f45SBoqun Feng 	IRQ_ENABLE();
127696a16f45SBoqun Feng 
127796a16f45SBoqun Feng #define E2()				\
127896a16f45SBoqun Feng 					\
127996a16f45SBoqun Feng 	RL(A);				\
128096a16f45SBoqun Feng 	RU(A);				\
128196a16f45SBoqun Feng 
128296a16f45SBoqun Feng #define E3()				\
128396a16f45SBoqun Feng 					\
128496a16f45SBoqun Feng 	IRQ_ENTER();			\
128596a16f45SBoqun Feng 	RL(B);				\
128696a16f45SBoqun Feng 	RU(B);				\
128796a16f45SBoqun Feng 	IRQ_EXIT();
128896a16f45SBoqun Feng 
128996a16f45SBoqun Feng /*
129096a16f45SBoqun Feng  * Generate 24 testcases:
129196a16f45SBoqun Feng  */
129296a16f45SBoqun Feng #include "locking-selftest-hardirq.h"
129396a16f45SBoqun Feng #include "locking-selftest-rlock.h"
129496a16f45SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_hard_rlock)
129596a16f45SBoqun Feng 
129696a16f45SBoqun Feng #include "locking-selftest-wlock.h"
129796a16f45SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_hard_wlock)
129896a16f45SBoqun Feng 
129996a16f45SBoqun Feng #include "locking-selftest-softirq.h"
130096a16f45SBoqun Feng #include "locking-selftest-rlock.h"
130196a16f45SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_soft_rlock)
130296a16f45SBoqun Feng 
130396a16f45SBoqun Feng #include "locking-selftest-wlock.h"
130496a16f45SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_soft_wlock)
130596a16f45SBoqun Feng 
1306cae2ed9aSIngo Molnar #ifdef CONFIG_DEBUG_LOCK_ALLOC
1307cae2ed9aSIngo Molnar # define I_SPINLOCK(x)	lockdep_reset_lock(&lock_##x.dep_map)
1308cae2ed9aSIngo Molnar # define I_RWLOCK(x)	lockdep_reset_lock(&rwlock_##x.dep_map)
1309cae2ed9aSIngo Molnar # define I_MUTEX(x)	lockdep_reset_lock(&mutex_##x.dep_map)
1310cae2ed9aSIngo Molnar # define I_RWSEM(x)	lockdep_reset_lock(&rwsem_##x.dep_map)
13111de99445SMaarten Lankhorst # define I_WW(x)	lockdep_reset_lock(&x.dep_map)
1312018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
1313018956d6SPeter Zijlstra # define I_RTMUTEX(x)	lockdep_reset_lock(&rtmutex_##x.dep_map)
1314018956d6SPeter Zijlstra #endif
1315cae2ed9aSIngo Molnar #else
1316cae2ed9aSIngo Molnar # define I_SPINLOCK(x)
1317cae2ed9aSIngo Molnar # define I_RWLOCK(x)
1318cae2ed9aSIngo Molnar # define I_MUTEX(x)
1319cae2ed9aSIngo Molnar # define I_RWSEM(x)
13201de99445SMaarten Lankhorst # define I_WW(x)
1321cae2ed9aSIngo Molnar #endif
1322cae2ed9aSIngo Molnar 
1323018956d6SPeter Zijlstra #ifndef I_RTMUTEX
1324018956d6SPeter Zijlstra # define I_RTMUTEX(x)
1325018956d6SPeter Zijlstra #endif
1326018956d6SPeter Zijlstra 
1327018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
1328018956d6SPeter Zijlstra #define I2_RTMUTEX(x)	rt_mutex_init(&rtmutex_##x)
1329018956d6SPeter Zijlstra #else
1330018956d6SPeter Zijlstra #define I2_RTMUTEX(x)
1331018956d6SPeter Zijlstra #endif
1332018956d6SPeter Zijlstra 
1333cae2ed9aSIngo Molnar #define I1(x)					\
1334cae2ed9aSIngo Molnar 	do {					\
1335cae2ed9aSIngo Molnar 		I_SPINLOCK(x);			\
1336cae2ed9aSIngo Molnar 		I_RWLOCK(x);			\
1337cae2ed9aSIngo Molnar 		I_MUTEX(x);			\
1338cae2ed9aSIngo Molnar 		I_RWSEM(x);			\
1339018956d6SPeter Zijlstra 		I_RTMUTEX(x);			\
1340cae2ed9aSIngo Molnar 	} while (0)
1341cae2ed9aSIngo Molnar 
1342cae2ed9aSIngo Molnar #define I2(x)					\
1343cae2ed9aSIngo Molnar 	do {					\
1344*a2e9ae58SPeter Zijlstra 		spin_lock_init(&lock_##x);	\
1345cae2ed9aSIngo Molnar 		rwlock_init(&rwlock_##x);	\
1346cae2ed9aSIngo Molnar 		mutex_init(&mutex_##x);		\
1347cae2ed9aSIngo Molnar 		init_rwsem(&rwsem_##x);		\
1348018956d6SPeter Zijlstra 		I2_RTMUTEX(x);			\
1349cae2ed9aSIngo Molnar 	} while (0)
1350cae2ed9aSIngo Molnar 
1351cae2ed9aSIngo Molnar static void reset_locks(void)
1352cae2ed9aSIngo Molnar {
1353cae2ed9aSIngo Molnar 	local_irq_disable();
13541de99445SMaarten Lankhorst 	lockdep_free_key_range(&ww_lockdep.acquire_key, 1);
13551de99445SMaarten Lankhorst 	lockdep_free_key_range(&ww_lockdep.mutex_key, 1);
13561de99445SMaarten Lankhorst 
1357cae2ed9aSIngo Molnar 	I1(A); I1(B); I1(C); I1(D);
1358cae2ed9aSIngo Molnar 	I1(X1); I1(X2); I1(Y1); I1(Y2); I1(Z1); I1(Z2);
1359f3cf139eSMaarten Lankhorst 	I_WW(t); I_WW(t2); I_WW(o.base); I_WW(o2.base); I_WW(o3.base);
1360cae2ed9aSIngo Molnar 	lockdep_reset();
1361cae2ed9aSIngo Molnar 	I2(A); I2(B); I2(C); I2(D);
1362cae2ed9aSIngo Molnar 	init_shared_classes();
13631de99445SMaarten Lankhorst 
1364f3cf139eSMaarten Lankhorst 	ww_mutex_init(&o, &ww_lockdep); ww_mutex_init(&o2, &ww_lockdep); ww_mutex_init(&o3, &ww_lockdep);
13651de99445SMaarten Lankhorst 	memset(&t, 0, sizeof(t)); memset(&t2, 0, sizeof(t2));
13661de99445SMaarten Lankhorst 	memset(&ww_lockdep.acquire_key, 0, sizeof(ww_lockdep.acquire_key));
13671de99445SMaarten Lankhorst 	memset(&ww_lockdep.mutex_key, 0, sizeof(ww_lockdep.mutex_key));
1368cae2ed9aSIngo Molnar 	local_irq_enable();
1369cae2ed9aSIngo Molnar }
1370cae2ed9aSIngo Molnar 
1371cae2ed9aSIngo Molnar #undef I
1372cae2ed9aSIngo Molnar 
1373cae2ed9aSIngo Molnar static int testcase_total;
1374cae2ed9aSIngo Molnar static int testcase_successes;
1375cae2ed9aSIngo Molnar static int expected_testcase_failures;
1376cae2ed9aSIngo Molnar static int unexpected_testcase_failures;
1377cae2ed9aSIngo Molnar 
1378cae2ed9aSIngo Molnar static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask)
1379cae2ed9aSIngo Molnar {
1380cae2ed9aSIngo Molnar 	unsigned long saved_preempt_count = preempt_count();
1381cae2ed9aSIngo Molnar 
1382cae2ed9aSIngo Molnar 	WARN_ON(irqs_disabled());
1383cae2ed9aSIngo Molnar 
1384cae2ed9aSIngo Molnar 	testcase_fn();
1385cae2ed9aSIngo Molnar 	/*
1386cae2ed9aSIngo Molnar 	 * Filter out expected failures:
1387cae2ed9aSIngo Molnar 	 */
13881de99445SMaarten Lankhorst #ifndef CONFIG_PROVE_LOCKING
1389166989e3SMaarten Lankhorst 	if (expected == FAILURE && debug_locks) {
1390cae2ed9aSIngo Molnar 		expected_testcase_failures++;
139125139409SMichael Ellerman 		pr_cont("failed|");
1392166989e3SMaarten Lankhorst 	}
1393166989e3SMaarten Lankhorst 	else
1394166989e3SMaarten Lankhorst #endif
1395166989e3SMaarten Lankhorst 	if (debug_locks != expected) {
1396cae2ed9aSIngo Molnar 		unexpected_testcase_failures++;
139725139409SMichael Ellerman 		pr_cont("FAILED|");
1398cae2ed9aSIngo Molnar 	} else {
1399cae2ed9aSIngo Molnar 		testcase_successes++;
140025139409SMichael Ellerman 		pr_cont("  ok  |");
1401cae2ed9aSIngo Molnar 	}
1402cae2ed9aSIngo Molnar 	testcase_total++;
1403cae2ed9aSIngo Molnar 
1404cae2ed9aSIngo Molnar 	if (debug_locks_verbose)
140525139409SMichael Ellerman 		pr_cont(" lockclass mask: %x, debug_locks: %d, expected: %d\n",
1406cae2ed9aSIngo Molnar 			lockclass_mask, debug_locks, expected);
1407cae2ed9aSIngo Molnar 	/*
1408cae2ed9aSIngo Molnar 	 * Some tests (e.g. double-unlock) might corrupt the preemption
1409cae2ed9aSIngo Molnar 	 * count, so restore it:
1410cae2ed9aSIngo Molnar 	 */
14114a2b4b22SPeter Zijlstra 	preempt_count_set(saved_preempt_count);
1412cae2ed9aSIngo Molnar #ifdef CONFIG_TRACE_IRQFLAGS
1413cae2ed9aSIngo Molnar 	if (softirq_count())
1414cae2ed9aSIngo Molnar 		current->softirqs_enabled = 0;
1415cae2ed9aSIngo Molnar 	else
1416cae2ed9aSIngo Molnar 		current->softirqs_enabled = 1;
1417cae2ed9aSIngo Molnar #endif
1418cae2ed9aSIngo Molnar 
1419cae2ed9aSIngo Molnar 	reset_locks();
1420cae2ed9aSIngo Molnar }
1421cae2ed9aSIngo Molnar 
1422018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
1423018956d6SPeter Zijlstra #define dotest_rt(fn, e, m)	dotest((fn), (e), (m))
1424018956d6SPeter Zijlstra #else
1425018956d6SPeter Zijlstra #define dotest_rt(fn, e, m)
1426018956d6SPeter Zijlstra #endif
1427018956d6SPeter Zijlstra 
1428cae2ed9aSIngo Molnar static inline void print_testname(const char *testname)
1429cae2ed9aSIngo Molnar {
1430cae2ed9aSIngo Molnar 	printk("%33s:", testname);
1431cae2ed9aSIngo Molnar }
1432cae2ed9aSIngo Molnar 
1433cae2ed9aSIngo Molnar #define DO_TESTCASE_1(desc, name, nr)				\
1434cae2ed9aSIngo Molnar 	print_testname(desc"/"#nr);				\
1435cae2ed9aSIngo Molnar 	dotest(name##_##nr, SUCCESS, LOCKTYPE_RWLOCK);		\
143625139409SMichael Ellerman 	pr_cont("\n");
1437cae2ed9aSIngo Molnar 
1438cae2ed9aSIngo Molnar #define DO_TESTCASE_1B(desc, name, nr)				\
1439cae2ed9aSIngo Molnar 	print_testname(desc"/"#nr);				\
1440cae2ed9aSIngo Molnar 	dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK);		\
144125139409SMichael Ellerman 	pr_cont("\n");
1442cae2ed9aSIngo Molnar 
14438ef7ca75SBoqun Feng #define DO_TESTCASE_1RR(desc, name, nr)				\
14448ef7ca75SBoqun Feng 	print_testname(desc"/"#nr);				\
14458ef7ca75SBoqun Feng 	pr_cont("             |");				\
14468ef7ca75SBoqun Feng 	dotest(name##_##nr, SUCCESS, LOCKTYPE_RWLOCK);		\
14478ef7ca75SBoqun Feng 	pr_cont("\n");
14488ef7ca75SBoqun Feng 
14498ef7ca75SBoqun Feng #define DO_TESTCASE_1RRB(desc, name, nr)			\
14508ef7ca75SBoqun Feng 	print_testname(desc"/"#nr);				\
14518ef7ca75SBoqun Feng 	pr_cont("             |");				\
14528ef7ca75SBoqun Feng 	dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK);		\
14538ef7ca75SBoqun Feng 	pr_cont("\n");
14548ef7ca75SBoqun Feng 
14558ef7ca75SBoqun Feng 
1456cae2ed9aSIngo Molnar #define DO_TESTCASE_3(desc, name, nr)				\
1457cae2ed9aSIngo Molnar 	print_testname(desc"/"#nr);				\
1458cae2ed9aSIngo Molnar 	dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN);	\
1459cae2ed9aSIngo Molnar 	dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK);	\
1460cae2ed9aSIngo Molnar 	dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK);	\
146125139409SMichael Ellerman 	pr_cont("\n");
1462cae2ed9aSIngo Molnar 
1463cae2ed9aSIngo Molnar #define DO_TESTCASE_3RW(desc, name, nr)				\
1464cae2ed9aSIngo Molnar 	print_testname(desc"/"#nr);				\
1465cae2ed9aSIngo Molnar 	dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN|LOCKTYPE_RWLOCK);\
1466cae2ed9aSIngo Molnar 	dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK);	\
1467cae2ed9aSIngo Molnar 	dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK);	\
146825139409SMichael Ellerman 	pr_cont("\n");
1469cae2ed9aSIngo Molnar 
147031e0d747SBoqun Feng #define DO_TESTCASE_2RW(desc, name, nr)				\
147131e0d747SBoqun Feng 	print_testname(desc"/"#nr);				\
147231e0d747SBoqun Feng 	pr_cont("      |");					\
147331e0d747SBoqun Feng 	dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK);	\
147431e0d747SBoqun Feng 	dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK);	\
147531e0d747SBoqun Feng 	pr_cont("\n");
147631e0d747SBoqun Feng 
147731e0d747SBoqun Feng #define DO_TESTCASE_2x2RW(desc, name, nr)			\
147831e0d747SBoqun Feng 	DO_TESTCASE_2RW("hard-"desc, name##_hard, nr)		\
147931e0d747SBoqun Feng 	DO_TESTCASE_2RW("soft-"desc, name##_soft, nr)		\
148031e0d747SBoqun Feng 
148131e0d747SBoqun Feng #define DO_TESTCASE_6x2x2RW(desc, name)				\
148231e0d747SBoqun Feng 	DO_TESTCASE_2x2RW(desc, name, 123);			\
148331e0d747SBoqun Feng 	DO_TESTCASE_2x2RW(desc, name, 132);			\
148431e0d747SBoqun Feng 	DO_TESTCASE_2x2RW(desc, name, 213);			\
148531e0d747SBoqun Feng 	DO_TESTCASE_2x2RW(desc, name, 231);			\
148631e0d747SBoqun Feng 	DO_TESTCASE_2x2RW(desc, name, 312);			\
148731e0d747SBoqun Feng 	DO_TESTCASE_2x2RW(desc, name, 321);
148831e0d747SBoqun Feng 
1489cae2ed9aSIngo Molnar #define DO_TESTCASE_6(desc, name)				\
1490cae2ed9aSIngo Molnar 	print_testname(desc);					\
1491cae2ed9aSIngo Molnar 	dotest(name##_spin, FAILURE, LOCKTYPE_SPIN);		\
1492cae2ed9aSIngo Molnar 	dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK);		\
1493cae2ed9aSIngo Molnar 	dotest(name##_rlock, FAILURE, LOCKTYPE_RWLOCK);		\
1494cae2ed9aSIngo Molnar 	dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX);		\
1495cae2ed9aSIngo Molnar 	dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM);		\
1496cae2ed9aSIngo Molnar 	dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM);		\
1497018956d6SPeter Zijlstra 	dotest_rt(name##_rtmutex, FAILURE, LOCKTYPE_RTMUTEX);	\
149825139409SMichael Ellerman 	pr_cont("\n");
1499cae2ed9aSIngo Molnar 
1500cae2ed9aSIngo Molnar #define DO_TESTCASE_6_SUCCESS(desc, name)			\
1501cae2ed9aSIngo Molnar 	print_testname(desc);					\
1502cae2ed9aSIngo Molnar 	dotest(name##_spin, SUCCESS, LOCKTYPE_SPIN);		\
1503cae2ed9aSIngo Molnar 	dotest(name##_wlock, SUCCESS, LOCKTYPE_RWLOCK);		\
1504cae2ed9aSIngo Molnar 	dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK);		\
1505cae2ed9aSIngo Molnar 	dotest(name##_mutex, SUCCESS, LOCKTYPE_MUTEX);		\
1506cae2ed9aSIngo Molnar 	dotest(name##_wsem, SUCCESS, LOCKTYPE_RWSEM);		\
1507cae2ed9aSIngo Molnar 	dotest(name##_rsem, SUCCESS, LOCKTYPE_RWSEM);		\
1508018956d6SPeter Zijlstra 	dotest_rt(name##_rtmutex, SUCCESS, LOCKTYPE_RTMUTEX);	\
150925139409SMichael Ellerman 	pr_cont("\n");
1510cae2ed9aSIngo Molnar 
1511cae2ed9aSIngo Molnar /*
1512cae2ed9aSIngo Molnar  * 'read' variant: rlocks must not trigger.
1513cae2ed9aSIngo Molnar  */
1514cae2ed9aSIngo Molnar #define DO_TESTCASE_6R(desc, name)				\
1515cae2ed9aSIngo Molnar 	print_testname(desc);					\
1516cae2ed9aSIngo Molnar 	dotest(name##_spin, FAILURE, LOCKTYPE_SPIN);		\
1517cae2ed9aSIngo Molnar 	dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK);		\
1518cae2ed9aSIngo Molnar 	dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK);		\
1519cae2ed9aSIngo Molnar 	dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX);		\
1520cae2ed9aSIngo Molnar 	dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM);		\
1521cae2ed9aSIngo Molnar 	dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM);		\
1522018956d6SPeter Zijlstra 	dotest_rt(name##_rtmutex, FAILURE, LOCKTYPE_RTMUTEX);	\
152325139409SMichael Ellerman 	pr_cont("\n");
1524cae2ed9aSIngo Molnar 
1525cae2ed9aSIngo Molnar #define DO_TESTCASE_2I(desc, name, nr)				\
1526cae2ed9aSIngo Molnar 	DO_TESTCASE_1("hard-"desc, name##_hard, nr);		\
1527cae2ed9aSIngo Molnar 	DO_TESTCASE_1("soft-"desc, name##_soft, nr);
1528cae2ed9aSIngo Molnar 
1529cae2ed9aSIngo Molnar #define DO_TESTCASE_2IB(desc, name, nr)				\
1530cae2ed9aSIngo Molnar 	DO_TESTCASE_1B("hard-"desc, name##_hard, nr);		\
1531cae2ed9aSIngo Molnar 	DO_TESTCASE_1B("soft-"desc, name##_soft, nr);
1532cae2ed9aSIngo Molnar 
1533cae2ed9aSIngo Molnar #define DO_TESTCASE_6I(desc, name, nr)				\
1534cae2ed9aSIngo Molnar 	DO_TESTCASE_3("hard-"desc, name##_hard, nr);		\
1535cae2ed9aSIngo Molnar 	DO_TESTCASE_3("soft-"desc, name##_soft, nr);
1536cae2ed9aSIngo Molnar 
1537cae2ed9aSIngo Molnar #define DO_TESTCASE_6IRW(desc, name, nr)			\
1538cae2ed9aSIngo Molnar 	DO_TESTCASE_3RW("hard-"desc, name##_hard, nr);		\
1539cae2ed9aSIngo Molnar 	DO_TESTCASE_3RW("soft-"desc, name##_soft, nr);
1540cae2ed9aSIngo Molnar 
1541cae2ed9aSIngo Molnar #define DO_TESTCASE_2x3(desc, name)				\
1542cae2ed9aSIngo Molnar 	DO_TESTCASE_3(desc, name, 12);				\
1543cae2ed9aSIngo Molnar 	DO_TESTCASE_3(desc, name, 21);
1544cae2ed9aSIngo Molnar 
1545cae2ed9aSIngo Molnar #define DO_TESTCASE_2x6(desc, name)				\
1546cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 12);				\
1547cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 21);
1548cae2ed9aSIngo Molnar 
1549cae2ed9aSIngo Molnar #define DO_TESTCASE_6x2(desc, name)				\
1550cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 123);			\
1551cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 132);			\
1552cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 213);			\
1553cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 231);			\
1554cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 312);			\
1555cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 321);
1556cae2ed9aSIngo Molnar 
1557cae2ed9aSIngo Molnar #define DO_TESTCASE_6x2B(desc, name)				\
1558cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 123);			\
1559cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 132);			\
1560cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 213);			\
1561cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 231);			\
1562cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 312);			\
1563cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 321);
1564cae2ed9aSIngo Molnar 
15658ef7ca75SBoqun Feng #define DO_TESTCASE_6x1RR(desc, name)				\
15668ef7ca75SBoqun Feng 	DO_TESTCASE_1RR(desc, name, 123);			\
15678ef7ca75SBoqun Feng 	DO_TESTCASE_1RR(desc, name, 132);			\
15688ef7ca75SBoqun Feng 	DO_TESTCASE_1RR(desc, name, 213);			\
15698ef7ca75SBoqun Feng 	DO_TESTCASE_1RR(desc, name, 231);			\
15708ef7ca75SBoqun Feng 	DO_TESTCASE_1RR(desc, name, 312);			\
15718ef7ca75SBoqun Feng 	DO_TESTCASE_1RR(desc, name, 321);
15728ef7ca75SBoqun Feng 
15738ef7ca75SBoqun Feng #define DO_TESTCASE_6x1RRB(desc, name)				\
15748ef7ca75SBoqun Feng 	DO_TESTCASE_1RRB(desc, name, 123);			\
15758ef7ca75SBoqun Feng 	DO_TESTCASE_1RRB(desc, name, 132);			\
15768ef7ca75SBoqun Feng 	DO_TESTCASE_1RRB(desc, name, 213);			\
15778ef7ca75SBoqun Feng 	DO_TESTCASE_1RRB(desc, name, 231);			\
15788ef7ca75SBoqun Feng 	DO_TESTCASE_1RRB(desc, name, 312);			\
15798ef7ca75SBoqun Feng 	DO_TESTCASE_1RRB(desc, name, 321);
15808ef7ca75SBoqun Feng 
1581cae2ed9aSIngo Molnar #define DO_TESTCASE_6x6(desc, name)				\
1582cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 123);			\
1583cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 132);			\
1584cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 213);			\
1585cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 231);			\
1586cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 312);			\
1587cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 321);
1588cae2ed9aSIngo Molnar 
1589cae2ed9aSIngo Molnar #define DO_TESTCASE_6x6RW(desc, name)				\
1590cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 123);			\
1591cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 132);			\
1592cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 213);			\
1593cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 231);			\
1594cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 312);			\
1595cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 321);
1596cae2ed9aSIngo Molnar 
15971de99445SMaarten Lankhorst static void ww_test_fail_acquire(void)
15981de99445SMaarten Lankhorst {
15991de99445SMaarten Lankhorst 	int ret;
16001de99445SMaarten Lankhorst 
16011de99445SMaarten Lankhorst 	WWAI(&t);
16021de99445SMaarten Lankhorst 	t.stamp++;
16031de99445SMaarten Lankhorst 
16041de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
16051de99445SMaarten Lankhorst 
16061de99445SMaarten Lankhorst 	if (WARN_ON(!o.ctx) ||
16071de99445SMaarten Lankhorst 	    WARN_ON(ret))
16081de99445SMaarten Lankhorst 		return;
16091de99445SMaarten Lankhorst 
16101de99445SMaarten Lankhorst 	/* No lockdep test, pure API */
16111de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
16121de99445SMaarten Lankhorst 	WARN_ON(ret != -EALREADY);
16131de99445SMaarten Lankhorst 
16141de99445SMaarten Lankhorst 	ret = WWT(&o);
16151de99445SMaarten Lankhorst 	WARN_ON(ret);
16161de99445SMaarten Lankhorst 
16171de99445SMaarten Lankhorst 	t2 = t;
16181de99445SMaarten Lankhorst 	t2.stamp++;
16191de99445SMaarten Lankhorst 	ret = WWL(&o, &t2);
16201de99445SMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
16211de99445SMaarten Lankhorst 	WWU(&o);
16221de99445SMaarten Lankhorst 
16231de99445SMaarten Lankhorst 	if (WWT(&o))
16241de99445SMaarten Lankhorst 		WWU(&o);
16251de99445SMaarten Lankhorst #ifdef CONFIG_DEBUG_LOCK_ALLOC
16261de99445SMaarten Lankhorst 	else
16271de99445SMaarten Lankhorst 		DEBUG_LOCKS_WARN_ON(1);
16281de99445SMaarten Lankhorst #endif
16291de99445SMaarten Lankhorst }
16301de99445SMaarten Lankhorst 
16312fe3d4b1SMaarten Lankhorst static void ww_test_normal(void)
16322fe3d4b1SMaarten Lankhorst {
16332fe3d4b1SMaarten Lankhorst 	int ret;
16342fe3d4b1SMaarten Lankhorst 
16352fe3d4b1SMaarten Lankhorst 	WWAI(&t);
16362fe3d4b1SMaarten Lankhorst 
16372fe3d4b1SMaarten Lankhorst 	/*
16382fe3d4b1SMaarten Lankhorst 	 * None of the ww_mutex codepaths should be taken in the 'normal'
16392fe3d4b1SMaarten Lankhorst 	 * mutex calls. The easiest way to verify this is by using the
16402fe3d4b1SMaarten Lankhorst 	 * normal mutex calls, and making sure o.ctx is unmodified.
16412fe3d4b1SMaarten Lankhorst 	 */
16422fe3d4b1SMaarten Lankhorst 
16432fe3d4b1SMaarten Lankhorst 	/* mutex_lock (and indirectly, mutex_lock_nested) */
16442fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
16452fe3d4b1SMaarten Lankhorst 	mutex_lock(&o.base);
16462fe3d4b1SMaarten Lankhorst 	mutex_unlock(&o.base);
16472fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
16482fe3d4b1SMaarten Lankhorst 
16492fe3d4b1SMaarten Lankhorst 	/* mutex_lock_interruptible (and *_nested) */
16502fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
16512fe3d4b1SMaarten Lankhorst 	ret = mutex_lock_interruptible(&o.base);
16522fe3d4b1SMaarten Lankhorst 	if (!ret)
16532fe3d4b1SMaarten Lankhorst 		mutex_unlock(&o.base);
16542fe3d4b1SMaarten Lankhorst 	else
16552fe3d4b1SMaarten Lankhorst 		WARN_ON(1);
16562fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
16572fe3d4b1SMaarten Lankhorst 
16582fe3d4b1SMaarten Lankhorst 	/* mutex_lock_killable (and *_nested) */
16592fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
16602fe3d4b1SMaarten Lankhorst 	ret = mutex_lock_killable(&o.base);
16612fe3d4b1SMaarten Lankhorst 	if (!ret)
16622fe3d4b1SMaarten Lankhorst 		mutex_unlock(&o.base);
16632fe3d4b1SMaarten Lankhorst 	else
16642fe3d4b1SMaarten Lankhorst 		WARN_ON(1);
16652fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
16662fe3d4b1SMaarten Lankhorst 
16672fe3d4b1SMaarten Lankhorst 	/* trylock, succeeding */
16682fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
16692fe3d4b1SMaarten Lankhorst 	ret = mutex_trylock(&o.base);
16702fe3d4b1SMaarten Lankhorst 	WARN_ON(!ret);
16712fe3d4b1SMaarten Lankhorst 	if (ret)
16722fe3d4b1SMaarten Lankhorst 		mutex_unlock(&o.base);
16732fe3d4b1SMaarten Lankhorst 	else
16742fe3d4b1SMaarten Lankhorst 		WARN_ON(1);
16752fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
16762fe3d4b1SMaarten Lankhorst 
16772fe3d4b1SMaarten Lankhorst 	/* trylock, failing */
16782fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
16792fe3d4b1SMaarten Lankhorst 	mutex_lock(&o.base);
16802fe3d4b1SMaarten Lankhorst 	ret = mutex_trylock(&o.base);
16812fe3d4b1SMaarten Lankhorst 	WARN_ON(ret);
16822fe3d4b1SMaarten Lankhorst 	mutex_unlock(&o.base);
16832fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
16842fe3d4b1SMaarten Lankhorst 
16852fe3d4b1SMaarten Lankhorst 	/* nest_lock */
16862fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
16872fe3d4b1SMaarten Lankhorst 	mutex_lock_nest_lock(&o.base, &t);
16882fe3d4b1SMaarten Lankhorst 	mutex_unlock(&o.base);
16892fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
16902fe3d4b1SMaarten Lankhorst }
16912fe3d4b1SMaarten Lankhorst 
16921de99445SMaarten Lankhorst static void ww_test_two_contexts(void)
16931de99445SMaarten Lankhorst {
16941de99445SMaarten Lankhorst 	WWAI(&t);
16951de99445SMaarten Lankhorst 	WWAI(&t2);
16961de99445SMaarten Lankhorst }
16971de99445SMaarten Lankhorst 
16981de99445SMaarten Lankhorst static void ww_test_diff_class(void)
16991de99445SMaarten Lankhorst {
17001de99445SMaarten Lankhorst 	WWAI(&t);
17011de99445SMaarten Lankhorst #ifdef CONFIG_DEBUG_MUTEXES
17021de99445SMaarten Lankhorst 	t.ww_class = NULL;
17031de99445SMaarten Lankhorst #endif
17041de99445SMaarten Lankhorst 	WWL(&o, &t);
17051de99445SMaarten Lankhorst }
17061de99445SMaarten Lankhorst 
17071de99445SMaarten Lankhorst static void ww_test_context_done_twice(void)
17081de99445SMaarten Lankhorst {
17091de99445SMaarten Lankhorst 	WWAI(&t);
17101de99445SMaarten Lankhorst 	WWAD(&t);
17111de99445SMaarten Lankhorst 	WWAD(&t);
17121de99445SMaarten Lankhorst 	WWAF(&t);
17131de99445SMaarten Lankhorst }
17141de99445SMaarten Lankhorst 
17151de99445SMaarten Lankhorst static void ww_test_context_unlock_twice(void)
17161de99445SMaarten Lankhorst {
17171de99445SMaarten Lankhorst 	WWAI(&t);
17181de99445SMaarten Lankhorst 	WWAD(&t);
17191de99445SMaarten Lankhorst 	WWAF(&t);
17201de99445SMaarten Lankhorst 	WWAF(&t);
17211de99445SMaarten Lankhorst }
17221de99445SMaarten Lankhorst 
17231de99445SMaarten Lankhorst static void ww_test_context_fini_early(void)
17241de99445SMaarten Lankhorst {
17251de99445SMaarten Lankhorst 	WWAI(&t);
17261de99445SMaarten Lankhorst 	WWL(&o, &t);
17271de99445SMaarten Lankhorst 	WWAD(&t);
17281de99445SMaarten Lankhorst 	WWAF(&t);
17291de99445SMaarten Lankhorst }
17301de99445SMaarten Lankhorst 
17311de99445SMaarten Lankhorst static void ww_test_context_lock_after_done(void)
17321de99445SMaarten Lankhorst {
17331de99445SMaarten Lankhorst 	WWAI(&t);
17341de99445SMaarten Lankhorst 	WWAD(&t);
17351de99445SMaarten Lankhorst 	WWL(&o, &t);
17361de99445SMaarten Lankhorst }
17371de99445SMaarten Lankhorst 
17381de99445SMaarten Lankhorst static void ww_test_object_unlock_twice(void)
17391de99445SMaarten Lankhorst {
17401de99445SMaarten Lankhorst 	WWL1(&o);
17411de99445SMaarten Lankhorst 	WWU(&o);
17421de99445SMaarten Lankhorst 	WWU(&o);
17431de99445SMaarten Lankhorst }
17441de99445SMaarten Lankhorst 
17451de99445SMaarten Lankhorst static void ww_test_object_lock_unbalanced(void)
17461de99445SMaarten Lankhorst {
17471de99445SMaarten Lankhorst 	WWAI(&t);
17481de99445SMaarten Lankhorst 	WWL(&o, &t);
17491de99445SMaarten Lankhorst 	t.acquired = 0;
17501de99445SMaarten Lankhorst 	WWU(&o);
17511de99445SMaarten Lankhorst 	WWAF(&t);
17521de99445SMaarten Lankhorst }
17531de99445SMaarten Lankhorst 
17541de99445SMaarten Lankhorst static void ww_test_object_lock_stale_context(void)
17551de99445SMaarten Lankhorst {
17561de99445SMaarten Lankhorst 	WWAI(&t);
17571de99445SMaarten Lankhorst 	o.ctx = &t2;
17581de99445SMaarten Lankhorst 	WWL(&o, &t);
17591de99445SMaarten Lankhorst }
17601de99445SMaarten Lankhorst 
1761f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_normal(void)
1762f3cf139eSMaarten Lankhorst {
1763f3cf139eSMaarten Lankhorst 	int ret;
1764f3cf139eSMaarten Lankhorst 
1765f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
1766f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
17675facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1768f3cf139eSMaarten Lankhorst 
1769f3cf139eSMaarten Lankhorst 	WWAI(&t);
1770f3cf139eSMaarten Lankhorst 	t2 = t;
1771f3cf139eSMaarten Lankhorst 	t2.stamp--;
1772f3cf139eSMaarten Lankhorst 
1773f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1774f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1775f3cf139eSMaarten Lankhorst 
1776f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1777f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1778f3cf139eSMaarten Lankhorst 
1779f3cf139eSMaarten Lankhorst 	o2.ctx = NULL;
1780f3cf139eSMaarten Lankhorst 	mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
1781f3cf139eSMaarten Lankhorst 	mutex_unlock(&o2.base);
1782f3cf139eSMaarten Lankhorst 	WWU(&o);
1783f3cf139eSMaarten Lankhorst 
1784f3cf139eSMaarten Lankhorst 	WWL(&o2, &t);
1785f3cf139eSMaarten Lankhorst }
1786f3cf139eSMaarten Lankhorst 
1787f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_normal_slow(void)
1788f3cf139eSMaarten Lankhorst {
1789f3cf139eSMaarten Lankhorst 	int ret;
1790f3cf139eSMaarten Lankhorst 
1791f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
17925facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1793f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1794f3cf139eSMaarten Lankhorst 
1795f3cf139eSMaarten Lankhorst 	WWAI(&t);
1796f3cf139eSMaarten Lankhorst 	t2 = t;
1797f3cf139eSMaarten Lankhorst 	t2.stamp--;
1798f3cf139eSMaarten Lankhorst 
1799f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1800f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1801f3cf139eSMaarten Lankhorst 
1802f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1803f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1804f3cf139eSMaarten Lankhorst 
1805f3cf139eSMaarten Lankhorst 	o2.ctx = NULL;
1806f3cf139eSMaarten Lankhorst 	mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
1807f3cf139eSMaarten Lankhorst 	mutex_unlock(&o2.base);
1808f3cf139eSMaarten Lankhorst 	WWU(&o);
1809f3cf139eSMaarten Lankhorst 
1810f3cf139eSMaarten Lankhorst 	ww_mutex_lock_slow(&o2, &t);
1811f3cf139eSMaarten Lankhorst }
1812f3cf139eSMaarten Lankhorst 
1813f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_no_unlock(void)
1814f3cf139eSMaarten Lankhorst {
1815f3cf139eSMaarten Lankhorst 	int ret;
1816f3cf139eSMaarten Lankhorst 
1817f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
1818f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
18195facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1820f3cf139eSMaarten Lankhorst 
1821f3cf139eSMaarten Lankhorst 	WWAI(&t);
1822f3cf139eSMaarten Lankhorst 	t2 = t;
1823f3cf139eSMaarten Lankhorst 	t2.stamp--;
1824f3cf139eSMaarten Lankhorst 
1825f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1826f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1827f3cf139eSMaarten Lankhorst 
1828f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1829f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1830f3cf139eSMaarten Lankhorst 
1831f3cf139eSMaarten Lankhorst 	o2.ctx = NULL;
1832f3cf139eSMaarten Lankhorst 	mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
1833f3cf139eSMaarten Lankhorst 	mutex_unlock(&o2.base);
1834f3cf139eSMaarten Lankhorst 
1835f3cf139eSMaarten Lankhorst 	WWL(&o2, &t);
1836f3cf139eSMaarten Lankhorst }
1837f3cf139eSMaarten Lankhorst 
1838f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_no_unlock_slow(void)
1839f3cf139eSMaarten Lankhorst {
1840f3cf139eSMaarten Lankhorst 	int ret;
1841f3cf139eSMaarten Lankhorst 
1842f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
18435facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1844f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1845f3cf139eSMaarten Lankhorst 
1846f3cf139eSMaarten Lankhorst 	WWAI(&t);
1847f3cf139eSMaarten Lankhorst 	t2 = t;
1848f3cf139eSMaarten Lankhorst 	t2.stamp--;
1849f3cf139eSMaarten Lankhorst 
1850f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1851f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1852f3cf139eSMaarten Lankhorst 
1853f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1854f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1855f3cf139eSMaarten Lankhorst 
1856f3cf139eSMaarten Lankhorst 	o2.ctx = NULL;
1857f3cf139eSMaarten Lankhorst 	mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
1858f3cf139eSMaarten Lankhorst 	mutex_unlock(&o2.base);
1859f3cf139eSMaarten Lankhorst 
1860f3cf139eSMaarten Lankhorst 	ww_mutex_lock_slow(&o2, &t);
1861f3cf139eSMaarten Lankhorst }
1862f3cf139eSMaarten Lankhorst 
1863f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_more(void)
1864f3cf139eSMaarten Lankhorst {
1865f3cf139eSMaarten Lankhorst 	int ret;
1866f3cf139eSMaarten Lankhorst 
1867f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
18685facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1869f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1870f3cf139eSMaarten Lankhorst 
1871f3cf139eSMaarten Lankhorst 	WWAI(&t);
1872f3cf139eSMaarten Lankhorst 	t2 = t;
1873f3cf139eSMaarten Lankhorst 	t2.stamp--;
1874f3cf139eSMaarten Lankhorst 
1875f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1876f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1877f3cf139eSMaarten Lankhorst 
1878f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1879f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1880f3cf139eSMaarten Lankhorst 
1881f3cf139eSMaarten Lankhorst 	ret = WWL(&o3, &t);
1882f3cf139eSMaarten Lankhorst }
1883f3cf139eSMaarten Lankhorst 
1884f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_more_slow(void)
1885f3cf139eSMaarten Lankhorst {
1886f3cf139eSMaarten Lankhorst 	int ret;
1887f3cf139eSMaarten Lankhorst 
1888f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
18895facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1890f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1891f3cf139eSMaarten Lankhorst 
1892f3cf139eSMaarten Lankhorst 	WWAI(&t);
1893f3cf139eSMaarten Lankhorst 	t2 = t;
1894f3cf139eSMaarten Lankhorst 	t2.stamp--;
1895f3cf139eSMaarten Lankhorst 
1896f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1897f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1898f3cf139eSMaarten Lankhorst 
1899f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1900f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1901f3cf139eSMaarten Lankhorst 
1902f3cf139eSMaarten Lankhorst 	ww_mutex_lock_slow(&o3, &t);
1903f3cf139eSMaarten Lankhorst }
1904f3cf139eSMaarten Lankhorst 
1905f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_more_edeadlk(void)
1906f3cf139eSMaarten Lankhorst {
1907f3cf139eSMaarten Lankhorst 	int ret;
1908f3cf139eSMaarten Lankhorst 
1909f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
19105facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1911f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1912f3cf139eSMaarten Lankhorst 
1913f3cf139eSMaarten Lankhorst 	mutex_lock(&o3.base);
19145facae4fSQian Cai 	mutex_release(&o3.base.dep_map, _THIS_IP_);
1915f3cf139eSMaarten Lankhorst 	o3.ctx = &t2;
1916f3cf139eSMaarten Lankhorst 
1917f3cf139eSMaarten Lankhorst 	WWAI(&t);
1918f3cf139eSMaarten Lankhorst 	t2 = t;
1919f3cf139eSMaarten Lankhorst 	t2.stamp--;
1920f3cf139eSMaarten Lankhorst 
1921f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1922f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1923f3cf139eSMaarten Lankhorst 
1924f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1925f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1926f3cf139eSMaarten Lankhorst 
1927f3cf139eSMaarten Lankhorst 	ret = WWL(&o3, &t);
1928f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1929f3cf139eSMaarten Lankhorst }
1930f3cf139eSMaarten Lankhorst 
1931f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_more_edeadlk_slow(void)
1932f3cf139eSMaarten Lankhorst {
1933f3cf139eSMaarten Lankhorst 	int ret;
1934f3cf139eSMaarten Lankhorst 
1935f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
19365facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1937f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1938f3cf139eSMaarten Lankhorst 
1939f3cf139eSMaarten Lankhorst 	mutex_lock(&o3.base);
19405facae4fSQian Cai 	mutex_release(&o3.base.dep_map, _THIS_IP_);
1941f3cf139eSMaarten Lankhorst 	o3.ctx = &t2;
1942f3cf139eSMaarten Lankhorst 
1943f3cf139eSMaarten Lankhorst 	WWAI(&t);
1944f3cf139eSMaarten Lankhorst 	t2 = t;
1945f3cf139eSMaarten Lankhorst 	t2.stamp--;
1946f3cf139eSMaarten Lankhorst 
1947f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1948f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1949f3cf139eSMaarten Lankhorst 
1950f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1951f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1952f3cf139eSMaarten Lankhorst 
1953f3cf139eSMaarten Lankhorst 	ww_mutex_lock_slow(&o3, &t);
1954f3cf139eSMaarten Lankhorst }
1955f3cf139eSMaarten Lankhorst 
1956f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_wrong(void)
1957f3cf139eSMaarten Lankhorst {
1958f3cf139eSMaarten Lankhorst 	int ret;
1959f3cf139eSMaarten Lankhorst 
1960f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
19615facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1962f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1963f3cf139eSMaarten Lankhorst 
1964f3cf139eSMaarten Lankhorst 	WWAI(&t);
1965f3cf139eSMaarten Lankhorst 	t2 = t;
1966f3cf139eSMaarten Lankhorst 	t2.stamp--;
1967f3cf139eSMaarten Lankhorst 
1968f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1969f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1970f3cf139eSMaarten Lankhorst 
1971f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1972f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1973f3cf139eSMaarten Lankhorst 	if (!ret)
1974f3cf139eSMaarten Lankhorst 		WWU(&o2);
1975f3cf139eSMaarten Lankhorst 
1976f3cf139eSMaarten Lankhorst 	WWU(&o);
1977f3cf139eSMaarten Lankhorst 
1978f3cf139eSMaarten Lankhorst 	ret = WWL(&o3, &t);
1979f3cf139eSMaarten Lankhorst }
1980f3cf139eSMaarten Lankhorst 
1981f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_wrong_slow(void)
1982f3cf139eSMaarten Lankhorst {
1983f3cf139eSMaarten Lankhorst 	int ret;
1984f3cf139eSMaarten Lankhorst 
1985f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
19865facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1987f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1988f3cf139eSMaarten Lankhorst 
1989f3cf139eSMaarten Lankhorst 	WWAI(&t);
1990f3cf139eSMaarten Lankhorst 	t2 = t;
1991f3cf139eSMaarten Lankhorst 	t2.stamp--;
1992f3cf139eSMaarten Lankhorst 
1993f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1994f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1995f3cf139eSMaarten Lankhorst 
1996f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1997f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1998f3cf139eSMaarten Lankhorst 	if (!ret)
1999f3cf139eSMaarten Lankhorst 		WWU(&o2);
2000f3cf139eSMaarten Lankhorst 
2001f3cf139eSMaarten Lankhorst 	WWU(&o);
2002f3cf139eSMaarten Lankhorst 
2003f3cf139eSMaarten Lankhorst 	ww_mutex_lock_slow(&o3, &t);
2004f3cf139eSMaarten Lankhorst }
2005f3cf139eSMaarten Lankhorst 
20061de99445SMaarten Lankhorst static void ww_test_spin_nest_unlocked(void)
20071de99445SMaarten Lankhorst {
2008*a2e9ae58SPeter Zijlstra 	spin_lock_nest_lock(&lock_A, &o.base);
20091de99445SMaarten Lankhorst 	U(A);
20101de99445SMaarten Lankhorst }
20111de99445SMaarten Lankhorst 
20121de99445SMaarten Lankhorst static void ww_test_unneeded_slow(void)
20131de99445SMaarten Lankhorst {
20141de99445SMaarten Lankhorst 	WWAI(&t);
20151de99445SMaarten Lankhorst 
20161de99445SMaarten Lankhorst 	ww_mutex_lock_slow(&o, &t);
20171de99445SMaarten Lankhorst }
20181de99445SMaarten Lankhorst 
20191de99445SMaarten Lankhorst static void ww_test_context_block(void)
20201de99445SMaarten Lankhorst {
20211de99445SMaarten Lankhorst 	int ret;
20221de99445SMaarten Lankhorst 
20231de99445SMaarten Lankhorst 	WWAI(&t);
20241de99445SMaarten Lankhorst 
20251de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
20261de99445SMaarten Lankhorst 	WARN_ON(ret);
20271de99445SMaarten Lankhorst 	WWL1(&o2);
20281de99445SMaarten Lankhorst }
20291de99445SMaarten Lankhorst 
20301de99445SMaarten Lankhorst static void ww_test_context_try(void)
20311de99445SMaarten Lankhorst {
20321de99445SMaarten Lankhorst 	int ret;
20331de99445SMaarten Lankhorst 
20341de99445SMaarten Lankhorst 	WWAI(&t);
20351de99445SMaarten Lankhorst 
20361de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
20371de99445SMaarten Lankhorst 	WARN_ON(ret);
20381de99445SMaarten Lankhorst 
20391de99445SMaarten Lankhorst 	ret = WWT(&o2);
20401de99445SMaarten Lankhorst 	WARN_ON(!ret);
20411de99445SMaarten Lankhorst 	WWU(&o2);
20421de99445SMaarten Lankhorst 	WWU(&o);
20431de99445SMaarten Lankhorst }
20441de99445SMaarten Lankhorst 
20451de99445SMaarten Lankhorst static void ww_test_context_context(void)
20461de99445SMaarten Lankhorst {
20471de99445SMaarten Lankhorst 	int ret;
20481de99445SMaarten Lankhorst 
20491de99445SMaarten Lankhorst 	WWAI(&t);
20501de99445SMaarten Lankhorst 
20511de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
20521de99445SMaarten Lankhorst 	WARN_ON(ret);
20531de99445SMaarten Lankhorst 
20541de99445SMaarten Lankhorst 	ret = WWL(&o2, &t);
20551de99445SMaarten Lankhorst 	WARN_ON(ret);
20561de99445SMaarten Lankhorst 
20571de99445SMaarten Lankhorst 	WWU(&o2);
20581de99445SMaarten Lankhorst 	WWU(&o);
20591de99445SMaarten Lankhorst }
20601de99445SMaarten Lankhorst 
20611de99445SMaarten Lankhorst static void ww_test_try_block(void)
20621de99445SMaarten Lankhorst {
20631de99445SMaarten Lankhorst 	bool ret;
20641de99445SMaarten Lankhorst 
20651de99445SMaarten Lankhorst 	ret = WWT(&o);
20661de99445SMaarten Lankhorst 	WARN_ON(!ret);
20671de99445SMaarten Lankhorst 
20681de99445SMaarten Lankhorst 	WWL1(&o2);
20691de99445SMaarten Lankhorst 	WWU(&o2);
20701de99445SMaarten Lankhorst 	WWU(&o);
20711de99445SMaarten Lankhorst }
20721de99445SMaarten Lankhorst 
20731de99445SMaarten Lankhorst static void ww_test_try_try(void)
20741de99445SMaarten Lankhorst {
20751de99445SMaarten Lankhorst 	bool ret;
20761de99445SMaarten Lankhorst 
20771de99445SMaarten Lankhorst 	ret = WWT(&o);
20781de99445SMaarten Lankhorst 	WARN_ON(!ret);
20791de99445SMaarten Lankhorst 	ret = WWT(&o2);
20801de99445SMaarten Lankhorst 	WARN_ON(!ret);
20811de99445SMaarten Lankhorst 	WWU(&o2);
20821de99445SMaarten Lankhorst 	WWU(&o);
20831de99445SMaarten Lankhorst }
20841de99445SMaarten Lankhorst 
20851de99445SMaarten Lankhorst static void ww_test_try_context(void)
20861de99445SMaarten Lankhorst {
20871de99445SMaarten Lankhorst 	int ret;
20881de99445SMaarten Lankhorst 
20891de99445SMaarten Lankhorst 	ret = WWT(&o);
20901de99445SMaarten Lankhorst 	WARN_ON(!ret);
20911de99445SMaarten Lankhorst 
20921de99445SMaarten Lankhorst 	WWAI(&t);
20931de99445SMaarten Lankhorst 
20941de99445SMaarten Lankhorst 	ret = WWL(&o2, &t);
20951de99445SMaarten Lankhorst 	WARN_ON(ret);
20961de99445SMaarten Lankhorst }
20971de99445SMaarten Lankhorst 
20981de99445SMaarten Lankhorst static void ww_test_block_block(void)
20991de99445SMaarten Lankhorst {
21001de99445SMaarten Lankhorst 	WWL1(&o);
21011de99445SMaarten Lankhorst 	WWL1(&o2);
21021de99445SMaarten Lankhorst }
21031de99445SMaarten Lankhorst 
21041de99445SMaarten Lankhorst static void ww_test_block_try(void)
21051de99445SMaarten Lankhorst {
21061de99445SMaarten Lankhorst 	bool ret;
21071de99445SMaarten Lankhorst 
21081de99445SMaarten Lankhorst 	WWL1(&o);
21091de99445SMaarten Lankhorst 	ret = WWT(&o2);
21101de99445SMaarten Lankhorst 	WARN_ON(!ret);
21111de99445SMaarten Lankhorst }
21121de99445SMaarten Lankhorst 
21131de99445SMaarten Lankhorst static void ww_test_block_context(void)
21141de99445SMaarten Lankhorst {
21151de99445SMaarten Lankhorst 	int ret;
21161de99445SMaarten Lankhorst 
21171de99445SMaarten Lankhorst 	WWL1(&o);
21181de99445SMaarten Lankhorst 	WWAI(&t);
21191de99445SMaarten Lankhorst 
21201de99445SMaarten Lankhorst 	ret = WWL(&o2, &t);
21211de99445SMaarten Lankhorst 	WARN_ON(ret);
21221de99445SMaarten Lankhorst }
21231de99445SMaarten Lankhorst 
21241de99445SMaarten Lankhorst static void ww_test_spin_block(void)
21251de99445SMaarten Lankhorst {
21261de99445SMaarten Lankhorst 	L(A);
21271de99445SMaarten Lankhorst 	U(A);
21281de99445SMaarten Lankhorst 
21291de99445SMaarten Lankhorst 	WWL1(&o);
21301de99445SMaarten Lankhorst 	L(A);
21311de99445SMaarten Lankhorst 	U(A);
21321de99445SMaarten Lankhorst 	WWU(&o);
21331de99445SMaarten Lankhorst 
21341de99445SMaarten Lankhorst 	L(A);
21351de99445SMaarten Lankhorst 	WWL1(&o);
21361de99445SMaarten Lankhorst 	WWU(&o);
21371de99445SMaarten Lankhorst 	U(A);
21381de99445SMaarten Lankhorst }
21391de99445SMaarten Lankhorst 
21401de99445SMaarten Lankhorst static void ww_test_spin_try(void)
21411de99445SMaarten Lankhorst {
21421de99445SMaarten Lankhorst 	bool ret;
21431de99445SMaarten Lankhorst 
21441de99445SMaarten Lankhorst 	L(A);
21451de99445SMaarten Lankhorst 	U(A);
21461de99445SMaarten Lankhorst 
21471de99445SMaarten Lankhorst 	ret = WWT(&o);
21481de99445SMaarten Lankhorst 	WARN_ON(!ret);
21491de99445SMaarten Lankhorst 	L(A);
21501de99445SMaarten Lankhorst 	U(A);
21511de99445SMaarten Lankhorst 	WWU(&o);
21521de99445SMaarten Lankhorst 
21531de99445SMaarten Lankhorst 	L(A);
21541de99445SMaarten Lankhorst 	ret = WWT(&o);
21551de99445SMaarten Lankhorst 	WARN_ON(!ret);
21561de99445SMaarten Lankhorst 	WWU(&o);
21571de99445SMaarten Lankhorst 	U(A);
21581de99445SMaarten Lankhorst }
21591de99445SMaarten Lankhorst 
21601de99445SMaarten Lankhorst static void ww_test_spin_context(void)
21611de99445SMaarten Lankhorst {
21621de99445SMaarten Lankhorst 	int ret;
21631de99445SMaarten Lankhorst 
21641de99445SMaarten Lankhorst 	L(A);
21651de99445SMaarten Lankhorst 	U(A);
21661de99445SMaarten Lankhorst 
21671de99445SMaarten Lankhorst 	WWAI(&t);
21681de99445SMaarten Lankhorst 
21691de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
21701de99445SMaarten Lankhorst 	WARN_ON(ret);
21711de99445SMaarten Lankhorst 	L(A);
21721de99445SMaarten Lankhorst 	U(A);
21731de99445SMaarten Lankhorst 	WWU(&o);
21741de99445SMaarten Lankhorst 
21751de99445SMaarten Lankhorst 	L(A);
21761de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
21771de99445SMaarten Lankhorst 	WARN_ON(ret);
21781de99445SMaarten Lankhorst 	WWU(&o);
21791de99445SMaarten Lankhorst 	U(A);
21801de99445SMaarten Lankhorst }
21811de99445SMaarten Lankhorst 
21821de99445SMaarten Lankhorst static void ww_tests(void)
21831de99445SMaarten Lankhorst {
21841de99445SMaarten Lankhorst 	printk("  --------------------------------------------------------------------------\n");
21851de99445SMaarten Lankhorst 	printk("  | Wound/wait tests |\n");
21861de99445SMaarten Lankhorst 	printk("  ---------------------\n");
21871de99445SMaarten Lankhorst 
21881de99445SMaarten Lankhorst 	print_testname("ww api failures");
21891de99445SMaarten Lankhorst 	dotest(ww_test_fail_acquire, SUCCESS, LOCKTYPE_WW);
21902fe3d4b1SMaarten Lankhorst 	dotest(ww_test_normal, SUCCESS, LOCKTYPE_WW);
21911de99445SMaarten Lankhorst 	dotest(ww_test_unneeded_slow, FAILURE, LOCKTYPE_WW);
219225139409SMichael Ellerman 	pr_cont("\n");
21931de99445SMaarten Lankhorst 
21941de99445SMaarten Lankhorst 	print_testname("ww contexts mixing");
21951de99445SMaarten Lankhorst 	dotest(ww_test_two_contexts, FAILURE, LOCKTYPE_WW);
21961de99445SMaarten Lankhorst 	dotest(ww_test_diff_class, FAILURE, LOCKTYPE_WW);
219725139409SMichael Ellerman 	pr_cont("\n");
21981de99445SMaarten Lankhorst 
21991de99445SMaarten Lankhorst 	print_testname("finishing ww context");
22001de99445SMaarten Lankhorst 	dotest(ww_test_context_done_twice, FAILURE, LOCKTYPE_WW);
22011de99445SMaarten Lankhorst 	dotest(ww_test_context_unlock_twice, FAILURE, LOCKTYPE_WW);
22021de99445SMaarten Lankhorst 	dotest(ww_test_context_fini_early, FAILURE, LOCKTYPE_WW);
22031de99445SMaarten Lankhorst 	dotest(ww_test_context_lock_after_done, FAILURE, LOCKTYPE_WW);
220425139409SMichael Ellerman 	pr_cont("\n");
22051de99445SMaarten Lankhorst 
22061de99445SMaarten Lankhorst 	print_testname("locking mismatches");
22071de99445SMaarten Lankhorst 	dotest(ww_test_object_unlock_twice, FAILURE, LOCKTYPE_WW);
22081de99445SMaarten Lankhorst 	dotest(ww_test_object_lock_unbalanced, FAILURE, LOCKTYPE_WW);
22091de99445SMaarten Lankhorst 	dotest(ww_test_object_lock_stale_context, FAILURE, LOCKTYPE_WW);
221025139409SMichael Ellerman 	pr_cont("\n");
22111de99445SMaarten Lankhorst 
2212f3cf139eSMaarten Lankhorst 	print_testname("EDEADLK handling");
2213f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_normal, SUCCESS, LOCKTYPE_WW);
2214f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_normal_slow, SUCCESS, LOCKTYPE_WW);
2215f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_no_unlock, FAILURE, LOCKTYPE_WW);
2216f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_no_unlock_slow, FAILURE, LOCKTYPE_WW);
2217f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_more, FAILURE, LOCKTYPE_WW);
2218f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_more_slow, FAILURE, LOCKTYPE_WW);
2219f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_more_edeadlk, FAILURE, LOCKTYPE_WW);
2220f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_more_edeadlk_slow, FAILURE, LOCKTYPE_WW);
2221f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_wrong, FAILURE, LOCKTYPE_WW);
2222f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_wrong_slow, FAILURE, LOCKTYPE_WW);
222325139409SMichael Ellerman 	pr_cont("\n");
2224f3cf139eSMaarten Lankhorst 
22251de99445SMaarten Lankhorst 	print_testname("spinlock nest unlocked");
22261de99445SMaarten Lankhorst 	dotest(ww_test_spin_nest_unlocked, FAILURE, LOCKTYPE_WW);
222725139409SMichael Ellerman 	pr_cont("\n");
22281de99445SMaarten Lankhorst 
22291de99445SMaarten Lankhorst 	printk("  -----------------------------------------------------\n");
22301de99445SMaarten Lankhorst 	printk("                                 |block | try  |context|\n");
22311de99445SMaarten Lankhorst 	printk("  -----------------------------------------------------\n");
22321de99445SMaarten Lankhorst 
22331de99445SMaarten Lankhorst 	print_testname("context");
22341de99445SMaarten Lankhorst 	dotest(ww_test_context_block, FAILURE, LOCKTYPE_WW);
22351de99445SMaarten Lankhorst 	dotest(ww_test_context_try, SUCCESS, LOCKTYPE_WW);
22361de99445SMaarten Lankhorst 	dotest(ww_test_context_context, SUCCESS, LOCKTYPE_WW);
223725139409SMichael Ellerman 	pr_cont("\n");
22381de99445SMaarten Lankhorst 
22391de99445SMaarten Lankhorst 	print_testname("try");
22401de99445SMaarten Lankhorst 	dotest(ww_test_try_block, FAILURE, LOCKTYPE_WW);
22411de99445SMaarten Lankhorst 	dotest(ww_test_try_try, SUCCESS, LOCKTYPE_WW);
22421de99445SMaarten Lankhorst 	dotest(ww_test_try_context, FAILURE, LOCKTYPE_WW);
224325139409SMichael Ellerman 	pr_cont("\n");
22441de99445SMaarten Lankhorst 
22451de99445SMaarten Lankhorst 	print_testname("block");
22461de99445SMaarten Lankhorst 	dotest(ww_test_block_block, FAILURE, LOCKTYPE_WW);
22471de99445SMaarten Lankhorst 	dotest(ww_test_block_try, SUCCESS, LOCKTYPE_WW);
22481de99445SMaarten Lankhorst 	dotest(ww_test_block_context, FAILURE, LOCKTYPE_WW);
224925139409SMichael Ellerman 	pr_cont("\n");
22501de99445SMaarten Lankhorst 
22511de99445SMaarten Lankhorst 	print_testname("spinlock");
22521de99445SMaarten Lankhorst 	dotest(ww_test_spin_block, FAILURE, LOCKTYPE_WW);
22531de99445SMaarten Lankhorst 	dotest(ww_test_spin_try, SUCCESS, LOCKTYPE_WW);
22541de99445SMaarten Lankhorst 	dotest(ww_test_spin_context, FAILURE, LOCKTYPE_WW);
225525139409SMichael Ellerman 	pr_cont("\n");
22561de99445SMaarten Lankhorst }
2257cae2ed9aSIngo Molnar 
2258ad56450dSBoqun Feng 
2259ad56450dSBoqun Feng /*
2260ad56450dSBoqun Feng  * <in hardirq handler>
2261ad56450dSBoqun Feng  * read_lock(&A);
2262ad56450dSBoqun Feng  *			<hardirq disable>
2263ad56450dSBoqun Feng  *			spin_lock(&B);
2264ad56450dSBoqun Feng  * spin_lock(&B);
2265ad56450dSBoqun Feng  *			read_lock(&A);
2266ad56450dSBoqun Feng  *
2267ad56450dSBoqun Feng  * is a deadlock.
2268ad56450dSBoqun Feng  */
2269ad56450dSBoqun Feng static void queued_read_lock_hardirq_RE_Er(void)
2270ad56450dSBoqun Feng {
2271ad56450dSBoqun Feng 	HARDIRQ_ENTER();
2272ad56450dSBoqun Feng 	read_lock(&rwlock_A);
2273ad56450dSBoqun Feng 	LOCK(B);
2274ad56450dSBoqun Feng 	UNLOCK(B);
2275ad56450dSBoqun Feng 	read_unlock(&rwlock_A);
2276ad56450dSBoqun Feng 	HARDIRQ_EXIT();
2277ad56450dSBoqun Feng 
2278ad56450dSBoqun Feng 	HARDIRQ_DISABLE();
2279ad56450dSBoqun Feng 	LOCK(B);
2280ad56450dSBoqun Feng 	read_lock(&rwlock_A);
2281ad56450dSBoqun Feng 	read_unlock(&rwlock_A);
2282ad56450dSBoqun Feng 	UNLOCK(B);
2283ad56450dSBoqun Feng 	HARDIRQ_ENABLE();
2284ad56450dSBoqun Feng }
2285ad56450dSBoqun Feng 
2286ad56450dSBoqun Feng /*
2287ad56450dSBoqun Feng  * <in hardirq handler>
2288ad56450dSBoqun Feng  * spin_lock(&B);
2289ad56450dSBoqun Feng  *			<hardirq disable>
2290ad56450dSBoqun Feng  *			read_lock(&A);
2291ad56450dSBoqun Feng  * read_lock(&A);
2292ad56450dSBoqun Feng  *			spin_lock(&B);
2293ad56450dSBoqun Feng  *
2294ad56450dSBoqun Feng  * is not a deadlock.
2295ad56450dSBoqun Feng  */
2296ad56450dSBoqun Feng static void queued_read_lock_hardirq_ER_rE(void)
2297ad56450dSBoqun Feng {
2298ad56450dSBoqun Feng 	HARDIRQ_ENTER();
2299ad56450dSBoqun Feng 	LOCK(B);
2300ad56450dSBoqun Feng 	read_lock(&rwlock_A);
2301ad56450dSBoqun Feng 	read_unlock(&rwlock_A);
2302ad56450dSBoqun Feng 	UNLOCK(B);
2303ad56450dSBoqun Feng 	HARDIRQ_EXIT();
2304ad56450dSBoqun Feng 
2305ad56450dSBoqun Feng 	HARDIRQ_DISABLE();
2306ad56450dSBoqun Feng 	read_lock(&rwlock_A);
2307ad56450dSBoqun Feng 	LOCK(B);
2308ad56450dSBoqun Feng 	UNLOCK(B);
2309ad56450dSBoqun Feng 	read_unlock(&rwlock_A);
2310ad56450dSBoqun Feng 	HARDIRQ_ENABLE();
2311ad56450dSBoqun Feng }
2312ad56450dSBoqun Feng 
2313ad56450dSBoqun Feng /*
2314ad56450dSBoqun Feng  * <hardirq disable>
2315ad56450dSBoqun Feng  * spin_lock(&B);
2316ad56450dSBoqun Feng  *			read_lock(&A);
2317ad56450dSBoqun Feng  *			<in hardirq handler>
2318ad56450dSBoqun Feng  *			spin_lock(&B);
2319ad56450dSBoqun Feng  * read_lock(&A);
2320ad56450dSBoqun Feng  *
2321ad56450dSBoqun Feng  * is a deadlock. Because the two read_lock()s are both non-recursive readers.
2322ad56450dSBoqun Feng  */
2323ad56450dSBoqun Feng static void queued_read_lock_hardirq_inversion(void)
2324ad56450dSBoqun Feng {
2325ad56450dSBoqun Feng 
2326ad56450dSBoqun Feng 	HARDIRQ_ENTER();
2327ad56450dSBoqun Feng 	LOCK(B);
2328ad56450dSBoqun Feng 	UNLOCK(B);
2329ad56450dSBoqun Feng 	HARDIRQ_EXIT();
2330ad56450dSBoqun Feng 
2331ad56450dSBoqun Feng 	HARDIRQ_DISABLE();
2332ad56450dSBoqun Feng 	LOCK(B);
2333ad56450dSBoqun Feng 	read_lock(&rwlock_A);
2334ad56450dSBoqun Feng 	read_unlock(&rwlock_A);
2335ad56450dSBoqun Feng 	UNLOCK(B);
2336ad56450dSBoqun Feng 	HARDIRQ_ENABLE();
2337ad56450dSBoqun Feng 
2338ad56450dSBoqun Feng 	read_lock(&rwlock_A);
2339ad56450dSBoqun Feng 	read_unlock(&rwlock_A);
2340ad56450dSBoqun Feng }
2341ad56450dSBoqun Feng 
2342ad56450dSBoqun Feng static void queued_read_lock_tests(void)
2343ad56450dSBoqun Feng {
2344ad56450dSBoqun Feng 	printk("  --------------------------------------------------------------------------\n");
2345ad56450dSBoqun Feng 	printk("  | queued read lock tests |\n");
2346ad56450dSBoqun Feng 	printk("  ---------------------------\n");
2347ad56450dSBoqun Feng 	print_testname("hardirq read-lock/lock-read");
2348ad56450dSBoqun Feng 	dotest(queued_read_lock_hardirq_RE_Er, FAILURE, LOCKTYPE_RWLOCK);
2349ad56450dSBoqun Feng 	pr_cont("\n");
2350ad56450dSBoqun Feng 
2351ad56450dSBoqun Feng 	print_testname("hardirq lock-read/read-lock");
2352ad56450dSBoqun Feng 	dotest(queued_read_lock_hardirq_ER_rE, SUCCESS, LOCKTYPE_RWLOCK);
2353ad56450dSBoqun Feng 	pr_cont("\n");
2354ad56450dSBoqun Feng 
2355ad56450dSBoqun Feng 	print_testname("hardirq inversion");
2356ad56450dSBoqun Feng 	dotest(queued_read_lock_hardirq_inversion, FAILURE, LOCKTYPE_RWLOCK);
2357ad56450dSBoqun Feng 	pr_cont("\n");
2358ad56450dSBoqun Feng }
2359ad56450dSBoqun Feng 
2360cae2ed9aSIngo Molnar void locking_selftest(void)
2361cae2ed9aSIngo Molnar {
2362cae2ed9aSIngo Molnar 	/*
2363cae2ed9aSIngo Molnar 	 * Got a locking failure before the selftest ran?
2364cae2ed9aSIngo Molnar 	 */
2365cae2ed9aSIngo Molnar 	if (!debug_locks) {
2366cae2ed9aSIngo Molnar 		printk("----------------------------------\n");
2367cae2ed9aSIngo Molnar 		printk("| Locking API testsuite disabled |\n");
2368cae2ed9aSIngo Molnar 		printk("----------------------------------\n");
2369cae2ed9aSIngo Molnar 		return;
2370cae2ed9aSIngo Molnar 	}
2371cae2ed9aSIngo Molnar 
2372cae2ed9aSIngo Molnar 	/*
2373e9181886SBoqun Feng 	 * treats read_lock() as recursive read locks for testing purpose
2374e9181886SBoqun Feng 	 */
2375e9181886SBoqun Feng 	force_read_lock_recursive = 1;
2376e9181886SBoqun Feng 
2377e9181886SBoqun Feng 	/*
2378cae2ed9aSIngo Molnar 	 * Run the testsuite:
2379cae2ed9aSIngo Molnar 	 */
2380cae2ed9aSIngo Molnar 	printk("------------------------\n");
2381cae2ed9aSIngo Molnar 	printk("| Locking API testsuite:\n");
2382cae2ed9aSIngo Molnar 	printk("----------------------------------------------------------------------------\n");
2383cae2ed9aSIngo Molnar 	printk("                                 | spin |wlock |rlock |mutex | wsem | rsem |\n");
2384cae2ed9aSIngo Molnar 	printk("  --------------------------------------------------------------------------\n");
2385cae2ed9aSIngo Molnar 
2386cae2ed9aSIngo Molnar 	init_shared_classes();
2387cae2ed9aSIngo Molnar 	debug_locks_silent = !debug_locks_verbose;
2388cdc84d79SBart Van Assche 	lockdep_set_selftest_task(current);
2389cae2ed9aSIngo Molnar 
23906c9076ecSIngo Molnar 	DO_TESTCASE_6R("A-A deadlock", AA);
2391cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-B-A deadlock", ABBA);
2392cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-B-C-C-A deadlock", ABBCCA);
2393cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-C-A-B-C deadlock", ABCABC);
2394cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-B-C-C-D-D-A deadlock", ABBCCDDA);
2395cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-C-D-B-D-D-A deadlock", ABCDBDDA);
2396cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-C-D-B-C-D-A deadlock", ABCDBCDA);
2397cae2ed9aSIngo Molnar 	DO_TESTCASE_6("double unlock", double_unlock);
2398cae2ed9aSIngo Molnar 	DO_TESTCASE_6("initialize held", init_held);
2399cae2ed9aSIngo Molnar 
2400cae2ed9aSIngo Molnar 	printk("  --------------------------------------------------------------------------\n");
2401cae2ed9aSIngo Molnar 	print_testname("recursive read-lock");
240225139409SMichael Ellerman 	pr_cont("             |");
2403cae2ed9aSIngo Molnar 	dotest(rlock_AA1, SUCCESS, LOCKTYPE_RWLOCK);
240425139409SMichael Ellerman 	pr_cont("             |");
2405cae2ed9aSIngo Molnar 	dotest(rsem_AA1, FAILURE, LOCKTYPE_RWSEM);
240625139409SMichael Ellerman 	pr_cont("\n");
2407cae2ed9aSIngo Molnar 
2408cae2ed9aSIngo Molnar 	print_testname("recursive read-lock #2");
240925139409SMichael Ellerman 	pr_cont("             |");
24106c9076ecSIngo Molnar 	dotest(rlock_AA1B, SUCCESS, LOCKTYPE_RWLOCK);
241125139409SMichael Ellerman 	pr_cont("             |");
2412cae2ed9aSIngo Molnar 	dotest(rsem_AA1B, FAILURE, LOCKTYPE_RWSEM);
241325139409SMichael Ellerman 	pr_cont("\n");
2414cae2ed9aSIngo Molnar 
2415cae2ed9aSIngo Molnar 	print_testname("mixed read-write-lock");
241625139409SMichael Ellerman 	pr_cont("             |");
2417cae2ed9aSIngo Molnar 	dotest(rlock_AA2, FAILURE, LOCKTYPE_RWLOCK);
241825139409SMichael Ellerman 	pr_cont("             |");
2419cae2ed9aSIngo Molnar 	dotest(rsem_AA2, FAILURE, LOCKTYPE_RWSEM);
242025139409SMichael Ellerman 	pr_cont("\n");
2421cae2ed9aSIngo Molnar 
2422cae2ed9aSIngo Molnar 	print_testname("mixed write-read-lock");
242325139409SMichael Ellerman 	pr_cont("             |");
2424cae2ed9aSIngo Molnar 	dotest(rlock_AA3, FAILURE, LOCKTYPE_RWLOCK);
242525139409SMichael Ellerman 	pr_cont("             |");
2426cae2ed9aSIngo Molnar 	dotest(rsem_AA3, FAILURE, LOCKTYPE_RWSEM);
242725139409SMichael Ellerman 	pr_cont("\n");
2428cae2ed9aSIngo Molnar 
2429e9149858SPeter Zijlstra 	print_testname("mixed read-lock/lock-write ABBA");
2430e9149858SPeter Zijlstra 	pr_cont("             |");
2431e9149858SPeter Zijlstra 	dotest(rlock_ABBA1, FAILURE, LOCKTYPE_RWLOCK);
2432e9149858SPeter Zijlstra 	pr_cont("             |");
2433e9149858SPeter Zijlstra 	dotest(rwsem_ABBA1, FAILURE, LOCKTYPE_RWSEM);
2434e9149858SPeter Zijlstra 
2435e9149858SPeter Zijlstra 	print_testname("mixed read-lock/lock-read ABBA");
2436e9149858SPeter Zijlstra 	pr_cont("             |");
2437e9149858SPeter Zijlstra 	dotest(rlock_ABBA2, SUCCESS, LOCKTYPE_RWLOCK);
2438e9149858SPeter Zijlstra 	pr_cont("             |");
2439e9149858SPeter Zijlstra 	dotest(rwsem_ABBA2, FAILURE, LOCKTYPE_RWSEM);
2440e9149858SPeter Zijlstra 
2441e9149858SPeter Zijlstra 	print_testname("mixed write-lock/lock-write ABBA");
2442e9149858SPeter Zijlstra 	pr_cont("             |");
2443e9149858SPeter Zijlstra 	dotest(rlock_ABBA3, FAILURE, LOCKTYPE_RWLOCK);
2444e9149858SPeter Zijlstra 	pr_cont("             |");
2445e9149858SPeter Zijlstra 	dotest(rwsem_ABBA3, FAILURE, LOCKTYPE_RWSEM);
2446e9149858SPeter Zijlstra 
2447d4f200e5SBoqun Feng 	print_testname("chain cached mixed R-L/L-W ABBA");
2448d4f200e5SBoqun Feng 	pr_cont("             |");
2449d4f200e5SBoqun Feng 	dotest(rlock_chaincache_ABBA1, FAILURE, LOCKTYPE_RWLOCK);
2450d4f200e5SBoqun Feng 
24518ef7ca75SBoqun Feng 	DO_TESTCASE_6x1RRB("rlock W1R2/W2R3/W3R1", W1R2_W2R3_W3R1);
24528ef7ca75SBoqun Feng 	DO_TESTCASE_6x1RRB("rlock W1W2/R2R3/W3R1", W1W2_R2R3_W3R1);
24538ef7ca75SBoqun Feng 	DO_TESTCASE_6x1RR("rlock W1W2/R2R3/R3W1", W1W2_R2R3_R3W1);
24548ef7ca75SBoqun Feng 	DO_TESTCASE_6x1RR("rlock W1R2/R2R3/W3W1", W1R2_R2R3_W3W1);
24558ef7ca75SBoqun Feng 
2456cae2ed9aSIngo Molnar 	printk("  --------------------------------------------------------------------------\n");
2457cae2ed9aSIngo Molnar 
2458cae2ed9aSIngo Molnar 	/*
2459cae2ed9aSIngo Molnar 	 * irq-context testcases:
2460cae2ed9aSIngo Molnar 	 */
2461cae2ed9aSIngo Molnar 	DO_TESTCASE_2x6("irqs-on + irq-safe-A", irqsafe1);
2462cae2ed9aSIngo Molnar 	DO_TESTCASE_2x3("sirq-safe-A => hirqs-on", irqsafe2A);
2463cae2ed9aSIngo Molnar 	DO_TESTCASE_2x6("safe-A + irqs-on", irqsafe2B);
2464cae2ed9aSIngo Molnar 	DO_TESTCASE_6x6("safe-A + unsafe-B #1", irqsafe3);
2465cae2ed9aSIngo Molnar 	DO_TESTCASE_6x6("safe-A + unsafe-B #2", irqsafe4);
2466cae2ed9aSIngo Molnar 	DO_TESTCASE_6x6RW("irq lock-inversion", irq_inversion);
2467cae2ed9aSIngo Molnar 
246831e0d747SBoqun Feng 	DO_TESTCASE_6x2x2RW("irq read-recursion", irq_read_recursion);
246931e0d747SBoqun Feng 	DO_TESTCASE_6x2x2RW("irq read-recursion #2", irq_read_recursion2);
247096a16f45SBoqun Feng 	DO_TESTCASE_6x2x2RW("irq read-recursion #3", irq_read_recursion3);
2471cae2ed9aSIngo Molnar 
24721de99445SMaarten Lankhorst 	ww_tests();
24731de99445SMaarten Lankhorst 
2474e9181886SBoqun Feng 	force_read_lock_recursive = 0;
2475e9181886SBoqun Feng 	/*
2476e9181886SBoqun Feng 	 * queued_read_lock() specific test cases can be put here
2477e9181886SBoqun Feng 	 */
2478ad56450dSBoqun Feng 	if (IS_ENABLED(CONFIG_QUEUED_RWLOCKS))
2479ad56450dSBoqun Feng 		queued_read_lock_tests();
2480e9181886SBoqun Feng 
2481cae2ed9aSIngo Molnar 	if (unexpected_testcase_failures) {
2482cae2ed9aSIngo Molnar 		printk("-----------------------------------------------------------------\n");
2483cae2ed9aSIngo Molnar 		debug_locks = 0;
2484cae2ed9aSIngo Molnar 		printk("BUG: %3d unexpected failures (out of %3d) - debugging disabled! |\n",
2485cae2ed9aSIngo Molnar 			unexpected_testcase_failures, testcase_total);
2486cae2ed9aSIngo Molnar 		printk("-----------------------------------------------------------------\n");
2487cae2ed9aSIngo Molnar 	} else if (expected_testcase_failures && testcase_successes) {
2488cae2ed9aSIngo Molnar 		printk("--------------------------------------------------------\n");
2489cae2ed9aSIngo Molnar 		printk("%3d out of %3d testcases failed, as expected. |\n",
2490cae2ed9aSIngo Molnar 			expected_testcase_failures, testcase_total);
2491cae2ed9aSIngo Molnar 		printk("----------------------------------------------------\n");
2492cae2ed9aSIngo Molnar 		debug_locks = 1;
2493cae2ed9aSIngo Molnar 	} else if (expected_testcase_failures && !testcase_successes) {
2494cae2ed9aSIngo Molnar 		printk("--------------------------------------------------------\n");
2495cae2ed9aSIngo Molnar 		printk("All %3d testcases failed, as expected. |\n",
2496cae2ed9aSIngo Molnar 			expected_testcase_failures);
2497cae2ed9aSIngo Molnar 		printk("----------------------------------------\n");
2498cae2ed9aSIngo Molnar 		debug_locks = 1;
2499cae2ed9aSIngo Molnar 	} else {
2500cae2ed9aSIngo Molnar 		printk("-------------------------------------------------------\n");
2501cae2ed9aSIngo Molnar 		printk("Good, all %3d testcases passed! |\n",
2502cae2ed9aSIngo Molnar 			testcase_successes);
2503cae2ed9aSIngo Molnar 		printk("---------------------------------\n");
2504cae2ed9aSIngo Molnar 		debug_locks = 1;
2505cae2ed9aSIngo Molnar 	}
2506cdc84d79SBart Van Assche 	lockdep_set_selftest_task(NULL);
2507cae2ed9aSIngo Molnar 	debug_locks_silent = 0;
2508cae2ed9aSIngo Molnar }
2509