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