xref: /linux-6.15/lib/locking-selftest.c (revision e9181886)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2cae2ed9aSIngo Molnar /*
3cae2ed9aSIngo Molnar  * lib/locking-selftest.c
4cae2ed9aSIngo Molnar  *
5cae2ed9aSIngo Molnar  * Testsuite for various locking APIs: spinlocks, rwlocks,
6cae2ed9aSIngo Molnar  * mutexes and rw-semaphores.
7cae2ed9aSIngo Molnar  *
8cae2ed9aSIngo Molnar  * It is checking both false positives and false negatives.
9cae2ed9aSIngo Molnar  *
10cae2ed9aSIngo Molnar  * Started by Ingo Molnar:
11cae2ed9aSIngo Molnar  *
12cae2ed9aSIngo Molnar  *  Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <[email protected]>
13cae2ed9aSIngo Molnar  */
14cae2ed9aSIngo Molnar #include <linux/rwsem.h>
15cae2ed9aSIngo Molnar #include <linux/mutex.h>
161b375dc3SMaarten Lankhorst #include <linux/ww_mutex.h>
17cae2ed9aSIngo Molnar #include <linux/sched.h>
18cae2ed9aSIngo Molnar #include <linux/delay.h>
19fbb9ce95SIngo Molnar #include <linux/lockdep.h>
20cae2ed9aSIngo Molnar #include <linux/spinlock.h>
21cae2ed9aSIngo Molnar #include <linux/kallsyms.h>
22cae2ed9aSIngo Molnar #include <linux/interrupt.h>
23cae2ed9aSIngo Molnar #include <linux/debug_locks.h>
24cae2ed9aSIngo Molnar #include <linux/irqflags.h>
25018956d6SPeter Zijlstra #include <linux/rtmutex.h>
26cae2ed9aSIngo Molnar 
27cae2ed9aSIngo Molnar /*
28cae2ed9aSIngo Molnar  * Change this to 1 if you want to see the failure printouts:
29cae2ed9aSIngo Molnar  */
30cae2ed9aSIngo Molnar static unsigned int debug_locks_verbose;
31*e9181886SBoqun Feng unsigned int force_read_lock_recursive;
32cae2ed9aSIngo Molnar 
3308295b3bSThomas Hellstrom static DEFINE_WD_CLASS(ww_lockdep);
341de99445SMaarten Lankhorst 
35cae2ed9aSIngo Molnar static int __init setup_debug_locks_verbose(char *str)
36cae2ed9aSIngo Molnar {
37cae2ed9aSIngo Molnar 	get_option(&str, &debug_locks_verbose);
38cae2ed9aSIngo Molnar 
39cae2ed9aSIngo Molnar 	return 1;
40cae2ed9aSIngo Molnar }
41cae2ed9aSIngo Molnar 
42cae2ed9aSIngo Molnar __setup("debug_locks_verbose=", setup_debug_locks_verbose);
43cae2ed9aSIngo Molnar 
44cae2ed9aSIngo Molnar #define FAILURE		0
45cae2ed9aSIngo Molnar #define SUCCESS		1
46cae2ed9aSIngo Molnar 
47cae2ed9aSIngo Molnar #define LOCKTYPE_SPIN	0x1
48cae2ed9aSIngo Molnar #define LOCKTYPE_RWLOCK	0x2
49cae2ed9aSIngo Molnar #define LOCKTYPE_MUTEX	0x4
50cae2ed9aSIngo Molnar #define LOCKTYPE_RWSEM	0x8
511de99445SMaarten Lankhorst #define LOCKTYPE_WW	0x10
52018956d6SPeter Zijlstra #define LOCKTYPE_RTMUTEX 0x20
531de99445SMaarten Lankhorst 
541de99445SMaarten Lankhorst static struct ww_acquire_ctx t, t2;
55f3cf139eSMaarten Lankhorst static struct ww_mutex o, o2, o3;
56cae2ed9aSIngo Molnar 
57cae2ed9aSIngo Molnar /*
58cae2ed9aSIngo Molnar  * Normal standalone locks, for the circular and irq-context
59cae2ed9aSIngo Molnar  * dependency tests:
60cae2ed9aSIngo Molnar  */
619fb1b90cSYong Zhang static DEFINE_RAW_SPINLOCK(lock_A);
629fb1b90cSYong Zhang static DEFINE_RAW_SPINLOCK(lock_B);
639fb1b90cSYong Zhang static DEFINE_RAW_SPINLOCK(lock_C);
649fb1b90cSYong Zhang static DEFINE_RAW_SPINLOCK(lock_D);
65cae2ed9aSIngo Molnar 
66cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_A);
67cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_B);
68cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_C);
69cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_D);
70cae2ed9aSIngo Molnar 
71cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_A);
72cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_B);
73cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_C);
74cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_D);
75cae2ed9aSIngo Molnar 
76cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_A);
77cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_B);
78cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_C);
79cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_D);
80cae2ed9aSIngo Molnar 
81018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
82018956d6SPeter Zijlstra 
83018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_A);
84018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_B);
85018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_C);
86018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_D);
87018956d6SPeter Zijlstra 
88018956d6SPeter Zijlstra #endif
89018956d6SPeter Zijlstra 
90cae2ed9aSIngo Molnar /*
91cae2ed9aSIngo Molnar  * Locks that we initialize dynamically as well so that
92cae2ed9aSIngo Molnar  * e.g. X1 and X2 becomes two instances of the same class,
93cae2ed9aSIngo Molnar  * but X* and Y* are different classes. We do this so that
94cae2ed9aSIngo Molnar  * we do not trigger a real lockup:
95cae2ed9aSIngo Molnar  */
969fb1b90cSYong Zhang static DEFINE_RAW_SPINLOCK(lock_X1);
979fb1b90cSYong Zhang static DEFINE_RAW_SPINLOCK(lock_X2);
989fb1b90cSYong Zhang static DEFINE_RAW_SPINLOCK(lock_Y1);
999fb1b90cSYong Zhang static DEFINE_RAW_SPINLOCK(lock_Y2);
1009fb1b90cSYong Zhang static DEFINE_RAW_SPINLOCK(lock_Z1);
1019fb1b90cSYong Zhang static DEFINE_RAW_SPINLOCK(lock_Z2);
102cae2ed9aSIngo Molnar 
103cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_X1);
104cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_X2);
105cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Y1);
106cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Y2);
107cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Z1);
108cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Z2);
109cae2ed9aSIngo Molnar 
110cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_X1);
111cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_X2);
112cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Y1);
113cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Y2);
114cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Z1);
115cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Z2);
116cae2ed9aSIngo Molnar 
117cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_X1);
118cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_X2);
119cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Y1);
120cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Y2);
121cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Z1);
122cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Z2);
123cae2ed9aSIngo Molnar 
124018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
125018956d6SPeter Zijlstra 
126018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_X1);
127018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_X2);
128018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_Y1);
129018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_Y2);
130018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_Z1);
131018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_Z2);
132018956d6SPeter Zijlstra 
133018956d6SPeter Zijlstra #endif
134018956d6SPeter Zijlstra 
135cae2ed9aSIngo Molnar /*
136cae2ed9aSIngo Molnar  * non-inlined runtime initializers, to let separate locks share
137cae2ed9aSIngo Molnar  * the same lock-class:
138cae2ed9aSIngo Molnar  */
139cae2ed9aSIngo Molnar #define INIT_CLASS_FUNC(class) 				\
140cae2ed9aSIngo Molnar static noinline void					\
1419fb1b90cSYong Zhang init_class_##class(raw_spinlock_t *lock, rwlock_t *rwlock, \
1429fb1b90cSYong Zhang 	struct mutex *mutex, struct rw_semaphore *rwsem)\
143cae2ed9aSIngo Molnar {							\
1449fb1b90cSYong Zhang 	raw_spin_lock_init(lock);			\
145cae2ed9aSIngo Molnar 	rwlock_init(rwlock);				\
146cae2ed9aSIngo Molnar 	mutex_init(mutex);				\
147cae2ed9aSIngo Molnar 	init_rwsem(rwsem);				\
148cae2ed9aSIngo Molnar }
149cae2ed9aSIngo Molnar 
150cae2ed9aSIngo Molnar INIT_CLASS_FUNC(X)
151cae2ed9aSIngo Molnar INIT_CLASS_FUNC(Y)
152cae2ed9aSIngo Molnar INIT_CLASS_FUNC(Z)
153cae2ed9aSIngo Molnar 
154cae2ed9aSIngo Molnar static void init_shared_classes(void)
155cae2ed9aSIngo Molnar {
156018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
157018956d6SPeter Zijlstra 	static struct lock_class_key rt_X, rt_Y, rt_Z;
158018956d6SPeter Zijlstra 
159018956d6SPeter Zijlstra 	__rt_mutex_init(&rtmutex_X1, __func__, &rt_X);
160018956d6SPeter Zijlstra 	__rt_mutex_init(&rtmutex_X2, __func__, &rt_X);
161018956d6SPeter Zijlstra 	__rt_mutex_init(&rtmutex_Y1, __func__, &rt_Y);
162018956d6SPeter Zijlstra 	__rt_mutex_init(&rtmutex_Y2, __func__, &rt_Y);
163018956d6SPeter Zijlstra 	__rt_mutex_init(&rtmutex_Z1, __func__, &rt_Z);
164018956d6SPeter Zijlstra 	__rt_mutex_init(&rtmutex_Z2, __func__, &rt_Z);
165018956d6SPeter Zijlstra #endif
166018956d6SPeter Zijlstra 
167cae2ed9aSIngo Molnar 	init_class_X(&lock_X1, &rwlock_X1, &mutex_X1, &rwsem_X1);
168cae2ed9aSIngo Molnar 	init_class_X(&lock_X2, &rwlock_X2, &mutex_X2, &rwsem_X2);
169cae2ed9aSIngo Molnar 
170cae2ed9aSIngo Molnar 	init_class_Y(&lock_Y1, &rwlock_Y1, &mutex_Y1, &rwsem_Y1);
171cae2ed9aSIngo Molnar 	init_class_Y(&lock_Y2, &rwlock_Y2, &mutex_Y2, &rwsem_Y2);
172cae2ed9aSIngo Molnar 
173cae2ed9aSIngo Molnar 	init_class_Z(&lock_Z1, &rwlock_Z1, &mutex_Z1, &rwsem_Z1);
174cae2ed9aSIngo Molnar 	init_class_Z(&lock_Z2, &rwlock_Z2, &mutex_Z2, &rwsem_Z2);
175cae2ed9aSIngo Molnar }
176cae2ed9aSIngo Molnar 
177cae2ed9aSIngo Molnar /*
178cae2ed9aSIngo Molnar  * For spinlocks and rwlocks we also do hardirq-safe / softirq-safe tests.
179cae2ed9aSIngo Molnar  * The following functions use a lock from a simulated hardirq/softirq
180cae2ed9aSIngo Molnar  * context, causing the locks to be marked as hardirq-safe/softirq-safe:
181cae2ed9aSIngo Molnar  */
182cae2ed9aSIngo Molnar 
183cae2ed9aSIngo Molnar #define HARDIRQ_DISABLE		local_irq_disable
184cae2ed9aSIngo Molnar #define HARDIRQ_ENABLE		local_irq_enable
185cae2ed9aSIngo Molnar 
186cae2ed9aSIngo Molnar #define HARDIRQ_ENTER()				\
187cae2ed9aSIngo Molnar 	local_irq_disable();			\
188ba9f207cSFrederic Weisbecker 	__irq_enter();				\
189cae2ed9aSIngo Molnar 	WARN_ON(!in_irq());
190cae2ed9aSIngo Molnar 
191cae2ed9aSIngo Molnar #define HARDIRQ_EXIT()				\
192cae2ed9aSIngo Molnar 	__irq_exit();				\
193cae2ed9aSIngo Molnar 	local_irq_enable();
194cae2ed9aSIngo Molnar 
195cae2ed9aSIngo Molnar #define SOFTIRQ_DISABLE		local_bh_disable
196cae2ed9aSIngo Molnar #define SOFTIRQ_ENABLE		local_bh_enable
197cae2ed9aSIngo Molnar 
198cae2ed9aSIngo Molnar #define SOFTIRQ_ENTER()				\
199cae2ed9aSIngo Molnar 		local_bh_disable();		\
200cae2ed9aSIngo Molnar 		local_irq_disable();		\
201d820ac4cSIngo Molnar 		lockdep_softirq_enter();	\
202cae2ed9aSIngo Molnar 		WARN_ON(!in_softirq());
203cae2ed9aSIngo Molnar 
204cae2ed9aSIngo Molnar #define SOFTIRQ_EXIT()				\
205d820ac4cSIngo Molnar 		lockdep_softirq_exit();		\
206cae2ed9aSIngo Molnar 		local_irq_enable();		\
207cae2ed9aSIngo Molnar 		local_bh_enable();
208cae2ed9aSIngo Molnar 
209cae2ed9aSIngo Molnar /*
210cae2ed9aSIngo Molnar  * Shortcuts for lock/unlock API variants, to keep
211cae2ed9aSIngo Molnar  * the testcases compact:
212cae2ed9aSIngo Molnar  */
2139fb1b90cSYong Zhang #define L(x)			raw_spin_lock(&lock_##x)
2149fb1b90cSYong Zhang #define U(x)			raw_spin_unlock(&lock_##x)
215cae2ed9aSIngo Molnar #define LU(x)			L(x); U(x)
2169fb1b90cSYong Zhang #define SI(x)			raw_spin_lock_init(&lock_##x)
217cae2ed9aSIngo Molnar 
218cae2ed9aSIngo Molnar #define WL(x)			write_lock(&rwlock_##x)
219cae2ed9aSIngo Molnar #define WU(x)			write_unlock(&rwlock_##x)
220cae2ed9aSIngo Molnar #define WLU(x)			WL(x); WU(x)
221cae2ed9aSIngo Molnar 
222cae2ed9aSIngo Molnar #define RL(x)			read_lock(&rwlock_##x)
223cae2ed9aSIngo Molnar #define RU(x)			read_unlock(&rwlock_##x)
224cae2ed9aSIngo Molnar #define RLU(x)			RL(x); RU(x)
225cae2ed9aSIngo Molnar #define RWI(x)			rwlock_init(&rwlock_##x)
226cae2ed9aSIngo Molnar 
227cae2ed9aSIngo Molnar #define ML(x)			mutex_lock(&mutex_##x)
228cae2ed9aSIngo Molnar #define MU(x)			mutex_unlock(&mutex_##x)
229cae2ed9aSIngo Molnar #define MI(x)			mutex_init(&mutex_##x)
230cae2ed9aSIngo Molnar 
231018956d6SPeter Zijlstra #define RTL(x)			rt_mutex_lock(&rtmutex_##x)
232018956d6SPeter Zijlstra #define RTU(x)			rt_mutex_unlock(&rtmutex_##x)
233018956d6SPeter Zijlstra #define RTI(x)			rt_mutex_init(&rtmutex_##x)
234018956d6SPeter Zijlstra 
235cae2ed9aSIngo Molnar #define WSL(x)			down_write(&rwsem_##x)
236cae2ed9aSIngo Molnar #define WSU(x)			up_write(&rwsem_##x)
237cae2ed9aSIngo Molnar 
238cae2ed9aSIngo Molnar #define RSL(x)			down_read(&rwsem_##x)
239cae2ed9aSIngo Molnar #define RSU(x)			up_read(&rwsem_##x)
240cae2ed9aSIngo Molnar #define RWSI(x)			init_rwsem(&rwsem_##x)
241cae2ed9aSIngo Molnar 
2421de99445SMaarten Lankhorst #ifndef CONFIG_DEBUG_WW_MUTEX_SLOWPATH
2431de99445SMaarten Lankhorst #define WWAI(x)			ww_acquire_init(x, &ww_lockdep)
2441de99445SMaarten Lankhorst #else
2451de99445SMaarten Lankhorst #define WWAI(x)			do { ww_acquire_init(x, &ww_lockdep); (x)->deadlock_inject_countdown = ~0U; } while (0)
2461de99445SMaarten Lankhorst #endif
2471de99445SMaarten Lankhorst #define WWAD(x)			ww_acquire_done(x)
2481de99445SMaarten Lankhorst #define WWAF(x)			ww_acquire_fini(x)
2491de99445SMaarten Lankhorst 
2501de99445SMaarten Lankhorst #define WWL(x, c)		ww_mutex_lock(x, c)
2511de99445SMaarten Lankhorst #define WWT(x)			ww_mutex_trylock(x)
2521de99445SMaarten Lankhorst #define WWL1(x)			ww_mutex_lock(x, NULL)
2531de99445SMaarten Lankhorst #define WWU(x)			ww_mutex_unlock(x)
2541de99445SMaarten Lankhorst 
2551de99445SMaarten Lankhorst 
256cae2ed9aSIngo Molnar #define LOCK_UNLOCK_2(x,y)	LOCK(x); LOCK(y); UNLOCK(y); UNLOCK(x)
257cae2ed9aSIngo Molnar 
258cae2ed9aSIngo Molnar /*
259cae2ed9aSIngo Molnar  * Generate different permutations of the same testcase, using
260cae2ed9aSIngo Molnar  * the same basic lock-dependency/state events:
261cae2ed9aSIngo Molnar  */
262cae2ed9aSIngo Molnar 
263cae2ed9aSIngo Molnar #define GENERATE_TESTCASE(name)			\
264cae2ed9aSIngo Molnar 						\
265cae2ed9aSIngo Molnar static void name(void) { E(); }
266cae2ed9aSIngo Molnar 
267cae2ed9aSIngo Molnar #define GENERATE_PERMUTATIONS_2_EVENTS(name)	\
268cae2ed9aSIngo Molnar 						\
269cae2ed9aSIngo Molnar static void name##_12(void) { E1(); E2(); }	\
270cae2ed9aSIngo Molnar static void name##_21(void) { E2(); E1(); }
271cae2ed9aSIngo Molnar 
272cae2ed9aSIngo Molnar #define GENERATE_PERMUTATIONS_3_EVENTS(name)		\
273cae2ed9aSIngo Molnar 							\
274cae2ed9aSIngo Molnar static void name##_123(void) { E1(); E2(); E3(); }	\
275cae2ed9aSIngo Molnar static void name##_132(void) { E1(); E3(); E2(); }	\
276cae2ed9aSIngo Molnar static void name##_213(void) { E2(); E1(); E3(); }	\
277cae2ed9aSIngo Molnar static void name##_231(void) { E2(); E3(); E1(); }	\
278cae2ed9aSIngo Molnar static void name##_312(void) { E3(); E1(); E2(); }	\
279cae2ed9aSIngo Molnar static void name##_321(void) { E3(); E2(); E1(); }
280cae2ed9aSIngo Molnar 
281cae2ed9aSIngo Molnar /*
282cae2ed9aSIngo Molnar  * AA deadlock:
283cae2ed9aSIngo Molnar  */
284cae2ed9aSIngo Molnar 
285cae2ed9aSIngo Molnar #define E()					\
286cae2ed9aSIngo Molnar 						\
287cae2ed9aSIngo Molnar 	LOCK(X1);				\
288cae2ed9aSIngo Molnar 	LOCK(X2); /* this one should fail */
289cae2ed9aSIngo Molnar 
290cae2ed9aSIngo Molnar /*
291cae2ed9aSIngo Molnar  * 6 testcases:
292cae2ed9aSIngo Molnar  */
293cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
294cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_spin)
295cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
296cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_wlock)
297cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
298cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_rlock)
299cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
300cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_mutex)
301cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
302cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_wsem)
303cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
304cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_rsem)
305cae2ed9aSIngo Molnar 
306018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
307018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
308018956d6SPeter Zijlstra GENERATE_TESTCASE(AA_rtmutex);
309018956d6SPeter Zijlstra #endif
310018956d6SPeter Zijlstra 
311cae2ed9aSIngo Molnar #undef E
312cae2ed9aSIngo Molnar 
313cae2ed9aSIngo Molnar /*
314cae2ed9aSIngo Molnar  * Special-case for read-locking, they are
3156c9076ecSIngo Molnar  * allowed to recurse on the same lock class:
316cae2ed9aSIngo Molnar  */
317cae2ed9aSIngo Molnar static void rlock_AA1(void)
318cae2ed9aSIngo Molnar {
319cae2ed9aSIngo Molnar 	RL(X1);
320cae2ed9aSIngo Molnar 	RL(X1); // this one should NOT fail
321cae2ed9aSIngo Molnar }
322cae2ed9aSIngo Molnar 
323cae2ed9aSIngo Molnar static void rlock_AA1B(void)
324cae2ed9aSIngo Molnar {
325cae2ed9aSIngo Molnar 	RL(X1);
3266c9076ecSIngo Molnar 	RL(X2); // this one should NOT fail
327cae2ed9aSIngo Molnar }
328cae2ed9aSIngo Molnar 
329cae2ed9aSIngo Molnar static void rsem_AA1(void)
330cae2ed9aSIngo Molnar {
331cae2ed9aSIngo Molnar 	RSL(X1);
332cae2ed9aSIngo Molnar 	RSL(X1); // this one should fail
333cae2ed9aSIngo Molnar }
334cae2ed9aSIngo Molnar 
335cae2ed9aSIngo Molnar static void rsem_AA1B(void)
336cae2ed9aSIngo Molnar {
337cae2ed9aSIngo Molnar 	RSL(X1);
338cae2ed9aSIngo Molnar 	RSL(X2); // this one should fail
339cae2ed9aSIngo Molnar }
340cae2ed9aSIngo Molnar /*
341cae2ed9aSIngo Molnar  * The mixing of read and write locks is not allowed:
342cae2ed9aSIngo Molnar  */
343cae2ed9aSIngo Molnar static void rlock_AA2(void)
344cae2ed9aSIngo Molnar {
345cae2ed9aSIngo Molnar 	RL(X1);
346cae2ed9aSIngo Molnar 	WL(X2); // this one should fail
347cae2ed9aSIngo Molnar }
348cae2ed9aSIngo Molnar 
349cae2ed9aSIngo Molnar static void rsem_AA2(void)
350cae2ed9aSIngo Molnar {
351cae2ed9aSIngo Molnar 	RSL(X1);
352cae2ed9aSIngo Molnar 	WSL(X2); // this one should fail
353cae2ed9aSIngo Molnar }
354cae2ed9aSIngo Molnar 
355cae2ed9aSIngo Molnar static void rlock_AA3(void)
356cae2ed9aSIngo Molnar {
357cae2ed9aSIngo Molnar 	WL(X1);
358cae2ed9aSIngo Molnar 	RL(X2); // this one should fail
359cae2ed9aSIngo Molnar }
360cae2ed9aSIngo Molnar 
361cae2ed9aSIngo Molnar static void rsem_AA3(void)
362cae2ed9aSIngo Molnar {
363cae2ed9aSIngo Molnar 	WSL(X1);
364cae2ed9aSIngo Molnar 	RSL(X2); // this one should fail
365cae2ed9aSIngo Molnar }
366cae2ed9aSIngo Molnar 
367cae2ed9aSIngo Molnar /*
368e9149858SPeter Zijlstra  * read_lock(A)
369e9149858SPeter Zijlstra  * spin_lock(B)
370e9149858SPeter Zijlstra  *		spin_lock(B)
371e9149858SPeter Zijlstra  *		write_lock(A)
372e9149858SPeter Zijlstra  */
373e9149858SPeter Zijlstra static void rlock_ABBA1(void)
374e9149858SPeter Zijlstra {
375e9149858SPeter Zijlstra 	RL(X1);
376e9149858SPeter Zijlstra 	L(Y1);
377e9149858SPeter Zijlstra 	U(Y1);
378e9149858SPeter Zijlstra 	RU(X1);
379e9149858SPeter Zijlstra 
380e9149858SPeter Zijlstra 	L(Y1);
381e9149858SPeter Zijlstra 	WL(X1);
382e9149858SPeter Zijlstra 	WU(X1);
383e9149858SPeter Zijlstra 	U(Y1); // should fail
384e9149858SPeter Zijlstra }
385e9149858SPeter Zijlstra 
386e9149858SPeter Zijlstra static void rwsem_ABBA1(void)
387e9149858SPeter Zijlstra {
388e9149858SPeter Zijlstra 	RSL(X1);
389e9149858SPeter Zijlstra 	ML(Y1);
390e9149858SPeter Zijlstra 	MU(Y1);
391e9149858SPeter Zijlstra 	RSU(X1);
392e9149858SPeter Zijlstra 
393e9149858SPeter Zijlstra 	ML(Y1);
394e9149858SPeter Zijlstra 	WSL(X1);
395e9149858SPeter Zijlstra 	WSU(X1);
396e9149858SPeter Zijlstra 	MU(Y1); // should fail
397e9149858SPeter Zijlstra }
398e9149858SPeter Zijlstra 
399e9149858SPeter Zijlstra /*
400e9149858SPeter Zijlstra  * read_lock(A)
401e9149858SPeter Zijlstra  * spin_lock(B)
402e9149858SPeter Zijlstra  *		spin_lock(B)
403e9149858SPeter Zijlstra  *		read_lock(A)
404e9149858SPeter Zijlstra  */
405e9149858SPeter Zijlstra static void rlock_ABBA2(void)
406e9149858SPeter Zijlstra {
407e9149858SPeter Zijlstra 	RL(X1);
408e9149858SPeter Zijlstra 	L(Y1);
409e9149858SPeter Zijlstra 	U(Y1);
410e9149858SPeter Zijlstra 	RU(X1);
411e9149858SPeter Zijlstra 
412e9149858SPeter Zijlstra 	L(Y1);
413e9149858SPeter Zijlstra 	RL(X1);
414e9149858SPeter Zijlstra 	RU(X1);
415e9149858SPeter Zijlstra 	U(Y1); // should NOT fail
416e9149858SPeter Zijlstra }
417e9149858SPeter Zijlstra 
418e9149858SPeter Zijlstra static void rwsem_ABBA2(void)
419e9149858SPeter Zijlstra {
420e9149858SPeter Zijlstra 	RSL(X1);
421e9149858SPeter Zijlstra 	ML(Y1);
422e9149858SPeter Zijlstra 	MU(Y1);
423e9149858SPeter Zijlstra 	RSU(X1);
424e9149858SPeter Zijlstra 
425e9149858SPeter Zijlstra 	ML(Y1);
426e9149858SPeter Zijlstra 	RSL(X1);
427e9149858SPeter Zijlstra 	RSU(X1);
428e9149858SPeter Zijlstra 	MU(Y1); // should fail
429e9149858SPeter Zijlstra }
430e9149858SPeter Zijlstra 
431e9149858SPeter Zijlstra 
432e9149858SPeter Zijlstra /*
433e9149858SPeter Zijlstra  * write_lock(A)
434e9149858SPeter Zijlstra  * spin_lock(B)
435e9149858SPeter Zijlstra  *		spin_lock(B)
436e9149858SPeter Zijlstra  *		write_lock(A)
437e9149858SPeter Zijlstra  */
438e9149858SPeter Zijlstra static void rlock_ABBA3(void)
439e9149858SPeter Zijlstra {
440e9149858SPeter Zijlstra 	WL(X1);
441e9149858SPeter Zijlstra 	L(Y1);
442e9149858SPeter Zijlstra 	U(Y1);
443e9149858SPeter Zijlstra 	WU(X1);
444e9149858SPeter Zijlstra 
445e9149858SPeter Zijlstra 	L(Y1);
446e9149858SPeter Zijlstra 	WL(X1);
447e9149858SPeter Zijlstra 	WU(X1);
448e9149858SPeter Zijlstra 	U(Y1); // should fail
449e9149858SPeter Zijlstra }
450e9149858SPeter Zijlstra 
451e9149858SPeter Zijlstra static void rwsem_ABBA3(void)
452e9149858SPeter Zijlstra {
453e9149858SPeter Zijlstra 	WSL(X1);
454e9149858SPeter Zijlstra 	ML(Y1);
455e9149858SPeter Zijlstra 	MU(Y1);
456e9149858SPeter Zijlstra 	WSU(X1);
457e9149858SPeter Zijlstra 
458e9149858SPeter Zijlstra 	ML(Y1);
459e9149858SPeter Zijlstra 	WSL(X1);
460e9149858SPeter Zijlstra 	WSU(X1);
461e9149858SPeter Zijlstra 	MU(Y1); // should fail
462e9149858SPeter Zijlstra }
463e9149858SPeter Zijlstra 
464e9149858SPeter Zijlstra /*
465cae2ed9aSIngo Molnar  * ABBA deadlock:
466cae2ed9aSIngo Molnar  */
467cae2ed9aSIngo Molnar 
468cae2ed9aSIngo Molnar #define E()					\
469cae2ed9aSIngo Molnar 						\
470cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
471cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, A); /* fail */
472cae2ed9aSIngo Molnar 
473cae2ed9aSIngo Molnar /*
474cae2ed9aSIngo Molnar  * 6 testcases:
475cae2ed9aSIngo Molnar  */
476cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
477cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_spin)
478cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
479cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_wlock)
480cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
481cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_rlock)
482cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
483cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_mutex)
484cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
485cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_wsem)
486cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
487cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_rsem)
488cae2ed9aSIngo Molnar 
489018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
490018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
491018956d6SPeter Zijlstra GENERATE_TESTCASE(ABBA_rtmutex);
492018956d6SPeter Zijlstra #endif
493018956d6SPeter Zijlstra 
494cae2ed9aSIngo Molnar #undef E
495cae2ed9aSIngo Molnar 
496cae2ed9aSIngo Molnar /*
497cae2ed9aSIngo Molnar  * AB BC CA deadlock:
498cae2ed9aSIngo Molnar  */
499cae2ed9aSIngo Molnar 
500cae2ed9aSIngo Molnar #define E()					\
501cae2ed9aSIngo Molnar 						\
502cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
503cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, C);			\
504cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, A); /* fail */
505cae2ed9aSIngo Molnar 
506cae2ed9aSIngo Molnar /*
507cae2ed9aSIngo Molnar  * 6 testcases:
508cae2ed9aSIngo Molnar  */
509cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
510cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_spin)
511cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
512cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_wlock)
513cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
514cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_rlock)
515cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
516cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_mutex)
517cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
518cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_wsem)
519cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
520cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_rsem)
521cae2ed9aSIngo Molnar 
522018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
523018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
524018956d6SPeter Zijlstra GENERATE_TESTCASE(ABBCCA_rtmutex);
525018956d6SPeter Zijlstra #endif
526018956d6SPeter Zijlstra 
527cae2ed9aSIngo Molnar #undef E
528cae2ed9aSIngo Molnar 
529cae2ed9aSIngo Molnar /*
530cae2ed9aSIngo Molnar  * AB CA BC deadlock:
531cae2ed9aSIngo Molnar  */
532cae2ed9aSIngo Molnar 
533cae2ed9aSIngo Molnar #define E()					\
534cae2ed9aSIngo Molnar 						\
535cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
536cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, A);			\
537cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, C); /* fail */
538cae2ed9aSIngo Molnar 
539cae2ed9aSIngo Molnar /*
540cae2ed9aSIngo Molnar  * 6 testcases:
541cae2ed9aSIngo Molnar  */
542cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
543cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_spin)
544cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
545cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_wlock)
546cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
547cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_rlock)
548cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
549cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_mutex)
550cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
551cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_wsem)
552cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
553cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_rsem)
554cae2ed9aSIngo Molnar 
555018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
556018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
557018956d6SPeter Zijlstra GENERATE_TESTCASE(ABCABC_rtmutex);
558018956d6SPeter Zijlstra #endif
559018956d6SPeter Zijlstra 
560cae2ed9aSIngo Molnar #undef E
561cae2ed9aSIngo Molnar 
562cae2ed9aSIngo Molnar /*
563cae2ed9aSIngo Molnar  * AB BC CD DA deadlock:
564cae2ed9aSIngo Molnar  */
565cae2ed9aSIngo Molnar 
566cae2ed9aSIngo Molnar #define E()					\
567cae2ed9aSIngo Molnar 						\
568cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
569cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, C);			\
570cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, D);			\
571cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(D, A); /* fail */
572cae2ed9aSIngo Molnar 
573cae2ed9aSIngo Molnar /*
574cae2ed9aSIngo Molnar  * 6 testcases:
575cae2ed9aSIngo Molnar  */
576cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
577cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_spin)
578cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
579cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_wlock)
580cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
581cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_rlock)
582cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
583cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_mutex)
584cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
585cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_wsem)
586cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
587cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_rsem)
588cae2ed9aSIngo Molnar 
589018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
590018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
591018956d6SPeter Zijlstra GENERATE_TESTCASE(ABBCCDDA_rtmutex);
592018956d6SPeter Zijlstra #endif
593018956d6SPeter Zijlstra 
594cae2ed9aSIngo Molnar #undef E
595cae2ed9aSIngo Molnar 
596cae2ed9aSIngo Molnar /*
597cae2ed9aSIngo Molnar  * AB CD BD DA deadlock:
598cae2ed9aSIngo Molnar  */
599cae2ed9aSIngo Molnar #define E()					\
600cae2ed9aSIngo Molnar 						\
601cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
602cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, D);			\
603cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, D);			\
604cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(D, A); /* fail */
605cae2ed9aSIngo Molnar 
606cae2ed9aSIngo Molnar /*
607cae2ed9aSIngo Molnar  * 6 testcases:
608cae2ed9aSIngo Molnar  */
609cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
610cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_spin)
611cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
612cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_wlock)
613cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
614cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_rlock)
615cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
616cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_mutex)
617cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
618cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_wsem)
619cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
620cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_rsem)
621cae2ed9aSIngo Molnar 
622018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
623018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
624018956d6SPeter Zijlstra GENERATE_TESTCASE(ABCDBDDA_rtmutex);
625018956d6SPeter Zijlstra #endif
626018956d6SPeter Zijlstra 
627cae2ed9aSIngo Molnar #undef E
628cae2ed9aSIngo Molnar 
629cae2ed9aSIngo Molnar /*
630cae2ed9aSIngo Molnar  * AB CD BC DA deadlock:
631cae2ed9aSIngo Molnar  */
632cae2ed9aSIngo Molnar #define E()					\
633cae2ed9aSIngo Molnar 						\
634cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
635cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, D);			\
636cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, C);			\
637cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(D, A); /* fail */
638cae2ed9aSIngo Molnar 
639cae2ed9aSIngo Molnar /*
640cae2ed9aSIngo Molnar  * 6 testcases:
641cae2ed9aSIngo Molnar  */
642cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
643cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_spin)
644cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
645cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_wlock)
646cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
647cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_rlock)
648cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
649cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_mutex)
650cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
651cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_wsem)
652cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
653cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_rsem)
654cae2ed9aSIngo Molnar 
655018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
656018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
657018956d6SPeter Zijlstra GENERATE_TESTCASE(ABCDBCDA_rtmutex);
658018956d6SPeter Zijlstra #endif
659018956d6SPeter Zijlstra 
660cae2ed9aSIngo Molnar #undef E
661cae2ed9aSIngo Molnar 
662cae2ed9aSIngo Molnar /*
663cae2ed9aSIngo Molnar  * Double unlock:
664cae2ed9aSIngo Molnar  */
665cae2ed9aSIngo Molnar #define E()					\
666cae2ed9aSIngo Molnar 						\
667cae2ed9aSIngo Molnar 	LOCK(A);				\
668cae2ed9aSIngo Molnar 	UNLOCK(A);				\
669cae2ed9aSIngo Molnar 	UNLOCK(A); /* fail */
670cae2ed9aSIngo Molnar 
671cae2ed9aSIngo Molnar /*
672cae2ed9aSIngo Molnar  * 6 testcases:
673cae2ed9aSIngo Molnar  */
674cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
675cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_spin)
676cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
677cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_wlock)
678cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
679cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_rlock)
680cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
681cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_mutex)
682cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
683cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_wsem)
684cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
685cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_rsem)
686cae2ed9aSIngo Molnar 
687018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
688018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
689018956d6SPeter Zijlstra GENERATE_TESTCASE(double_unlock_rtmutex);
690018956d6SPeter Zijlstra #endif
691018956d6SPeter Zijlstra 
692cae2ed9aSIngo Molnar #undef E
693cae2ed9aSIngo Molnar 
694cae2ed9aSIngo Molnar /*
695cae2ed9aSIngo Molnar  * initializing a held lock:
696cae2ed9aSIngo Molnar  */
697cae2ed9aSIngo Molnar #define E()					\
698cae2ed9aSIngo Molnar 						\
699cae2ed9aSIngo Molnar 	LOCK(A);				\
700cae2ed9aSIngo Molnar 	INIT(A); /* fail */
701cae2ed9aSIngo Molnar 
702cae2ed9aSIngo Molnar /*
703cae2ed9aSIngo Molnar  * 6 testcases:
704cae2ed9aSIngo Molnar  */
705cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
706cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_spin)
707cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
708cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_wlock)
709cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
710cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_rlock)
711cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
712cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_mutex)
713cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
714cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_wsem)
715cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
716cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_rsem)
717cae2ed9aSIngo Molnar 
718018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
719018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
720018956d6SPeter Zijlstra GENERATE_TESTCASE(init_held_rtmutex);
721018956d6SPeter Zijlstra #endif
722018956d6SPeter Zijlstra 
723cae2ed9aSIngo Molnar #undef E
724cae2ed9aSIngo Molnar 
725cae2ed9aSIngo Molnar /*
726cae2ed9aSIngo Molnar  * locking an irq-safe lock with irqs enabled:
727cae2ed9aSIngo Molnar  */
728cae2ed9aSIngo Molnar #define E1()				\
729cae2ed9aSIngo Molnar 					\
730cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
731cae2ed9aSIngo Molnar 	LOCK(A);			\
732cae2ed9aSIngo Molnar 	UNLOCK(A);			\
733cae2ed9aSIngo Molnar 	IRQ_EXIT();
734cae2ed9aSIngo Molnar 
735cae2ed9aSIngo Molnar #define E2()				\
736cae2ed9aSIngo Molnar 					\
737cae2ed9aSIngo Molnar 	LOCK(A);			\
738cae2ed9aSIngo Molnar 	UNLOCK(A);
739cae2ed9aSIngo Molnar 
740cae2ed9aSIngo Molnar /*
741cae2ed9aSIngo Molnar  * Generate 24 testcases:
742cae2ed9aSIngo Molnar  */
743cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
744cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_spin)
745cae2ed9aSIngo Molnar 
746cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
747cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_rlock)
748cae2ed9aSIngo Molnar 
749cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
750cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_wlock)
751cae2ed9aSIngo Molnar 
752cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
753cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_spin)
754cae2ed9aSIngo Molnar 
755cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
756cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_rlock)
757cae2ed9aSIngo Molnar 
758cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
759cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_wlock)
760cae2ed9aSIngo Molnar 
761cae2ed9aSIngo Molnar #undef E1
762cae2ed9aSIngo Molnar #undef E2
763cae2ed9aSIngo Molnar 
764cae2ed9aSIngo Molnar /*
765cae2ed9aSIngo Molnar  * Enabling hardirqs with a softirq-safe lock held:
766cae2ed9aSIngo Molnar  */
767cae2ed9aSIngo Molnar #define E1()				\
768cae2ed9aSIngo Molnar 					\
769cae2ed9aSIngo Molnar 	SOFTIRQ_ENTER();		\
770cae2ed9aSIngo Molnar 	LOCK(A);			\
771cae2ed9aSIngo Molnar 	UNLOCK(A);			\
772cae2ed9aSIngo Molnar 	SOFTIRQ_EXIT();
773cae2ed9aSIngo Molnar 
774cae2ed9aSIngo Molnar #define E2()				\
775cae2ed9aSIngo Molnar 					\
776cae2ed9aSIngo Molnar 	HARDIRQ_DISABLE();		\
777cae2ed9aSIngo Molnar 	LOCK(A);			\
778cae2ed9aSIngo Molnar 	HARDIRQ_ENABLE();		\
779cae2ed9aSIngo Molnar 	UNLOCK(A);
780cae2ed9aSIngo Molnar 
781cae2ed9aSIngo Molnar /*
782cae2ed9aSIngo Molnar  * Generate 12 testcases:
783cae2ed9aSIngo Molnar  */
784cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
785cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_spin)
786cae2ed9aSIngo Molnar 
787cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
788cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_wlock)
789cae2ed9aSIngo Molnar 
790cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
791cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_rlock)
792cae2ed9aSIngo Molnar 
793cae2ed9aSIngo Molnar #undef E1
794cae2ed9aSIngo Molnar #undef E2
795cae2ed9aSIngo Molnar 
796cae2ed9aSIngo Molnar /*
797cae2ed9aSIngo Molnar  * Enabling irqs with an irq-safe lock held:
798cae2ed9aSIngo Molnar  */
799cae2ed9aSIngo Molnar #define E1()				\
800cae2ed9aSIngo Molnar 					\
801cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
802cae2ed9aSIngo Molnar 	LOCK(A);			\
803cae2ed9aSIngo Molnar 	UNLOCK(A);			\
804cae2ed9aSIngo Molnar 	IRQ_EXIT();
805cae2ed9aSIngo Molnar 
806cae2ed9aSIngo Molnar #define E2()				\
807cae2ed9aSIngo Molnar 					\
808cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
809cae2ed9aSIngo Molnar 	LOCK(A);			\
810cae2ed9aSIngo Molnar 	IRQ_ENABLE();			\
811cae2ed9aSIngo Molnar 	UNLOCK(A);
812cae2ed9aSIngo Molnar 
813cae2ed9aSIngo Molnar /*
814cae2ed9aSIngo Molnar  * Generate 24 testcases:
815cae2ed9aSIngo Molnar  */
816cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
817cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_spin)
818cae2ed9aSIngo Molnar 
819cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
820cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_rlock)
821cae2ed9aSIngo Molnar 
822cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
823cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_wlock)
824cae2ed9aSIngo Molnar 
825cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
826cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_spin)
827cae2ed9aSIngo Molnar 
828cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
829cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_rlock)
830cae2ed9aSIngo Molnar 
831cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
832cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock)
833cae2ed9aSIngo Molnar 
834cae2ed9aSIngo Molnar #undef E1
835cae2ed9aSIngo Molnar #undef E2
836cae2ed9aSIngo Molnar 
837cae2ed9aSIngo Molnar /*
838cae2ed9aSIngo Molnar  * Acquiring a irq-unsafe lock while holding an irq-safe-lock:
839cae2ed9aSIngo Molnar  */
840cae2ed9aSIngo Molnar #define E1()				\
841cae2ed9aSIngo Molnar 					\
842cae2ed9aSIngo Molnar 	LOCK(A);			\
843cae2ed9aSIngo Molnar 	LOCK(B);			\
844cae2ed9aSIngo Molnar 	UNLOCK(B);			\
845cae2ed9aSIngo Molnar 	UNLOCK(A);			\
846cae2ed9aSIngo Molnar 
847cae2ed9aSIngo Molnar #define E2()				\
848cae2ed9aSIngo Molnar 					\
849cae2ed9aSIngo Molnar 	LOCK(B);			\
850cae2ed9aSIngo Molnar 	UNLOCK(B);
851cae2ed9aSIngo Molnar 
852cae2ed9aSIngo Molnar #define E3()				\
853cae2ed9aSIngo Molnar 					\
854cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
855cae2ed9aSIngo Molnar 	LOCK(A);			\
856cae2ed9aSIngo Molnar 	UNLOCK(A);			\
857cae2ed9aSIngo Molnar 	IRQ_EXIT();
858cae2ed9aSIngo Molnar 
859cae2ed9aSIngo Molnar /*
860cae2ed9aSIngo Molnar  * Generate 36 testcases:
861cae2ed9aSIngo Molnar  */
862cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
863cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_spin)
864cae2ed9aSIngo Molnar 
865cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
866cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_rlock)
867cae2ed9aSIngo Molnar 
868cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
869cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_wlock)
870cae2ed9aSIngo Molnar 
871cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
872cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_spin)
873cae2ed9aSIngo Molnar 
874cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
875cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_rlock)
876cae2ed9aSIngo Molnar 
877cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
878cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock)
879cae2ed9aSIngo Molnar 
880cae2ed9aSIngo Molnar #undef E1
881cae2ed9aSIngo Molnar #undef E2
882cae2ed9aSIngo Molnar #undef E3
883cae2ed9aSIngo Molnar 
884cae2ed9aSIngo Molnar /*
885cae2ed9aSIngo Molnar  * If a lock turns into softirq-safe, but earlier it took
886cae2ed9aSIngo Molnar  * a softirq-unsafe lock:
887cae2ed9aSIngo Molnar  */
888cae2ed9aSIngo Molnar 
889cae2ed9aSIngo Molnar #define E1()				\
890cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
891cae2ed9aSIngo Molnar 	LOCK(A);			\
892cae2ed9aSIngo Molnar 	LOCK(B);			\
893cae2ed9aSIngo Molnar 	UNLOCK(B);			\
894cae2ed9aSIngo Molnar 	UNLOCK(A);			\
895cae2ed9aSIngo Molnar 	IRQ_ENABLE();
896cae2ed9aSIngo Molnar 
897cae2ed9aSIngo Molnar #define E2()				\
898cae2ed9aSIngo Molnar 	LOCK(B);			\
899cae2ed9aSIngo Molnar 	UNLOCK(B);
900cae2ed9aSIngo Molnar 
901cae2ed9aSIngo Molnar #define E3()				\
902cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
903cae2ed9aSIngo Molnar 	LOCK(A);			\
904cae2ed9aSIngo Molnar 	UNLOCK(A);			\
905cae2ed9aSIngo Molnar 	IRQ_EXIT();
906cae2ed9aSIngo Molnar 
907cae2ed9aSIngo Molnar /*
908cae2ed9aSIngo Molnar  * Generate 36 testcases:
909cae2ed9aSIngo Molnar  */
910cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
911cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_spin)
912cae2ed9aSIngo Molnar 
913cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
914cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_rlock)
915cae2ed9aSIngo Molnar 
916cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
917cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_wlock)
918cae2ed9aSIngo Molnar 
919cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
920cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_spin)
921cae2ed9aSIngo Molnar 
922cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
923cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_rlock)
924cae2ed9aSIngo Molnar 
925cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
926cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_wlock)
927cae2ed9aSIngo Molnar 
928cae2ed9aSIngo Molnar #undef E1
929cae2ed9aSIngo Molnar #undef E2
930cae2ed9aSIngo Molnar #undef E3
931cae2ed9aSIngo Molnar 
932cae2ed9aSIngo Molnar /*
933cae2ed9aSIngo Molnar  * read-lock / write-lock irq inversion.
934cae2ed9aSIngo Molnar  *
935cae2ed9aSIngo Molnar  * Deadlock scenario:
936cae2ed9aSIngo Molnar  *
937cae2ed9aSIngo Molnar  * CPU#1 is at #1, i.e. it has write-locked A, but has not
938cae2ed9aSIngo Molnar  * taken B yet.
939cae2ed9aSIngo Molnar  *
940cae2ed9aSIngo Molnar  * CPU#2 is at #2, i.e. it has locked B.
941cae2ed9aSIngo Molnar  *
942cae2ed9aSIngo Molnar  * Hardirq hits CPU#2 at point #2 and is trying to read-lock A.
943cae2ed9aSIngo Molnar  *
944cae2ed9aSIngo Molnar  * The deadlock occurs because CPU#1 will spin on B, and CPU#2
945cae2ed9aSIngo Molnar  * will spin on A.
946cae2ed9aSIngo Molnar  */
947cae2ed9aSIngo Molnar 
948cae2ed9aSIngo Molnar #define E1()				\
949cae2ed9aSIngo Molnar 					\
950cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
951cae2ed9aSIngo Molnar 	WL(A);				\
952cae2ed9aSIngo Molnar 	LOCK(B);			\
953cae2ed9aSIngo Molnar 	UNLOCK(B);			\
954cae2ed9aSIngo Molnar 	WU(A);				\
955cae2ed9aSIngo Molnar 	IRQ_ENABLE();
956cae2ed9aSIngo Molnar 
957cae2ed9aSIngo Molnar #define E2()				\
958cae2ed9aSIngo Molnar 					\
959cae2ed9aSIngo Molnar 	LOCK(B);			\
960cae2ed9aSIngo Molnar 	UNLOCK(B);
961cae2ed9aSIngo Molnar 
962cae2ed9aSIngo Molnar #define E3()				\
963cae2ed9aSIngo Molnar 					\
964cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
965cae2ed9aSIngo Molnar 	RL(A);				\
966cae2ed9aSIngo Molnar 	RU(A);				\
967cae2ed9aSIngo Molnar 	IRQ_EXIT();
968cae2ed9aSIngo Molnar 
969cae2ed9aSIngo Molnar /*
970cae2ed9aSIngo Molnar  * Generate 36 testcases:
971cae2ed9aSIngo Molnar  */
972cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
973cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_spin)
974cae2ed9aSIngo Molnar 
975cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
976cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_rlock)
977cae2ed9aSIngo Molnar 
978cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
979cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_wlock)
980cae2ed9aSIngo Molnar 
981cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
982cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_spin)
983cae2ed9aSIngo Molnar 
984cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
985cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_rlock)
986cae2ed9aSIngo Molnar 
987cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
988cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_wlock)
989cae2ed9aSIngo Molnar 
990cae2ed9aSIngo Molnar #undef E1
991cae2ed9aSIngo Molnar #undef E2
992cae2ed9aSIngo Molnar #undef E3
993cae2ed9aSIngo Molnar 
994cae2ed9aSIngo Molnar /*
995cae2ed9aSIngo Molnar  * read-lock / write-lock recursion that is actually safe.
996cae2ed9aSIngo Molnar  */
997cae2ed9aSIngo Molnar 
998cae2ed9aSIngo Molnar #define E1()				\
999cae2ed9aSIngo Molnar 					\
1000cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
1001cae2ed9aSIngo Molnar 	WL(A);				\
1002cae2ed9aSIngo Molnar 	WU(A);				\
1003cae2ed9aSIngo Molnar 	IRQ_ENABLE();
1004cae2ed9aSIngo Molnar 
1005cae2ed9aSIngo Molnar #define E2()				\
1006cae2ed9aSIngo Molnar 					\
1007cae2ed9aSIngo Molnar 	RL(A);				\
1008cae2ed9aSIngo Molnar 	RU(A);				\
1009cae2ed9aSIngo Molnar 
1010cae2ed9aSIngo Molnar #define E3()				\
1011cae2ed9aSIngo Molnar 					\
1012cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
1013cae2ed9aSIngo Molnar 	RL(A);				\
1014cae2ed9aSIngo Molnar 	L(B);				\
1015cae2ed9aSIngo Molnar 	U(B);				\
1016cae2ed9aSIngo Molnar 	RU(A);				\
1017cae2ed9aSIngo Molnar 	IRQ_EXIT();
1018cae2ed9aSIngo Molnar 
1019cae2ed9aSIngo Molnar /*
1020cae2ed9aSIngo Molnar  * Generate 12 testcases:
1021cae2ed9aSIngo Molnar  */
1022cae2ed9aSIngo Molnar #include "locking-selftest-hardirq.h"
1023cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard)
1024cae2ed9aSIngo Molnar 
1025cae2ed9aSIngo Molnar #include "locking-selftest-softirq.h"
1026cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft)
1027cae2ed9aSIngo Molnar 
1028cae2ed9aSIngo Molnar #undef E1
1029cae2ed9aSIngo Molnar #undef E2
1030cae2ed9aSIngo Molnar #undef E3
1031cae2ed9aSIngo Molnar 
1032cae2ed9aSIngo Molnar /*
1033cae2ed9aSIngo Molnar  * read-lock / write-lock recursion that is unsafe.
1034cae2ed9aSIngo Molnar  */
1035cae2ed9aSIngo Molnar 
1036cae2ed9aSIngo Molnar #define E1()				\
1037cae2ed9aSIngo Molnar 					\
1038cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
1039cae2ed9aSIngo Molnar 	L(B);				\
1040cae2ed9aSIngo Molnar 	WL(A);				\
1041cae2ed9aSIngo Molnar 	WU(A);				\
1042cae2ed9aSIngo Molnar 	U(B);				\
1043cae2ed9aSIngo Molnar 	IRQ_ENABLE();
1044cae2ed9aSIngo Molnar 
1045cae2ed9aSIngo Molnar #define E2()				\
1046cae2ed9aSIngo Molnar 					\
1047cae2ed9aSIngo Molnar 	RL(A);				\
1048cae2ed9aSIngo Molnar 	RU(A);				\
1049cae2ed9aSIngo Molnar 
1050cae2ed9aSIngo Molnar #define E3()				\
1051cae2ed9aSIngo Molnar 					\
1052cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
1053cae2ed9aSIngo Molnar 	L(B);				\
1054cae2ed9aSIngo Molnar 	U(B);				\
1055cae2ed9aSIngo Molnar 	IRQ_EXIT();
1056cae2ed9aSIngo Molnar 
1057cae2ed9aSIngo Molnar /*
1058cae2ed9aSIngo Molnar  * Generate 12 testcases:
1059cae2ed9aSIngo Molnar  */
1060cae2ed9aSIngo Molnar #include "locking-selftest-hardirq.h"
1061cae2ed9aSIngo Molnar // GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard)
1062cae2ed9aSIngo Molnar 
1063cae2ed9aSIngo Molnar #include "locking-selftest-softirq.h"
1064cae2ed9aSIngo Molnar // GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft)
1065cae2ed9aSIngo Molnar 
1066cae2ed9aSIngo Molnar #ifdef CONFIG_DEBUG_LOCK_ALLOC
1067cae2ed9aSIngo Molnar # define I_SPINLOCK(x)	lockdep_reset_lock(&lock_##x.dep_map)
1068cae2ed9aSIngo Molnar # define I_RWLOCK(x)	lockdep_reset_lock(&rwlock_##x.dep_map)
1069cae2ed9aSIngo Molnar # define I_MUTEX(x)	lockdep_reset_lock(&mutex_##x.dep_map)
1070cae2ed9aSIngo Molnar # define I_RWSEM(x)	lockdep_reset_lock(&rwsem_##x.dep_map)
10711de99445SMaarten Lankhorst # define I_WW(x)	lockdep_reset_lock(&x.dep_map)
1072018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
1073018956d6SPeter Zijlstra # define I_RTMUTEX(x)	lockdep_reset_lock(&rtmutex_##x.dep_map)
1074018956d6SPeter Zijlstra #endif
1075cae2ed9aSIngo Molnar #else
1076cae2ed9aSIngo Molnar # define I_SPINLOCK(x)
1077cae2ed9aSIngo Molnar # define I_RWLOCK(x)
1078cae2ed9aSIngo Molnar # define I_MUTEX(x)
1079cae2ed9aSIngo Molnar # define I_RWSEM(x)
10801de99445SMaarten Lankhorst # define I_WW(x)
1081cae2ed9aSIngo Molnar #endif
1082cae2ed9aSIngo Molnar 
1083018956d6SPeter Zijlstra #ifndef I_RTMUTEX
1084018956d6SPeter Zijlstra # define I_RTMUTEX(x)
1085018956d6SPeter Zijlstra #endif
1086018956d6SPeter Zijlstra 
1087018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
1088018956d6SPeter Zijlstra #define I2_RTMUTEX(x)	rt_mutex_init(&rtmutex_##x)
1089018956d6SPeter Zijlstra #else
1090018956d6SPeter Zijlstra #define I2_RTMUTEX(x)
1091018956d6SPeter Zijlstra #endif
1092018956d6SPeter Zijlstra 
1093cae2ed9aSIngo Molnar #define I1(x)					\
1094cae2ed9aSIngo Molnar 	do {					\
1095cae2ed9aSIngo Molnar 		I_SPINLOCK(x);			\
1096cae2ed9aSIngo Molnar 		I_RWLOCK(x);			\
1097cae2ed9aSIngo Molnar 		I_MUTEX(x);			\
1098cae2ed9aSIngo Molnar 		I_RWSEM(x);			\
1099018956d6SPeter Zijlstra 		I_RTMUTEX(x);			\
1100cae2ed9aSIngo Molnar 	} while (0)
1101cae2ed9aSIngo Molnar 
1102cae2ed9aSIngo Molnar #define I2(x)					\
1103cae2ed9aSIngo Molnar 	do {					\
11049fb1b90cSYong Zhang 		raw_spin_lock_init(&lock_##x);	\
1105cae2ed9aSIngo Molnar 		rwlock_init(&rwlock_##x);	\
1106cae2ed9aSIngo Molnar 		mutex_init(&mutex_##x);		\
1107cae2ed9aSIngo Molnar 		init_rwsem(&rwsem_##x);		\
1108018956d6SPeter Zijlstra 		I2_RTMUTEX(x);			\
1109cae2ed9aSIngo Molnar 	} while (0)
1110cae2ed9aSIngo Molnar 
1111cae2ed9aSIngo Molnar static void reset_locks(void)
1112cae2ed9aSIngo Molnar {
1113cae2ed9aSIngo Molnar 	local_irq_disable();
11141de99445SMaarten Lankhorst 	lockdep_free_key_range(&ww_lockdep.acquire_key, 1);
11151de99445SMaarten Lankhorst 	lockdep_free_key_range(&ww_lockdep.mutex_key, 1);
11161de99445SMaarten Lankhorst 
1117cae2ed9aSIngo Molnar 	I1(A); I1(B); I1(C); I1(D);
1118cae2ed9aSIngo Molnar 	I1(X1); I1(X2); I1(Y1); I1(Y2); I1(Z1); I1(Z2);
1119f3cf139eSMaarten Lankhorst 	I_WW(t); I_WW(t2); I_WW(o.base); I_WW(o2.base); I_WW(o3.base);
1120cae2ed9aSIngo Molnar 	lockdep_reset();
1121cae2ed9aSIngo Molnar 	I2(A); I2(B); I2(C); I2(D);
1122cae2ed9aSIngo Molnar 	init_shared_classes();
11231de99445SMaarten Lankhorst 
1124f3cf139eSMaarten Lankhorst 	ww_mutex_init(&o, &ww_lockdep); ww_mutex_init(&o2, &ww_lockdep); ww_mutex_init(&o3, &ww_lockdep);
11251de99445SMaarten Lankhorst 	memset(&t, 0, sizeof(t)); memset(&t2, 0, sizeof(t2));
11261de99445SMaarten Lankhorst 	memset(&ww_lockdep.acquire_key, 0, sizeof(ww_lockdep.acquire_key));
11271de99445SMaarten Lankhorst 	memset(&ww_lockdep.mutex_key, 0, sizeof(ww_lockdep.mutex_key));
1128cae2ed9aSIngo Molnar 	local_irq_enable();
1129cae2ed9aSIngo Molnar }
1130cae2ed9aSIngo Molnar 
1131cae2ed9aSIngo Molnar #undef I
1132cae2ed9aSIngo Molnar 
1133cae2ed9aSIngo Molnar static int testcase_total;
1134cae2ed9aSIngo Molnar static int testcase_successes;
1135cae2ed9aSIngo Molnar static int expected_testcase_failures;
1136cae2ed9aSIngo Molnar static int unexpected_testcase_failures;
1137cae2ed9aSIngo Molnar 
1138cae2ed9aSIngo Molnar static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask)
1139cae2ed9aSIngo Molnar {
1140cae2ed9aSIngo Molnar 	unsigned long saved_preempt_count = preempt_count();
1141cae2ed9aSIngo Molnar 
1142cae2ed9aSIngo Molnar 	WARN_ON(irqs_disabled());
1143cae2ed9aSIngo Molnar 
1144cae2ed9aSIngo Molnar 	testcase_fn();
1145cae2ed9aSIngo Molnar 	/*
1146cae2ed9aSIngo Molnar 	 * Filter out expected failures:
1147cae2ed9aSIngo Molnar 	 */
11481de99445SMaarten Lankhorst #ifndef CONFIG_PROVE_LOCKING
1149166989e3SMaarten Lankhorst 	if (expected == FAILURE && debug_locks) {
1150cae2ed9aSIngo Molnar 		expected_testcase_failures++;
115125139409SMichael Ellerman 		pr_cont("failed|");
1152166989e3SMaarten Lankhorst 	}
1153166989e3SMaarten Lankhorst 	else
1154166989e3SMaarten Lankhorst #endif
1155166989e3SMaarten Lankhorst 	if (debug_locks != expected) {
1156cae2ed9aSIngo Molnar 		unexpected_testcase_failures++;
115725139409SMichael Ellerman 		pr_cont("FAILED|");
1158cae2ed9aSIngo Molnar 	} else {
1159cae2ed9aSIngo Molnar 		testcase_successes++;
116025139409SMichael Ellerman 		pr_cont("  ok  |");
1161cae2ed9aSIngo Molnar 	}
1162cae2ed9aSIngo Molnar 	testcase_total++;
1163cae2ed9aSIngo Molnar 
1164cae2ed9aSIngo Molnar 	if (debug_locks_verbose)
116525139409SMichael Ellerman 		pr_cont(" lockclass mask: %x, debug_locks: %d, expected: %d\n",
1166cae2ed9aSIngo Molnar 			lockclass_mask, debug_locks, expected);
1167cae2ed9aSIngo Molnar 	/*
1168cae2ed9aSIngo Molnar 	 * Some tests (e.g. double-unlock) might corrupt the preemption
1169cae2ed9aSIngo Molnar 	 * count, so restore it:
1170cae2ed9aSIngo Molnar 	 */
11714a2b4b22SPeter Zijlstra 	preempt_count_set(saved_preempt_count);
1172cae2ed9aSIngo Molnar #ifdef CONFIG_TRACE_IRQFLAGS
1173cae2ed9aSIngo Molnar 	if (softirq_count())
1174cae2ed9aSIngo Molnar 		current->softirqs_enabled = 0;
1175cae2ed9aSIngo Molnar 	else
1176cae2ed9aSIngo Molnar 		current->softirqs_enabled = 1;
1177cae2ed9aSIngo Molnar #endif
1178cae2ed9aSIngo Molnar 
1179cae2ed9aSIngo Molnar 	reset_locks();
1180cae2ed9aSIngo Molnar }
1181cae2ed9aSIngo Molnar 
1182018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
1183018956d6SPeter Zijlstra #define dotest_rt(fn, e, m)	dotest((fn), (e), (m))
1184018956d6SPeter Zijlstra #else
1185018956d6SPeter Zijlstra #define dotest_rt(fn, e, m)
1186018956d6SPeter Zijlstra #endif
1187018956d6SPeter Zijlstra 
1188cae2ed9aSIngo Molnar static inline void print_testname(const char *testname)
1189cae2ed9aSIngo Molnar {
1190cae2ed9aSIngo Molnar 	printk("%33s:", testname);
1191cae2ed9aSIngo Molnar }
1192cae2ed9aSIngo Molnar 
1193cae2ed9aSIngo Molnar #define DO_TESTCASE_1(desc, name, nr)				\
1194cae2ed9aSIngo Molnar 	print_testname(desc"/"#nr);				\
1195cae2ed9aSIngo Molnar 	dotest(name##_##nr, SUCCESS, LOCKTYPE_RWLOCK);		\
119625139409SMichael Ellerman 	pr_cont("\n");
1197cae2ed9aSIngo Molnar 
1198cae2ed9aSIngo Molnar #define DO_TESTCASE_1B(desc, name, nr)				\
1199cae2ed9aSIngo Molnar 	print_testname(desc"/"#nr);				\
1200cae2ed9aSIngo Molnar 	dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK);		\
120125139409SMichael Ellerman 	pr_cont("\n");
1202cae2ed9aSIngo Molnar 
1203cae2ed9aSIngo Molnar #define DO_TESTCASE_3(desc, name, nr)				\
1204cae2ed9aSIngo Molnar 	print_testname(desc"/"#nr);				\
1205cae2ed9aSIngo Molnar 	dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN);	\
1206cae2ed9aSIngo Molnar 	dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK);	\
1207cae2ed9aSIngo Molnar 	dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK);	\
120825139409SMichael Ellerman 	pr_cont("\n");
1209cae2ed9aSIngo Molnar 
1210cae2ed9aSIngo Molnar #define DO_TESTCASE_3RW(desc, name, nr)				\
1211cae2ed9aSIngo Molnar 	print_testname(desc"/"#nr);				\
1212cae2ed9aSIngo Molnar 	dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN|LOCKTYPE_RWLOCK);\
1213cae2ed9aSIngo Molnar 	dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK);	\
1214cae2ed9aSIngo Molnar 	dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK);	\
121525139409SMichael Ellerman 	pr_cont("\n");
1216cae2ed9aSIngo Molnar 
1217cae2ed9aSIngo Molnar #define DO_TESTCASE_6(desc, name)				\
1218cae2ed9aSIngo Molnar 	print_testname(desc);					\
1219cae2ed9aSIngo Molnar 	dotest(name##_spin, FAILURE, LOCKTYPE_SPIN);		\
1220cae2ed9aSIngo Molnar 	dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK);		\
1221cae2ed9aSIngo Molnar 	dotest(name##_rlock, FAILURE, LOCKTYPE_RWLOCK);		\
1222cae2ed9aSIngo Molnar 	dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX);		\
1223cae2ed9aSIngo Molnar 	dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM);		\
1224cae2ed9aSIngo Molnar 	dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM);		\
1225018956d6SPeter Zijlstra 	dotest_rt(name##_rtmutex, FAILURE, LOCKTYPE_RTMUTEX);	\
122625139409SMichael Ellerman 	pr_cont("\n");
1227cae2ed9aSIngo Molnar 
1228cae2ed9aSIngo Molnar #define DO_TESTCASE_6_SUCCESS(desc, name)			\
1229cae2ed9aSIngo Molnar 	print_testname(desc);					\
1230cae2ed9aSIngo Molnar 	dotest(name##_spin, SUCCESS, LOCKTYPE_SPIN);		\
1231cae2ed9aSIngo Molnar 	dotest(name##_wlock, SUCCESS, LOCKTYPE_RWLOCK);		\
1232cae2ed9aSIngo Molnar 	dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK);		\
1233cae2ed9aSIngo Molnar 	dotest(name##_mutex, SUCCESS, LOCKTYPE_MUTEX);		\
1234cae2ed9aSIngo Molnar 	dotest(name##_wsem, SUCCESS, LOCKTYPE_RWSEM);		\
1235cae2ed9aSIngo Molnar 	dotest(name##_rsem, SUCCESS, LOCKTYPE_RWSEM);		\
1236018956d6SPeter Zijlstra 	dotest_rt(name##_rtmutex, SUCCESS, LOCKTYPE_RTMUTEX);	\
123725139409SMichael Ellerman 	pr_cont("\n");
1238cae2ed9aSIngo Molnar 
1239cae2ed9aSIngo Molnar /*
1240cae2ed9aSIngo Molnar  * 'read' variant: rlocks must not trigger.
1241cae2ed9aSIngo Molnar  */
1242cae2ed9aSIngo Molnar #define DO_TESTCASE_6R(desc, name)				\
1243cae2ed9aSIngo Molnar 	print_testname(desc);					\
1244cae2ed9aSIngo Molnar 	dotest(name##_spin, FAILURE, LOCKTYPE_SPIN);		\
1245cae2ed9aSIngo Molnar 	dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK);		\
1246cae2ed9aSIngo Molnar 	dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK);		\
1247cae2ed9aSIngo Molnar 	dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX);		\
1248cae2ed9aSIngo Molnar 	dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM);		\
1249cae2ed9aSIngo Molnar 	dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM);		\
1250018956d6SPeter Zijlstra 	dotest_rt(name##_rtmutex, FAILURE, LOCKTYPE_RTMUTEX);	\
125125139409SMichael Ellerman 	pr_cont("\n");
1252cae2ed9aSIngo Molnar 
1253cae2ed9aSIngo Molnar #define DO_TESTCASE_2I(desc, name, nr)				\
1254cae2ed9aSIngo Molnar 	DO_TESTCASE_1("hard-"desc, name##_hard, nr);		\
1255cae2ed9aSIngo Molnar 	DO_TESTCASE_1("soft-"desc, name##_soft, nr);
1256cae2ed9aSIngo Molnar 
1257cae2ed9aSIngo Molnar #define DO_TESTCASE_2IB(desc, name, nr)				\
1258cae2ed9aSIngo Molnar 	DO_TESTCASE_1B("hard-"desc, name##_hard, nr);		\
1259cae2ed9aSIngo Molnar 	DO_TESTCASE_1B("soft-"desc, name##_soft, nr);
1260cae2ed9aSIngo Molnar 
1261cae2ed9aSIngo Molnar #define DO_TESTCASE_6I(desc, name, nr)				\
1262cae2ed9aSIngo Molnar 	DO_TESTCASE_3("hard-"desc, name##_hard, nr);		\
1263cae2ed9aSIngo Molnar 	DO_TESTCASE_3("soft-"desc, name##_soft, nr);
1264cae2ed9aSIngo Molnar 
1265cae2ed9aSIngo Molnar #define DO_TESTCASE_6IRW(desc, name, nr)			\
1266cae2ed9aSIngo Molnar 	DO_TESTCASE_3RW("hard-"desc, name##_hard, nr);		\
1267cae2ed9aSIngo Molnar 	DO_TESTCASE_3RW("soft-"desc, name##_soft, nr);
1268cae2ed9aSIngo Molnar 
1269cae2ed9aSIngo Molnar #define DO_TESTCASE_2x3(desc, name)				\
1270cae2ed9aSIngo Molnar 	DO_TESTCASE_3(desc, name, 12);				\
1271cae2ed9aSIngo Molnar 	DO_TESTCASE_3(desc, name, 21);
1272cae2ed9aSIngo Molnar 
1273cae2ed9aSIngo Molnar #define DO_TESTCASE_2x6(desc, name)				\
1274cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 12);				\
1275cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 21);
1276cae2ed9aSIngo Molnar 
1277cae2ed9aSIngo Molnar #define DO_TESTCASE_6x2(desc, name)				\
1278cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 123);			\
1279cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 132);			\
1280cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 213);			\
1281cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 231);			\
1282cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 312);			\
1283cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 321);
1284cae2ed9aSIngo Molnar 
1285cae2ed9aSIngo Molnar #define DO_TESTCASE_6x2B(desc, name)				\
1286cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 123);			\
1287cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 132);			\
1288cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 213);			\
1289cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 231);			\
1290cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 312);			\
1291cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 321);
1292cae2ed9aSIngo Molnar 
1293cae2ed9aSIngo Molnar #define DO_TESTCASE_6x6(desc, name)				\
1294cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 123);			\
1295cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 132);			\
1296cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 213);			\
1297cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 231);			\
1298cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 312);			\
1299cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 321);
1300cae2ed9aSIngo Molnar 
1301cae2ed9aSIngo Molnar #define DO_TESTCASE_6x6RW(desc, name)				\
1302cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 123);			\
1303cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 132);			\
1304cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 213);			\
1305cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 231);			\
1306cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 312);			\
1307cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 321);
1308cae2ed9aSIngo Molnar 
13091de99445SMaarten Lankhorst static void ww_test_fail_acquire(void)
13101de99445SMaarten Lankhorst {
13111de99445SMaarten Lankhorst 	int ret;
13121de99445SMaarten Lankhorst 
13131de99445SMaarten Lankhorst 	WWAI(&t);
13141de99445SMaarten Lankhorst 	t.stamp++;
13151de99445SMaarten Lankhorst 
13161de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
13171de99445SMaarten Lankhorst 
13181de99445SMaarten Lankhorst 	if (WARN_ON(!o.ctx) ||
13191de99445SMaarten Lankhorst 	    WARN_ON(ret))
13201de99445SMaarten Lankhorst 		return;
13211de99445SMaarten Lankhorst 
13221de99445SMaarten Lankhorst 	/* No lockdep test, pure API */
13231de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
13241de99445SMaarten Lankhorst 	WARN_ON(ret != -EALREADY);
13251de99445SMaarten Lankhorst 
13261de99445SMaarten Lankhorst 	ret = WWT(&o);
13271de99445SMaarten Lankhorst 	WARN_ON(ret);
13281de99445SMaarten Lankhorst 
13291de99445SMaarten Lankhorst 	t2 = t;
13301de99445SMaarten Lankhorst 	t2.stamp++;
13311de99445SMaarten Lankhorst 	ret = WWL(&o, &t2);
13321de99445SMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
13331de99445SMaarten Lankhorst 	WWU(&o);
13341de99445SMaarten Lankhorst 
13351de99445SMaarten Lankhorst 	if (WWT(&o))
13361de99445SMaarten Lankhorst 		WWU(&o);
13371de99445SMaarten Lankhorst #ifdef CONFIG_DEBUG_LOCK_ALLOC
13381de99445SMaarten Lankhorst 	else
13391de99445SMaarten Lankhorst 		DEBUG_LOCKS_WARN_ON(1);
13401de99445SMaarten Lankhorst #endif
13411de99445SMaarten Lankhorst }
13421de99445SMaarten Lankhorst 
13432fe3d4b1SMaarten Lankhorst static void ww_test_normal(void)
13442fe3d4b1SMaarten Lankhorst {
13452fe3d4b1SMaarten Lankhorst 	int ret;
13462fe3d4b1SMaarten Lankhorst 
13472fe3d4b1SMaarten Lankhorst 	WWAI(&t);
13482fe3d4b1SMaarten Lankhorst 
13492fe3d4b1SMaarten Lankhorst 	/*
13502fe3d4b1SMaarten Lankhorst 	 * None of the ww_mutex codepaths should be taken in the 'normal'
13512fe3d4b1SMaarten Lankhorst 	 * mutex calls. The easiest way to verify this is by using the
13522fe3d4b1SMaarten Lankhorst 	 * normal mutex calls, and making sure o.ctx is unmodified.
13532fe3d4b1SMaarten Lankhorst 	 */
13542fe3d4b1SMaarten Lankhorst 
13552fe3d4b1SMaarten Lankhorst 	/* mutex_lock (and indirectly, mutex_lock_nested) */
13562fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
13572fe3d4b1SMaarten Lankhorst 	mutex_lock(&o.base);
13582fe3d4b1SMaarten Lankhorst 	mutex_unlock(&o.base);
13592fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
13602fe3d4b1SMaarten Lankhorst 
13612fe3d4b1SMaarten Lankhorst 	/* mutex_lock_interruptible (and *_nested) */
13622fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
13632fe3d4b1SMaarten Lankhorst 	ret = mutex_lock_interruptible(&o.base);
13642fe3d4b1SMaarten Lankhorst 	if (!ret)
13652fe3d4b1SMaarten Lankhorst 		mutex_unlock(&o.base);
13662fe3d4b1SMaarten Lankhorst 	else
13672fe3d4b1SMaarten Lankhorst 		WARN_ON(1);
13682fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
13692fe3d4b1SMaarten Lankhorst 
13702fe3d4b1SMaarten Lankhorst 	/* mutex_lock_killable (and *_nested) */
13712fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
13722fe3d4b1SMaarten Lankhorst 	ret = mutex_lock_killable(&o.base);
13732fe3d4b1SMaarten Lankhorst 	if (!ret)
13742fe3d4b1SMaarten Lankhorst 		mutex_unlock(&o.base);
13752fe3d4b1SMaarten Lankhorst 	else
13762fe3d4b1SMaarten Lankhorst 		WARN_ON(1);
13772fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
13782fe3d4b1SMaarten Lankhorst 
13792fe3d4b1SMaarten Lankhorst 	/* trylock, succeeding */
13802fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
13812fe3d4b1SMaarten Lankhorst 	ret = mutex_trylock(&o.base);
13822fe3d4b1SMaarten Lankhorst 	WARN_ON(!ret);
13832fe3d4b1SMaarten Lankhorst 	if (ret)
13842fe3d4b1SMaarten Lankhorst 		mutex_unlock(&o.base);
13852fe3d4b1SMaarten Lankhorst 	else
13862fe3d4b1SMaarten Lankhorst 		WARN_ON(1);
13872fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
13882fe3d4b1SMaarten Lankhorst 
13892fe3d4b1SMaarten Lankhorst 	/* trylock, failing */
13902fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
13912fe3d4b1SMaarten Lankhorst 	mutex_lock(&o.base);
13922fe3d4b1SMaarten Lankhorst 	ret = mutex_trylock(&o.base);
13932fe3d4b1SMaarten Lankhorst 	WARN_ON(ret);
13942fe3d4b1SMaarten Lankhorst 	mutex_unlock(&o.base);
13952fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
13962fe3d4b1SMaarten Lankhorst 
13972fe3d4b1SMaarten Lankhorst 	/* nest_lock */
13982fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
13992fe3d4b1SMaarten Lankhorst 	mutex_lock_nest_lock(&o.base, &t);
14002fe3d4b1SMaarten Lankhorst 	mutex_unlock(&o.base);
14012fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
14022fe3d4b1SMaarten Lankhorst }
14032fe3d4b1SMaarten Lankhorst 
14041de99445SMaarten Lankhorst static void ww_test_two_contexts(void)
14051de99445SMaarten Lankhorst {
14061de99445SMaarten Lankhorst 	WWAI(&t);
14071de99445SMaarten Lankhorst 	WWAI(&t2);
14081de99445SMaarten Lankhorst }
14091de99445SMaarten Lankhorst 
14101de99445SMaarten Lankhorst static void ww_test_diff_class(void)
14111de99445SMaarten Lankhorst {
14121de99445SMaarten Lankhorst 	WWAI(&t);
14131de99445SMaarten Lankhorst #ifdef CONFIG_DEBUG_MUTEXES
14141de99445SMaarten Lankhorst 	t.ww_class = NULL;
14151de99445SMaarten Lankhorst #endif
14161de99445SMaarten Lankhorst 	WWL(&o, &t);
14171de99445SMaarten Lankhorst }
14181de99445SMaarten Lankhorst 
14191de99445SMaarten Lankhorst static void ww_test_context_done_twice(void)
14201de99445SMaarten Lankhorst {
14211de99445SMaarten Lankhorst 	WWAI(&t);
14221de99445SMaarten Lankhorst 	WWAD(&t);
14231de99445SMaarten Lankhorst 	WWAD(&t);
14241de99445SMaarten Lankhorst 	WWAF(&t);
14251de99445SMaarten Lankhorst }
14261de99445SMaarten Lankhorst 
14271de99445SMaarten Lankhorst static void ww_test_context_unlock_twice(void)
14281de99445SMaarten Lankhorst {
14291de99445SMaarten Lankhorst 	WWAI(&t);
14301de99445SMaarten Lankhorst 	WWAD(&t);
14311de99445SMaarten Lankhorst 	WWAF(&t);
14321de99445SMaarten Lankhorst 	WWAF(&t);
14331de99445SMaarten Lankhorst }
14341de99445SMaarten Lankhorst 
14351de99445SMaarten Lankhorst static void ww_test_context_fini_early(void)
14361de99445SMaarten Lankhorst {
14371de99445SMaarten Lankhorst 	WWAI(&t);
14381de99445SMaarten Lankhorst 	WWL(&o, &t);
14391de99445SMaarten Lankhorst 	WWAD(&t);
14401de99445SMaarten Lankhorst 	WWAF(&t);
14411de99445SMaarten Lankhorst }
14421de99445SMaarten Lankhorst 
14431de99445SMaarten Lankhorst static void ww_test_context_lock_after_done(void)
14441de99445SMaarten Lankhorst {
14451de99445SMaarten Lankhorst 	WWAI(&t);
14461de99445SMaarten Lankhorst 	WWAD(&t);
14471de99445SMaarten Lankhorst 	WWL(&o, &t);
14481de99445SMaarten Lankhorst }
14491de99445SMaarten Lankhorst 
14501de99445SMaarten Lankhorst static void ww_test_object_unlock_twice(void)
14511de99445SMaarten Lankhorst {
14521de99445SMaarten Lankhorst 	WWL1(&o);
14531de99445SMaarten Lankhorst 	WWU(&o);
14541de99445SMaarten Lankhorst 	WWU(&o);
14551de99445SMaarten Lankhorst }
14561de99445SMaarten Lankhorst 
14571de99445SMaarten Lankhorst static void ww_test_object_lock_unbalanced(void)
14581de99445SMaarten Lankhorst {
14591de99445SMaarten Lankhorst 	WWAI(&t);
14601de99445SMaarten Lankhorst 	WWL(&o, &t);
14611de99445SMaarten Lankhorst 	t.acquired = 0;
14621de99445SMaarten Lankhorst 	WWU(&o);
14631de99445SMaarten Lankhorst 	WWAF(&t);
14641de99445SMaarten Lankhorst }
14651de99445SMaarten Lankhorst 
14661de99445SMaarten Lankhorst static void ww_test_object_lock_stale_context(void)
14671de99445SMaarten Lankhorst {
14681de99445SMaarten Lankhorst 	WWAI(&t);
14691de99445SMaarten Lankhorst 	o.ctx = &t2;
14701de99445SMaarten Lankhorst 	WWL(&o, &t);
14711de99445SMaarten Lankhorst }
14721de99445SMaarten Lankhorst 
1473f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_normal(void)
1474f3cf139eSMaarten Lankhorst {
1475f3cf139eSMaarten Lankhorst 	int ret;
1476f3cf139eSMaarten Lankhorst 
1477f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
1478f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
14795facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1480f3cf139eSMaarten Lankhorst 
1481f3cf139eSMaarten Lankhorst 	WWAI(&t);
1482f3cf139eSMaarten Lankhorst 	t2 = t;
1483f3cf139eSMaarten Lankhorst 	t2.stamp--;
1484f3cf139eSMaarten Lankhorst 
1485f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1486f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1487f3cf139eSMaarten Lankhorst 
1488f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1489f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1490f3cf139eSMaarten Lankhorst 
1491f3cf139eSMaarten Lankhorst 	o2.ctx = NULL;
1492f3cf139eSMaarten Lankhorst 	mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
1493f3cf139eSMaarten Lankhorst 	mutex_unlock(&o2.base);
1494f3cf139eSMaarten Lankhorst 	WWU(&o);
1495f3cf139eSMaarten Lankhorst 
1496f3cf139eSMaarten Lankhorst 	WWL(&o2, &t);
1497f3cf139eSMaarten Lankhorst }
1498f3cf139eSMaarten Lankhorst 
1499f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_normal_slow(void)
1500f3cf139eSMaarten Lankhorst {
1501f3cf139eSMaarten Lankhorst 	int ret;
1502f3cf139eSMaarten Lankhorst 
1503f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
15045facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1505f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1506f3cf139eSMaarten Lankhorst 
1507f3cf139eSMaarten Lankhorst 	WWAI(&t);
1508f3cf139eSMaarten Lankhorst 	t2 = t;
1509f3cf139eSMaarten Lankhorst 	t2.stamp--;
1510f3cf139eSMaarten Lankhorst 
1511f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1512f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1513f3cf139eSMaarten Lankhorst 
1514f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1515f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1516f3cf139eSMaarten Lankhorst 
1517f3cf139eSMaarten Lankhorst 	o2.ctx = NULL;
1518f3cf139eSMaarten Lankhorst 	mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
1519f3cf139eSMaarten Lankhorst 	mutex_unlock(&o2.base);
1520f3cf139eSMaarten Lankhorst 	WWU(&o);
1521f3cf139eSMaarten Lankhorst 
1522f3cf139eSMaarten Lankhorst 	ww_mutex_lock_slow(&o2, &t);
1523f3cf139eSMaarten Lankhorst }
1524f3cf139eSMaarten Lankhorst 
1525f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_no_unlock(void)
1526f3cf139eSMaarten Lankhorst {
1527f3cf139eSMaarten Lankhorst 	int ret;
1528f3cf139eSMaarten Lankhorst 
1529f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
1530f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
15315facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1532f3cf139eSMaarten Lankhorst 
1533f3cf139eSMaarten Lankhorst 	WWAI(&t);
1534f3cf139eSMaarten Lankhorst 	t2 = t;
1535f3cf139eSMaarten Lankhorst 	t2.stamp--;
1536f3cf139eSMaarten Lankhorst 
1537f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1538f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1539f3cf139eSMaarten Lankhorst 
1540f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1541f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1542f3cf139eSMaarten Lankhorst 
1543f3cf139eSMaarten Lankhorst 	o2.ctx = NULL;
1544f3cf139eSMaarten Lankhorst 	mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
1545f3cf139eSMaarten Lankhorst 	mutex_unlock(&o2.base);
1546f3cf139eSMaarten Lankhorst 
1547f3cf139eSMaarten Lankhorst 	WWL(&o2, &t);
1548f3cf139eSMaarten Lankhorst }
1549f3cf139eSMaarten Lankhorst 
1550f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_no_unlock_slow(void)
1551f3cf139eSMaarten Lankhorst {
1552f3cf139eSMaarten Lankhorst 	int ret;
1553f3cf139eSMaarten Lankhorst 
1554f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
15555facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1556f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1557f3cf139eSMaarten Lankhorst 
1558f3cf139eSMaarten Lankhorst 	WWAI(&t);
1559f3cf139eSMaarten Lankhorst 	t2 = t;
1560f3cf139eSMaarten Lankhorst 	t2.stamp--;
1561f3cf139eSMaarten Lankhorst 
1562f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1563f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1564f3cf139eSMaarten Lankhorst 
1565f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1566f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1567f3cf139eSMaarten Lankhorst 
1568f3cf139eSMaarten Lankhorst 	o2.ctx = NULL;
1569f3cf139eSMaarten Lankhorst 	mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
1570f3cf139eSMaarten Lankhorst 	mutex_unlock(&o2.base);
1571f3cf139eSMaarten Lankhorst 
1572f3cf139eSMaarten Lankhorst 	ww_mutex_lock_slow(&o2, &t);
1573f3cf139eSMaarten Lankhorst }
1574f3cf139eSMaarten Lankhorst 
1575f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_more(void)
1576f3cf139eSMaarten Lankhorst {
1577f3cf139eSMaarten Lankhorst 	int ret;
1578f3cf139eSMaarten Lankhorst 
1579f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
15805facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1581f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1582f3cf139eSMaarten Lankhorst 
1583f3cf139eSMaarten Lankhorst 	WWAI(&t);
1584f3cf139eSMaarten Lankhorst 	t2 = t;
1585f3cf139eSMaarten Lankhorst 	t2.stamp--;
1586f3cf139eSMaarten Lankhorst 
1587f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1588f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1589f3cf139eSMaarten Lankhorst 
1590f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1591f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1592f3cf139eSMaarten Lankhorst 
1593f3cf139eSMaarten Lankhorst 	ret = WWL(&o3, &t);
1594f3cf139eSMaarten Lankhorst }
1595f3cf139eSMaarten Lankhorst 
1596f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_more_slow(void)
1597f3cf139eSMaarten Lankhorst {
1598f3cf139eSMaarten Lankhorst 	int ret;
1599f3cf139eSMaarten Lankhorst 
1600f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
16015facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1602f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1603f3cf139eSMaarten Lankhorst 
1604f3cf139eSMaarten Lankhorst 	WWAI(&t);
1605f3cf139eSMaarten Lankhorst 	t2 = t;
1606f3cf139eSMaarten Lankhorst 	t2.stamp--;
1607f3cf139eSMaarten Lankhorst 
1608f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1609f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1610f3cf139eSMaarten Lankhorst 
1611f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1612f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1613f3cf139eSMaarten Lankhorst 
1614f3cf139eSMaarten Lankhorst 	ww_mutex_lock_slow(&o3, &t);
1615f3cf139eSMaarten Lankhorst }
1616f3cf139eSMaarten Lankhorst 
1617f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_more_edeadlk(void)
1618f3cf139eSMaarten Lankhorst {
1619f3cf139eSMaarten Lankhorst 	int ret;
1620f3cf139eSMaarten Lankhorst 
1621f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
16225facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1623f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1624f3cf139eSMaarten Lankhorst 
1625f3cf139eSMaarten Lankhorst 	mutex_lock(&o3.base);
16265facae4fSQian Cai 	mutex_release(&o3.base.dep_map, _THIS_IP_);
1627f3cf139eSMaarten Lankhorst 	o3.ctx = &t2;
1628f3cf139eSMaarten Lankhorst 
1629f3cf139eSMaarten Lankhorst 	WWAI(&t);
1630f3cf139eSMaarten Lankhorst 	t2 = t;
1631f3cf139eSMaarten Lankhorst 	t2.stamp--;
1632f3cf139eSMaarten Lankhorst 
1633f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1634f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1635f3cf139eSMaarten Lankhorst 
1636f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1637f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1638f3cf139eSMaarten Lankhorst 
1639f3cf139eSMaarten Lankhorst 	ret = WWL(&o3, &t);
1640f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1641f3cf139eSMaarten Lankhorst }
1642f3cf139eSMaarten Lankhorst 
1643f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_more_edeadlk_slow(void)
1644f3cf139eSMaarten Lankhorst {
1645f3cf139eSMaarten Lankhorst 	int ret;
1646f3cf139eSMaarten Lankhorst 
1647f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
16485facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1649f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1650f3cf139eSMaarten Lankhorst 
1651f3cf139eSMaarten Lankhorst 	mutex_lock(&o3.base);
16525facae4fSQian Cai 	mutex_release(&o3.base.dep_map, _THIS_IP_);
1653f3cf139eSMaarten Lankhorst 	o3.ctx = &t2;
1654f3cf139eSMaarten Lankhorst 
1655f3cf139eSMaarten Lankhorst 	WWAI(&t);
1656f3cf139eSMaarten Lankhorst 	t2 = t;
1657f3cf139eSMaarten Lankhorst 	t2.stamp--;
1658f3cf139eSMaarten Lankhorst 
1659f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1660f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1661f3cf139eSMaarten Lankhorst 
1662f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1663f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1664f3cf139eSMaarten Lankhorst 
1665f3cf139eSMaarten Lankhorst 	ww_mutex_lock_slow(&o3, &t);
1666f3cf139eSMaarten Lankhorst }
1667f3cf139eSMaarten Lankhorst 
1668f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_wrong(void)
1669f3cf139eSMaarten Lankhorst {
1670f3cf139eSMaarten Lankhorst 	int ret;
1671f3cf139eSMaarten Lankhorst 
1672f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
16735facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1674f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1675f3cf139eSMaarten Lankhorst 
1676f3cf139eSMaarten Lankhorst 	WWAI(&t);
1677f3cf139eSMaarten Lankhorst 	t2 = t;
1678f3cf139eSMaarten Lankhorst 	t2.stamp--;
1679f3cf139eSMaarten Lankhorst 
1680f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1681f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1682f3cf139eSMaarten Lankhorst 
1683f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1684f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1685f3cf139eSMaarten Lankhorst 	if (!ret)
1686f3cf139eSMaarten Lankhorst 		WWU(&o2);
1687f3cf139eSMaarten Lankhorst 
1688f3cf139eSMaarten Lankhorst 	WWU(&o);
1689f3cf139eSMaarten Lankhorst 
1690f3cf139eSMaarten Lankhorst 	ret = WWL(&o3, &t);
1691f3cf139eSMaarten Lankhorst }
1692f3cf139eSMaarten Lankhorst 
1693f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_wrong_slow(void)
1694f3cf139eSMaarten Lankhorst {
1695f3cf139eSMaarten Lankhorst 	int ret;
1696f3cf139eSMaarten Lankhorst 
1697f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
16985facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1699f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1700f3cf139eSMaarten Lankhorst 
1701f3cf139eSMaarten Lankhorst 	WWAI(&t);
1702f3cf139eSMaarten Lankhorst 	t2 = t;
1703f3cf139eSMaarten Lankhorst 	t2.stamp--;
1704f3cf139eSMaarten Lankhorst 
1705f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1706f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1707f3cf139eSMaarten Lankhorst 
1708f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1709f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1710f3cf139eSMaarten Lankhorst 	if (!ret)
1711f3cf139eSMaarten Lankhorst 		WWU(&o2);
1712f3cf139eSMaarten Lankhorst 
1713f3cf139eSMaarten Lankhorst 	WWU(&o);
1714f3cf139eSMaarten Lankhorst 
1715f3cf139eSMaarten Lankhorst 	ww_mutex_lock_slow(&o3, &t);
1716f3cf139eSMaarten Lankhorst }
1717f3cf139eSMaarten Lankhorst 
17181de99445SMaarten Lankhorst static void ww_test_spin_nest_unlocked(void)
17191de99445SMaarten Lankhorst {
17201de99445SMaarten Lankhorst 	raw_spin_lock_nest_lock(&lock_A, &o.base);
17211de99445SMaarten Lankhorst 	U(A);
17221de99445SMaarten Lankhorst }
17231de99445SMaarten Lankhorst 
17241de99445SMaarten Lankhorst static void ww_test_unneeded_slow(void)
17251de99445SMaarten Lankhorst {
17261de99445SMaarten Lankhorst 	WWAI(&t);
17271de99445SMaarten Lankhorst 
17281de99445SMaarten Lankhorst 	ww_mutex_lock_slow(&o, &t);
17291de99445SMaarten Lankhorst }
17301de99445SMaarten Lankhorst 
17311de99445SMaarten Lankhorst static void ww_test_context_block(void)
17321de99445SMaarten Lankhorst {
17331de99445SMaarten Lankhorst 	int ret;
17341de99445SMaarten Lankhorst 
17351de99445SMaarten Lankhorst 	WWAI(&t);
17361de99445SMaarten Lankhorst 
17371de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
17381de99445SMaarten Lankhorst 	WARN_ON(ret);
17391de99445SMaarten Lankhorst 	WWL1(&o2);
17401de99445SMaarten Lankhorst }
17411de99445SMaarten Lankhorst 
17421de99445SMaarten Lankhorst static void ww_test_context_try(void)
17431de99445SMaarten Lankhorst {
17441de99445SMaarten Lankhorst 	int ret;
17451de99445SMaarten Lankhorst 
17461de99445SMaarten Lankhorst 	WWAI(&t);
17471de99445SMaarten Lankhorst 
17481de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
17491de99445SMaarten Lankhorst 	WARN_ON(ret);
17501de99445SMaarten Lankhorst 
17511de99445SMaarten Lankhorst 	ret = WWT(&o2);
17521de99445SMaarten Lankhorst 	WARN_ON(!ret);
17531de99445SMaarten Lankhorst 	WWU(&o2);
17541de99445SMaarten Lankhorst 	WWU(&o);
17551de99445SMaarten Lankhorst }
17561de99445SMaarten Lankhorst 
17571de99445SMaarten Lankhorst static void ww_test_context_context(void)
17581de99445SMaarten Lankhorst {
17591de99445SMaarten Lankhorst 	int ret;
17601de99445SMaarten Lankhorst 
17611de99445SMaarten Lankhorst 	WWAI(&t);
17621de99445SMaarten Lankhorst 
17631de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
17641de99445SMaarten Lankhorst 	WARN_ON(ret);
17651de99445SMaarten Lankhorst 
17661de99445SMaarten Lankhorst 	ret = WWL(&o2, &t);
17671de99445SMaarten Lankhorst 	WARN_ON(ret);
17681de99445SMaarten Lankhorst 
17691de99445SMaarten Lankhorst 	WWU(&o2);
17701de99445SMaarten Lankhorst 	WWU(&o);
17711de99445SMaarten Lankhorst }
17721de99445SMaarten Lankhorst 
17731de99445SMaarten Lankhorst static void ww_test_try_block(void)
17741de99445SMaarten Lankhorst {
17751de99445SMaarten Lankhorst 	bool ret;
17761de99445SMaarten Lankhorst 
17771de99445SMaarten Lankhorst 	ret = WWT(&o);
17781de99445SMaarten Lankhorst 	WARN_ON(!ret);
17791de99445SMaarten Lankhorst 
17801de99445SMaarten Lankhorst 	WWL1(&o2);
17811de99445SMaarten Lankhorst 	WWU(&o2);
17821de99445SMaarten Lankhorst 	WWU(&o);
17831de99445SMaarten Lankhorst }
17841de99445SMaarten Lankhorst 
17851de99445SMaarten Lankhorst static void ww_test_try_try(void)
17861de99445SMaarten Lankhorst {
17871de99445SMaarten Lankhorst 	bool ret;
17881de99445SMaarten Lankhorst 
17891de99445SMaarten Lankhorst 	ret = WWT(&o);
17901de99445SMaarten Lankhorst 	WARN_ON(!ret);
17911de99445SMaarten Lankhorst 	ret = WWT(&o2);
17921de99445SMaarten Lankhorst 	WARN_ON(!ret);
17931de99445SMaarten Lankhorst 	WWU(&o2);
17941de99445SMaarten Lankhorst 	WWU(&o);
17951de99445SMaarten Lankhorst }
17961de99445SMaarten Lankhorst 
17971de99445SMaarten Lankhorst static void ww_test_try_context(void)
17981de99445SMaarten Lankhorst {
17991de99445SMaarten Lankhorst 	int ret;
18001de99445SMaarten Lankhorst 
18011de99445SMaarten Lankhorst 	ret = WWT(&o);
18021de99445SMaarten Lankhorst 	WARN_ON(!ret);
18031de99445SMaarten Lankhorst 
18041de99445SMaarten Lankhorst 	WWAI(&t);
18051de99445SMaarten Lankhorst 
18061de99445SMaarten Lankhorst 	ret = WWL(&o2, &t);
18071de99445SMaarten Lankhorst 	WARN_ON(ret);
18081de99445SMaarten Lankhorst }
18091de99445SMaarten Lankhorst 
18101de99445SMaarten Lankhorst static void ww_test_block_block(void)
18111de99445SMaarten Lankhorst {
18121de99445SMaarten Lankhorst 	WWL1(&o);
18131de99445SMaarten Lankhorst 	WWL1(&o2);
18141de99445SMaarten Lankhorst }
18151de99445SMaarten Lankhorst 
18161de99445SMaarten Lankhorst static void ww_test_block_try(void)
18171de99445SMaarten Lankhorst {
18181de99445SMaarten Lankhorst 	bool ret;
18191de99445SMaarten Lankhorst 
18201de99445SMaarten Lankhorst 	WWL1(&o);
18211de99445SMaarten Lankhorst 	ret = WWT(&o2);
18221de99445SMaarten Lankhorst 	WARN_ON(!ret);
18231de99445SMaarten Lankhorst }
18241de99445SMaarten Lankhorst 
18251de99445SMaarten Lankhorst static void ww_test_block_context(void)
18261de99445SMaarten Lankhorst {
18271de99445SMaarten Lankhorst 	int ret;
18281de99445SMaarten Lankhorst 
18291de99445SMaarten Lankhorst 	WWL1(&o);
18301de99445SMaarten Lankhorst 	WWAI(&t);
18311de99445SMaarten Lankhorst 
18321de99445SMaarten Lankhorst 	ret = WWL(&o2, &t);
18331de99445SMaarten Lankhorst 	WARN_ON(ret);
18341de99445SMaarten Lankhorst }
18351de99445SMaarten Lankhorst 
18361de99445SMaarten Lankhorst static void ww_test_spin_block(void)
18371de99445SMaarten Lankhorst {
18381de99445SMaarten Lankhorst 	L(A);
18391de99445SMaarten Lankhorst 	U(A);
18401de99445SMaarten Lankhorst 
18411de99445SMaarten Lankhorst 	WWL1(&o);
18421de99445SMaarten Lankhorst 	L(A);
18431de99445SMaarten Lankhorst 	U(A);
18441de99445SMaarten Lankhorst 	WWU(&o);
18451de99445SMaarten Lankhorst 
18461de99445SMaarten Lankhorst 	L(A);
18471de99445SMaarten Lankhorst 	WWL1(&o);
18481de99445SMaarten Lankhorst 	WWU(&o);
18491de99445SMaarten Lankhorst 	U(A);
18501de99445SMaarten Lankhorst }
18511de99445SMaarten Lankhorst 
18521de99445SMaarten Lankhorst static void ww_test_spin_try(void)
18531de99445SMaarten Lankhorst {
18541de99445SMaarten Lankhorst 	bool ret;
18551de99445SMaarten Lankhorst 
18561de99445SMaarten Lankhorst 	L(A);
18571de99445SMaarten Lankhorst 	U(A);
18581de99445SMaarten Lankhorst 
18591de99445SMaarten Lankhorst 	ret = WWT(&o);
18601de99445SMaarten Lankhorst 	WARN_ON(!ret);
18611de99445SMaarten Lankhorst 	L(A);
18621de99445SMaarten Lankhorst 	U(A);
18631de99445SMaarten Lankhorst 	WWU(&o);
18641de99445SMaarten Lankhorst 
18651de99445SMaarten Lankhorst 	L(A);
18661de99445SMaarten Lankhorst 	ret = WWT(&o);
18671de99445SMaarten Lankhorst 	WARN_ON(!ret);
18681de99445SMaarten Lankhorst 	WWU(&o);
18691de99445SMaarten Lankhorst 	U(A);
18701de99445SMaarten Lankhorst }
18711de99445SMaarten Lankhorst 
18721de99445SMaarten Lankhorst static void ww_test_spin_context(void)
18731de99445SMaarten Lankhorst {
18741de99445SMaarten Lankhorst 	int ret;
18751de99445SMaarten Lankhorst 
18761de99445SMaarten Lankhorst 	L(A);
18771de99445SMaarten Lankhorst 	U(A);
18781de99445SMaarten Lankhorst 
18791de99445SMaarten Lankhorst 	WWAI(&t);
18801de99445SMaarten Lankhorst 
18811de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
18821de99445SMaarten Lankhorst 	WARN_ON(ret);
18831de99445SMaarten Lankhorst 	L(A);
18841de99445SMaarten Lankhorst 	U(A);
18851de99445SMaarten Lankhorst 	WWU(&o);
18861de99445SMaarten Lankhorst 
18871de99445SMaarten Lankhorst 	L(A);
18881de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
18891de99445SMaarten Lankhorst 	WARN_ON(ret);
18901de99445SMaarten Lankhorst 	WWU(&o);
18911de99445SMaarten Lankhorst 	U(A);
18921de99445SMaarten Lankhorst }
18931de99445SMaarten Lankhorst 
18941de99445SMaarten Lankhorst static void ww_tests(void)
18951de99445SMaarten Lankhorst {
18961de99445SMaarten Lankhorst 	printk("  --------------------------------------------------------------------------\n");
18971de99445SMaarten Lankhorst 	printk("  | Wound/wait tests |\n");
18981de99445SMaarten Lankhorst 	printk("  ---------------------\n");
18991de99445SMaarten Lankhorst 
19001de99445SMaarten Lankhorst 	print_testname("ww api failures");
19011de99445SMaarten Lankhorst 	dotest(ww_test_fail_acquire, SUCCESS, LOCKTYPE_WW);
19022fe3d4b1SMaarten Lankhorst 	dotest(ww_test_normal, SUCCESS, LOCKTYPE_WW);
19031de99445SMaarten Lankhorst 	dotest(ww_test_unneeded_slow, FAILURE, LOCKTYPE_WW);
190425139409SMichael Ellerman 	pr_cont("\n");
19051de99445SMaarten Lankhorst 
19061de99445SMaarten Lankhorst 	print_testname("ww contexts mixing");
19071de99445SMaarten Lankhorst 	dotest(ww_test_two_contexts, FAILURE, LOCKTYPE_WW);
19081de99445SMaarten Lankhorst 	dotest(ww_test_diff_class, FAILURE, LOCKTYPE_WW);
190925139409SMichael Ellerman 	pr_cont("\n");
19101de99445SMaarten Lankhorst 
19111de99445SMaarten Lankhorst 	print_testname("finishing ww context");
19121de99445SMaarten Lankhorst 	dotest(ww_test_context_done_twice, FAILURE, LOCKTYPE_WW);
19131de99445SMaarten Lankhorst 	dotest(ww_test_context_unlock_twice, FAILURE, LOCKTYPE_WW);
19141de99445SMaarten Lankhorst 	dotest(ww_test_context_fini_early, FAILURE, LOCKTYPE_WW);
19151de99445SMaarten Lankhorst 	dotest(ww_test_context_lock_after_done, FAILURE, LOCKTYPE_WW);
191625139409SMichael Ellerman 	pr_cont("\n");
19171de99445SMaarten Lankhorst 
19181de99445SMaarten Lankhorst 	print_testname("locking mismatches");
19191de99445SMaarten Lankhorst 	dotest(ww_test_object_unlock_twice, FAILURE, LOCKTYPE_WW);
19201de99445SMaarten Lankhorst 	dotest(ww_test_object_lock_unbalanced, FAILURE, LOCKTYPE_WW);
19211de99445SMaarten Lankhorst 	dotest(ww_test_object_lock_stale_context, FAILURE, LOCKTYPE_WW);
192225139409SMichael Ellerman 	pr_cont("\n");
19231de99445SMaarten Lankhorst 
1924f3cf139eSMaarten Lankhorst 	print_testname("EDEADLK handling");
1925f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_normal, SUCCESS, LOCKTYPE_WW);
1926f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_normal_slow, SUCCESS, LOCKTYPE_WW);
1927f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_no_unlock, FAILURE, LOCKTYPE_WW);
1928f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_no_unlock_slow, FAILURE, LOCKTYPE_WW);
1929f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_more, FAILURE, LOCKTYPE_WW);
1930f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_more_slow, FAILURE, LOCKTYPE_WW);
1931f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_more_edeadlk, FAILURE, LOCKTYPE_WW);
1932f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_more_edeadlk_slow, FAILURE, LOCKTYPE_WW);
1933f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_wrong, FAILURE, LOCKTYPE_WW);
1934f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_wrong_slow, FAILURE, LOCKTYPE_WW);
193525139409SMichael Ellerman 	pr_cont("\n");
1936f3cf139eSMaarten Lankhorst 
19371de99445SMaarten Lankhorst 	print_testname("spinlock nest unlocked");
19381de99445SMaarten Lankhorst 	dotest(ww_test_spin_nest_unlocked, FAILURE, LOCKTYPE_WW);
193925139409SMichael Ellerman 	pr_cont("\n");
19401de99445SMaarten Lankhorst 
19411de99445SMaarten Lankhorst 	printk("  -----------------------------------------------------\n");
19421de99445SMaarten Lankhorst 	printk("                                 |block | try  |context|\n");
19431de99445SMaarten Lankhorst 	printk("  -----------------------------------------------------\n");
19441de99445SMaarten Lankhorst 
19451de99445SMaarten Lankhorst 	print_testname("context");
19461de99445SMaarten Lankhorst 	dotest(ww_test_context_block, FAILURE, LOCKTYPE_WW);
19471de99445SMaarten Lankhorst 	dotest(ww_test_context_try, SUCCESS, LOCKTYPE_WW);
19481de99445SMaarten Lankhorst 	dotest(ww_test_context_context, SUCCESS, LOCKTYPE_WW);
194925139409SMichael Ellerman 	pr_cont("\n");
19501de99445SMaarten Lankhorst 
19511de99445SMaarten Lankhorst 	print_testname("try");
19521de99445SMaarten Lankhorst 	dotest(ww_test_try_block, FAILURE, LOCKTYPE_WW);
19531de99445SMaarten Lankhorst 	dotest(ww_test_try_try, SUCCESS, LOCKTYPE_WW);
19541de99445SMaarten Lankhorst 	dotest(ww_test_try_context, FAILURE, LOCKTYPE_WW);
195525139409SMichael Ellerman 	pr_cont("\n");
19561de99445SMaarten Lankhorst 
19571de99445SMaarten Lankhorst 	print_testname("block");
19581de99445SMaarten Lankhorst 	dotest(ww_test_block_block, FAILURE, LOCKTYPE_WW);
19591de99445SMaarten Lankhorst 	dotest(ww_test_block_try, SUCCESS, LOCKTYPE_WW);
19601de99445SMaarten Lankhorst 	dotest(ww_test_block_context, FAILURE, LOCKTYPE_WW);
196125139409SMichael Ellerman 	pr_cont("\n");
19621de99445SMaarten Lankhorst 
19631de99445SMaarten Lankhorst 	print_testname("spinlock");
19641de99445SMaarten Lankhorst 	dotest(ww_test_spin_block, FAILURE, LOCKTYPE_WW);
19651de99445SMaarten Lankhorst 	dotest(ww_test_spin_try, SUCCESS, LOCKTYPE_WW);
19661de99445SMaarten Lankhorst 	dotest(ww_test_spin_context, FAILURE, LOCKTYPE_WW);
196725139409SMichael Ellerman 	pr_cont("\n");
19681de99445SMaarten Lankhorst }
1969cae2ed9aSIngo Molnar 
1970cae2ed9aSIngo Molnar void locking_selftest(void)
1971cae2ed9aSIngo Molnar {
1972cae2ed9aSIngo Molnar 	/*
1973cae2ed9aSIngo Molnar 	 * Got a locking failure before the selftest ran?
1974cae2ed9aSIngo Molnar 	 */
1975cae2ed9aSIngo Molnar 	if (!debug_locks) {
1976cae2ed9aSIngo Molnar 		printk("----------------------------------\n");
1977cae2ed9aSIngo Molnar 		printk("| Locking API testsuite disabled |\n");
1978cae2ed9aSIngo Molnar 		printk("----------------------------------\n");
1979cae2ed9aSIngo Molnar 		return;
1980cae2ed9aSIngo Molnar 	}
1981cae2ed9aSIngo Molnar 
1982cae2ed9aSIngo Molnar 	/*
1983*e9181886SBoqun Feng 	 * treats read_lock() as recursive read locks for testing purpose
1984*e9181886SBoqun Feng 	 */
1985*e9181886SBoqun Feng 	force_read_lock_recursive = 1;
1986*e9181886SBoqun Feng 
1987*e9181886SBoqun Feng 	/*
1988cae2ed9aSIngo Molnar 	 * Run the testsuite:
1989cae2ed9aSIngo Molnar 	 */
1990cae2ed9aSIngo Molnar 	printk("------------------------\n");
1991cae2ed9aSIngo Molnar 	printk("| Locking API testsuite:\n");
1992cae2ed9aSIngo Molnar 	printk("----------------------------------------------------------------------------\n");
1993cae2ed9aSIngo Molnar 	printk("                                 | spin |wlock |rlock |mutex | wsem | rsem |\n");
1994cae2ed9aSIngo Molnar 	printk("  --------------------------------------------------------------------------\n");
1995cae2ed9aSIngo Molnar 
1996cae2ed9aSIngo Molnar 	init_shared_classes();
1997cae2ed9aSIngo Molnar 	debug_locks_silent = !debug_locks_verbose;
1998cdc84d79SBart Van Assche 	lockdep_set_selftest_task(current);
1999cae2ed9aSIngo Molnar 
20006c9076ecSIngo Molnar 	DO_TESTCASE_6R("A-A deadlock", AA);
2001cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-B-A deadlock", ABBA);
2002cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-B-C-C-A deadlock", ABBCCA);
2003cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-C-A-B-C deadlock", ABCABC);
2004cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-B-C-C-D-D-A deadlock", ABBCCDDA);
2005cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-C-D-B-D-D-A deadlock", ABCDBDDA);
2006cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-C-D-B-C-D-A deadlock", ABCDBCDA);
2007cae2ed9aSIngo Molnar 	DO_TESTCASE_6("double unlock", double_unlock);
2008cae2ed9aSIngo Molnar 	DO_TESTCASE_6("initialize held", init_held);
2009cae2ed9aSIngo Molnar 
2010cae2ed9aSIngo Molnar 	printk("  --------------------------------------------------------------------------\n");
2011cae2ed9aSIngo Molnar 	print_testname("recursive read-lock");
201225139409SMichael Ellerman 	pr_cont("             |");
2013cae2ed9aSIngo Molnar 	dotest(rlock_AA1, SUCCESS, LOCKTYPE_RWLOCK);
201425139409SMichael Ellerman 	pr_cont("             |");
2015cae2ed9aSIngo Molnar 	dotest(rsem_AA1, FAILURE, LOCKTYPE_RWSEM);
201625139409SMichael Ellerman 	pr_cont("\n");
2017cae2ed9aSIngo Molnar 
2018cae2ed9aSIngo Molnar 	print_testname("recursive read-lock #2");
201925139409SMichael Ellerman 	pr_cont("             |");
20206c9076ecSIngo Molnar 	dotest(rlock_AA1B, SUCCESS, LOCKTYPE_RWLOCK);
202125139409SMichael Ellerman 	pr_cont("             |");
2022cae2ed9aSIngo Molnar 	dotest(rsem_AA1B, FAILURE, LOCKTYPE_RWSEM);
202325139409SMichael Ellerman 	pr_cont("\n");
2024cae2ed9aSIngo Molnar 
2025cae2ed9aSIngo Molnar 	print_testname("mixed read-write-lock");
202625139409SMichael Ellerman 	pr_cont("             |");
2027cae2ed9aSIngo Molnar 	dotest(rlock_AA2, FAILURE, LOCKTYPE_RWLOCK);
202825139409SMichael Ellerman 	pr_cont("             |");
2029cae2ed9aSIngo Molnar 	dotest(rsem_AA2, FAILURE, LOCKTYPE_RWSEM);
203025139409SMichael Ellerman 	pr_cont("\n");
2031cae2ed9aSIngo Molnar 
2032cae2ed9aSIngo Molnar 	print_testname("mixed write-read-lock");
203325139409SMichael Ellerman 	pr_cont("             |");
2034cae2ed9aSIngo Molnar 	dotest(rlock_AA3, FAILURE, LOCKTYPE_RWLOCK);
203525139409SMichael Ellerman 	pr_cont("             |");
2036cae2ed9aSIngo Molnar 	dotest(rsem_AA3, FAILURE, LOCKTYPE_RWSEM);
203725139409SMichael Ellerman 	pr_cont("\n");
2038cae2ed9aSIngo Molnar 
2039e9149858SPeter Zijlstra 	print_testname("mixed read-lock/lock-write ABBA");
2040e9149858SPeter Zijlstra 	pr_cont("             |");
2041e9149858SPeter Zijlstra 	dotest(rlock_ABBA1, FAILURE, LOCKTYPE_RWLOCK);
2042c7e2f69dSPeter Zijlstra #ifdef CONFIG_PROVE_LOCKING
2043d82fed75SPeter Zijlstra 	/*
2044d82fed75SPeter Zijlstra 	 * Lockdep does indeed fail here, but there's nothing we can do about
2045d82fed75SPeter Zijlstra 	 * that now.  Don't kill lockdep for it.
2046d82fed75SPeter Zijlstra 	 */
2047d82fed75SPeter Zijlstra 	unexpected_testcase_failures--;
2048c7e2f69dSPeter Zijlstra #endif
2049d82fed75SPeter Zijlstra 
2050e9149858SPeter Zijlstra 	pr_cont("             |");
2051e9149858SPeter Zijlstra 	dotest(rwsem_ABBA1, FAILURE, LOCKTYPE_RWSEM);
2052e9149858SPeter Zijlstra 
2053e9149858SPeter Zijlstra 	print_testname("mixed read-lock/lock-read ABBA");
2054e9149858SPeter Zijlstra 	pr_cont("             |");
2055e9149858SPeter Zijlstra 	dotest(rlock_ABBA2, SUCCESS, LOCKTYPE_RWLOCK);
2056e9149858SPeter Zijlstra 	pr_cont("             |");
2057e9149858SPeter Zijlstra 	dotest(rwsem_ABBA2, FAILURE, LOCKTYPE_RWSEM);
2058e9149858SPeter Zijlstra 
2059e9149858SPeter Zijlstra 	print_testname("mixed write-lock/lock-write ABBA");
2060e9149858SPeter Zijlstra 	pr_cont("             |");
2061e9149858SPeter Zijlstra 	dotest(rlock_ABBA3, FAILURE, LOCKTYPE_RWLOCK);
2062e9149858SPeter Zijlstra 	pr_cont("             |");
2063e9149858SPeter Zijlstra 	dotest(rwsem_ABBA3, FAILURE, LOCKTYPE_RWSEM);
2064e9149858SPeter Zijlstra 
2065cae2ed9aSIngo Molnar 	printk("  --------------------------------------------------------------------------\n");
2066cae2ed9aSIngo Molnar 
2067cae2ed9aSIngo Molnar 	/*
2068cae2ed9aSIngo Molnar 	 * irq-context testcases:
2069cae2ed9aSIngo Molnar 	 */
2070cae2ed9aSIngo Molnar 	DO_TESTCASE_2x6("irqs-on + irq-safe-A", irqsafe1);
2071cae2ed9aSIngo Molnar 	DO_TESTCASE_2x3("sirq-safe-A => hirqs-on", irqsafe2A);
2072cae2ed9aSIngo Molnar 	DO_TESTCASE_2x6("safe-A + irqs-on", irqsafe2B);
2073cae2ed9aSIngo Molnar 	DO_TESTCASE_6x6("safe-A + unsafe-B #1", irqsafe3);
2074cae2ed9aSIngo Molnar 	DO_TESTCASE_6x6("safe-A + unsafe-B #2", irqsafe4);
2075cae2ed9aSIngo Molnar 	DO_TESTCASE_6x6RW("irq lock-inversion", irq_inversion);
2076cae2ed9aSIngo Molnar 
2077cae2ed9aSIngo Molnar 	DO_TESTCASE_6x2("irq read-recursion", irq_read_recursion);
2078cae2ed9aSIngo Molnar //	DO_TESTCASE_6x2B("irq read-recursion #2", irq_read_recursion2);
2079cae2ed9aSIngo Molnar 
20801de99445SMaarten Lankhorst 	ww_tests();
20811de99445SMaarten Lankhorst 
2082*e9181886SBoqun Feng 	force_read_lock_recursive = 0;
2083*e9181886SBoqun Feng 	/*
2084*e9181886SBoqun Feng 	 * queued_read_lock() specific test cases can be put here
2085*e9181886SBoqun Feng 	 */
2086*e9181886SBoqun Feng 
2087cae2ed9aSIngo Molnar 	if (unexpected_testcase_failures) {
2088cae2ed9aSIngo Molnar 		printk("-----------------------------------------------------------------\n");
2089cae2ed9aSIngo Molnar 		debug_locks = 0;
2090cae2ed9aSIngo Molnar 		printk("BUG: %3d unexpected failures (out of %3d) - debugging disabled! |\n",
2091cae2ed9aSIngo Molnar 			unexpected_testcase_failures, testcase_total);
2092cae2ed9aSIngo Molnar 		printk("-----------------------------------------------------------------\n");
2093cae2ed9aSIngo Molnar 	} else if (expected_testcase_failures && testcase_successes) {
2094cae2ed9aSIngo Molnar 		printk("--------------------------------------------------------\n");
2095cae2ed9aSIngo Molnar 		printk("%3d out of %3d testcases failed, as expected. |\n",
2096cae2ed9aSIngo Molnar 			expected_testcase_failures, testcase_total);
2097cae2ed9aSIngo Molnar 		printk("----------------------------------------------------\n");
2098cae2ed9aSIngo Molnar 		debug_locks = 1;
2099cae2ed9aSIngo Molnar 	} else if (expected_testcase_failures && !testcase_successes) {
2100cae2ed9aSIngo Molnar 		printk("--------------------------------------------------------\n");
2101cae2ed9aSIngo Molnar 		printk("All %3d testcases failed, as expected. |\n",
2102cae2ed9aSIngo Molnar 			expected_testcase_failures);
2103cae2ed9aSIngo Molnar 		printk("----------------------------------------\n");
2104cae2ed9aSIngo Molnar 		debug_locks = 1;
2105cae2ed9aSIngo Molnar 	} else {
2106cae2ed9aSIngo Molnar 		printk("-------------------------------------------------------\n");
2107cae2ed9aSIngo Molnar 		printk("Good, all %3d testcases passed! |\n",
2108cae2ed9aSIngo Molnar 			testcase_successes);
2109cae2ed9aSIngo Molnar 		printk("---------------------------------\n");
2110cae2ed9aSIngo Molnar 		debug_locks = 1;
2111cae2ed9aSIngo Molnar 	}
2112cdc84d79SBart Van Assche 	lockdep_set_selftest_task(NULL);
2113cae2ed9aSIngo Molnar 	debug_locks_silent = 0;
2114cae2ed9aSIngo Molnar }
2115