xref: /linux-6.15/lib/locking-selftest.c (revision 8946ccc2)
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>
18d5037d1dSDaniel Vetter #include <linux/sched/mm.h>
19cae2ed9aSIngo Molnar #include <linux/delay.h>
20fbb9ce95SIngo Molnar #include <linux/lockdep.h>
21cae2ed9aSIngo Molnar #include <linux/spinlock.h>
22cae2ed9aSIngo Molnar #include <linux/kallsyms.h>
23cae2ed9aSIngo Molnar #include <linux/interrupt.h>
24cae2ed9aSIngo Molnar #include <linux/debug_locks.h>
25cae2ed9aSIngo Molnar #include <linux/irqflags.h>
26018956d6SPeter Zijlstra #include <linux/rtmutex.h>
277e923e6aSPeter Zijlstra #include <linux/local_lock.h>
28cae2ed9aSIngo Molnar 
29cae2ed9aSIngo Molnar /*
30cae2ed9aSIngo Molnar  * Change this to 1 if you want to see the failure printouts:
31cae2ed9aSIngo Molnar  */
32cae2ed9aSIngo Molnar static unsigned int debug_locks_verbose;
33e9181886SBoqun Feng unsigned int force_read_lock_recursive;
34cae2ed9aSIngo Molnar 
3508295b3bSThomas Hellstrom static DEFINE_WD_CLASS(ww_lockdep);
361de99445SMaarten Lankhorst 
37cae2ed9aSIngo Molnar static int __init setup_debug_locks_verbose(char *str)
38cae2ed9aSIngo Molnar {
39cae2ed9aSIngo Molnar 	get_option(&str, &debug_locks_verbose);
40cae2ed9aSIngo Molnar 
41cae2ed9aSIngo Molnar 	return 1;
42cae2ed9aSIngo Molnar }
43cae2ed9aSIngo Molnar 
44cae2ed9aSIngo Molnar __setup("debug_locks_verbose=", setup_debug_locks_verbose);
45cae2ed9aSIngo Molnar 
46cae2ed9aSIngo Molnar #define FAILURE		0
47cae2ed9aSIngo Molnar #define SUCCESS		1
48cae2ed9aSIngo Molnar 
49cae2ed9aSIngo Molnar #define LOCKTYPE_SPIN	0x1
50cae2ed9aSIngo Molnar #define LOCKTYPE_RWLOCK	0x2
51cae2ed9aSIngo Molnar #define LOCKTYPE_MUTEX	0x4
52cae2ed9aSIngo Molnar #define LOCKTYPE_RWSEM	0x8
531de99445SMaarten Lankhorst #define LOCKTYPE_WW	0x10
54018956d6SPeter Zijlstra #define LOCKTYPE_RTMUTEX 0x20
557e923e6aSPeter Zijlstra #define LOCKTYPE_LL	0x40
56*8946ccc2SBoqun Feng #define LOCKTYPE_SPECIAL 0x80
571de99445SMaarten Lankhorst 
581de99445SMaarten Lankhorst static struct ww_acquire_ctx t, t2;
59f3cf139eSMaarten Lankhorst static struct ww_mutex o, o2, o3;
60cae2ed9aSIngo Molnar 
61cae2ed9aSIngo Molnar /*
62cae2ed9aSIngo Molnar  * Normal standalone locks, for the circular and irq-context
63cae2ed9aSIngo Molnar  * dependency tests:
64cae2ed9aSIngo Molnar  */
65a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_A);
66a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_B);
67a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_C);
68a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_D);
69cae2ed9aSIngo Molnar 
709271a40dSBoqun Feng static DEFINE_RAW_SPINLOCK(raw_lock_A);
719271a40dSBoqun Feng static DEFINE_RAW_SPINLOCK(raw_lock_B);
729271a40dSBoqun Feng 
73cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_A);
74cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_B);
75cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_C);
76cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_D);
77cae2ed9aSIngo Molnar 
78cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_A);
79cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_B);
80cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_C);
81cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_D);
82cae2ed9aSIngo Molnar 
83cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_A);
84cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_B);
85cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_C);
86cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_D);
87cae2ed9aSIngo Molnar 
88018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
89018956d6SPeter Zijlstra 
90018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_A);
91018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_B);
92018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_C);
93018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_D);
94018956d6SPeter Zijlstra 
95018956d6SPeter Zijlstra #endif
96018956d6SPeter Zijlstra 
97cae2ed9aSIngo Molnar /*
98cae2ed9aSIngo Molnar  * Locks that we initialize dynamically as well so that
99cae2ed9aSIngo Molnar  * e.g. X1 and X2 becomes two instances of the same class,
100cae2ed9aSIngo Molnar  * but X* and Y* are different classes. We do this so that
101cae2ed9aSIngo Molnar  * we do not trigger a real lockup:
102cae2ed9aSIngo Molnar  */
103a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_X1);
104a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_X2);
105a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_Y1);
106a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_Y2);
107a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_Z1);
108a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_Z2);
109cae2ed9aSIngo Molnar 
110cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_X1);
111cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_X2);
112cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Y1);
113cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Y2);
114cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Z1);
115cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Z2);
116cae2ed9aSIngo Molnar 
117cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_X1);
118cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_X2);
119cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Y1);
120cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Y2);
121cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Z1);
122cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Z2);
123cae2ed9aSIngo Molnar 
124cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_X1);
125cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_X2);
126cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Y1);
127cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Y2);
128cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Z1);
129cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Z2);
130cae2ed9aSIngo Molnar 
131018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
132018956d6SPeter Zijlstra 
133018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_X1);
134018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_X2);
135018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_Y1);
136018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_Y2);
137018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_Z1);
138018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_Z2);
139018956d6SPeter Zijlstra 
140018956d6SPeter Zijlstra #endif
141018956d6SPeter Zijlstra 
1427e923e6aSPeter Zijlstra static local_lock_t local_A = INIT_LOCAL_LOCK(local_A);
1437e923e6aSPeter Zijlstra 
144cae2ed9aSIngo Molnar /*
145cae2ed9aSIngo Molnar  * non-inlined runtime initializers, to let separate locks share
146cae2ed9aSIngo Molnar  * the same lock-class:
147cae2ed9aSIngo Molnar  */
148cae2ed9aSIngo Molnar #define INIT_CLASS_FUNC(class) 				\
149cae2ed9aSIngo Molnar static noinline void					\
150a2e9ae58SPeter Zijlstra init_class_##class(spinlock_t *lock, rwlock_t *rwlock, \
1519fb1b90cSYong Zhang 	struct mutex *mutex, struct rw_semaphore *rwsem)\
152cae2ed9aSIngo Molnar {							\
153a2e9ae58SPeter Zijlstra 	spin_lock_init(lock);			\
154cae2ed9aSIngo Molnar 	rwlock_init(rwlock);				\
155cae2ed9aSIngo Molnar 	mutex_init(mutex);				\
156cae2ed9aSIngo Molnar 	init_rwsem(rwsem);				\
157cae2ed9aSIngo Molnar }
158cae2ed9aSIngo Molnar 
159cae2ed9aSIngo Molnar INIT_CLASS_FUNC(X)
160cae2ed9aSIngo Molnar INIT_CLASS_FUNC(Y)
161cae2ed9aSIngo Molnar INIT_CLASS_FUNC(Z)
162cae2ed9aSIngo Molnar 
163cae2ed9aSIngo Molnar static void init_shared_classes(void)
164cae2ed9aSIngo Molnar {
165018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
166018956d6SPeter Zijlstra 	static struct lock_class_key rt_X, rt_Y, rt_Z;
167018956d6SPeter Zijlstra 
168018956d6SPeter Zijlstra 	__rt_mutex_init(&rtmutex_X1, __func__, &rt_X);
169018956d6SPeter Zijlstra 	__rt_mutex_init(&rtmutex_X2, __func__, &rt_X);
170018956d6SPeter Zijlstra 	__rt_mutex_init(&rtmutex_Y1, __func__, &rt_Y);
171018956d6SPeter Zijlstra 	__rt_mutex_init(&rtmutex_Y2, __func__, &rt_Y);
172018956d6SPeter Zijlstra 	__rt_mutex_init(&rtmutex_Z1, __func__, &rt_Z);
173018956d6SPeter Zijlstra 	__rt_mutex_init(&rtmutex_Z2, __func__, &rt_Z);
174018956d6SPeter Zijlstra #endif
175018956d6SPeter Zijlstra 
176cae2ed9aSIngo Molnar 	init_class_X(&lock_X1, &rwlock_X1, &mutex_X1, &rwsem_X1);
177cae2ed9aSIngo Molnar 	init_class_X(&lock_X2, &rwlock_X2, &mutex_X2, &rwsem_X2);
178cae2ed9aSIngo Molnar 
179cae2ed9aSIngo Molnar 	init_class_Y(&lock_Y1, &rwlock_Y1, &mutex_Y1, &rwsem_Y1);
180cae2ed9aSIngo Molnar 	init_class_Y(&lock_Y2, &rwlock_Y2, &mutex_Y2, &rwsem_Y2);
181cae2ed9aSIngo Molnar 
182cae2ed9aSIngo Molnar 	init_class_Z(&lock_Z1, &rwlock_Z1, &mutex_Z1, &rwsem_Z1);
183cae2ed9aSIngo Molnar 	init_class_Z(&lock_Z2, &rwlock_Z2, &mutex_Z2, &rwsem_Z2);
184cae2ed9aSIngo Molnar }
185cae2ed9aSIngo Molnar 
186cae2ed9aSIngo Molnar /*
187cae2ed9aSIngo Molnar  * For spinlocks and rwlocks we also do hardirq-safe / softirq-safe tests.
188cae2ed9aSIngo Molnar  * The following functions use a lock from a simulated hardirq/softirq
189cae2ed9aSIngo Molnar  * context, causing the locks to be marked as hardirq-safe/softirq-safe:
190cae2ed9aSIngo Molnar  */
191cae2ed9aSIngo Molnar 
192cae2ed9aSIngo Molnar #define HARDIRQ_DISABLE		local_irq_disable
193cae2ed9aSIngo Molnar #define HARDIRQ_ENABLE		local_irq_enable
194cae2ed9aSIngo Molnar 
195cae2ed9aSIngo Molnar #define HARDIRQ_ENTER()				\
196cae2ed9aSIngo Molnar 	local_irq_disable();			\
197ba9f207cSFrederic Weisbecker 	__irq_enter();				\
198cae2ed9aSIngo Molnar 	WARN_ON(!in_irq());
199cae2ed9aSIngo Molnar 
200cae2ed9aSIngo Molnar #define HARDIRQ_EXIT()				\
201cae2ed9aSIngo Molnar 	__irq_exit();				\
202cae2ed9aSIngo Molnar 	local_irq_enable();
203cae2ed9aSIngo Molnar 
204cae2ed9aSIngo Molnar #define SOFTIRQ_DISABLE		local_bh_disable
205cae2ed9aSIngo Molnar #define SOFTIRQ_ENABLE		local_bh_enable
206cae2ed9aSIngo Molnar 
207cae2ed9aSIngo Molnar #define SOFTIRQ_ENTER()				\
208cae2ed9aSIngo Molnar 		local_bh_disable();		\
209cae2ed9aSIngo Molnar 		local_irq_disable();		\
210d820ac4cSIngo Molnar 		lockdep_softirq_enter();	\
211cae2ed9aSIngo Molnar 		WARN_ON(!in_softirq());
212cae2ed9aSIngo Molnar 
213cae2ed9aSIngo Molnar #define SOFTIRQ_EXIT()				\
214d820ac4cSIngo Molnar 		lockdep_softirq_exit();		\
215cae2ed9aSIngo Molnar 		local_irq_enable();		\
216cae2ed9aSIngo Molnar 		local_bh_enable();
217cae2ed9aSIngo Molnar 
218cae2ed9aSIngo Molnar /*
219cae2ed9aSIngo Molnar  * Shortcuts for lock/unlock API variants, to keep
220cae2ed9aSIngo Molnar  * the testcases compact:
221cae2ed9aSIngo Molnar  */
222a2e9ae58SPeter Zijlstra #define L(x)			spin_lock(&lock_##x)
223a2e9ae58SPeter Zijlstra #define U(x)			spin_unlock(&lock_##x)
224cae2ed9aSIngo Molnar #define LU(x)			L(x); U(x)
225a2e9ae58SPeter Zijlstra #define SI(x)			spin_lock_init(&lock_##x)
226cae2ed9aSIngo Molnar 
227cae2ed9aSIngo Molnar #define WL(x)			write_lock(&rwlock_##x)
228cae2ed9aSIngo Molnar #define WU(x)			write_unlock(&rwlock_##x)
229cae2ed9aSIngo Molnar #define WLU(x)			WL(x); WU(x)
230cae2ed9aSIngo Molnar 
231cae2ed9aSIngo Molnar #define RL(x)			read_lock(&rwlock_##x)
232cae2ed9aSIngo Molnar #define RU(x)			read_unlock(&rwlock_##x)
233cae2ed9aSIngo Molnar #define RLU(x)			RL(x); RU(x)
234cae2ed9aSIngo Molnar #define RWI(x)			rwlock_init(&rwlock_##x)
235cae2ed9aSIngo Molnar 
236cae2ed9aSIngo Molnar #define ML(x)			mutex_lock(&mutex_##x)
237cae2ed9aSIngo Molnar #define MU(x)			mutex_unlock(&mutex_##x)
238cae2ed9aSIngo Molnar #define MI(x)			mutex_init(&mutex_##x)
239cae2ed9aSIngo Molnar 
240018956d6SPeter Zijlstra #define RTL(x)			rt_mutex_lock(&rtmutex_##x)
241018956d6SPeter Zijlstra #define RTU(x)			rt_mutex_unlock(&rtmutex_##x)
242018956d6SPeter Zijlstra #define RTI(x)			rt_mutex_init(&rtmutex_##x)
243018956d6SPeter Zijlstra 
244cae2ed9aSIngo Molnar #define WSL(x)			down_write(&rwsem_##x)
245cae2ed9aSIngo Molnar #define WSU(x)			up_write(&rwsem_##x)
246cae2ed9aSIngo Molnar 
247cae2ed9aSIngo Molnar #define RSL(x)			down_read(&rwsem_##x)
248cae2ed9aSIngo Molnar #define RSU(x)			up_read(&rwsem_##x)
249cae2ed9aSIngo Molnar #define RWSI(x)			init_rwsem(&rwsem_##x)
250cae2ed9aSIngo Molnar 
2511de99445SMaarten Lankhorst #ifndef CONFIG_DEBUG_WW_MUTEX_SLOWPATH
2521de99445SMaarten Lankhorst #define WWAI(x)			ww_acquire_init(x, &ww_lockdep)
2531de99445SMaarten Lankhorst #else
2541de99445SMaarten Lankhorst #define WWAI(x)			do { ww_acquire_init(x, &ww_lockdep); (x)->deadlock_inject_countdown = ~0U; } while (0)
2551de99445SMaarten Lankhorst #endif
2561de99445SMaarten Lankhorst #define WWAD(x)			ww_acquire_done(x)
2571de99445SMaarten Lankhorst #define WWAF(x)			ww_acquire_fini(x)
2581de99445SMaarten Lankhorst 
2591de99445SMaarten Lankhorst #define WWL(x, c)		ww_mutex_lock(x, c)
2601de99445SMaarten Lankhorst #define WWT(x)			ww_mutex_trylock(x)
2611de99445SMaarten Lankhorst #define WWL1(x)			ww_mutex_lock(x, NULL)
2621de99445SMaarten Lankhorst #define WWU(x)			ww_mutex_unlock(x)
2631de99445SMaarten Lankhorst 
2641de99445SMaarten Lankhorst 
265cae2ed9aSIngo Molnar #define LOCK_UNLOCK_2(x,y)	LOCK(x); LOCK(y); UNLOCK(y); UNLOCK(x)
266cae2ed9aSIngo Molnar 
267cae2ed9aSIngo Molnar /*
268cae2ed9aSIngo Molnar  * Generate different permutations of the same testcase, using
269cae2ed9aSIngo Molnar  * the same basic lock-dependency/state events:
270cae2ed9aSIngo Molnar  */
271cae2ed9aSIngo Molnar 
272cae2ed9aSIngo Molnar #define GENERATE_TESTCASE(name)			\
273cae2ed9aSIngo Molnar 						\
274cae2ed9aSIngo Molnar static void name(void) { E(); }
275cae2ed9aSIngo Molnar 
276cae2ed9aSIngo Molnar #define GENERATE_PERMUTATIONS_2_EVENTS(name)	\
277cae2ed9aSIngo Molnar 						\
278cae2ed9aSIngo Molnar static void name##_12(void) { E1(); E2(); }	\
279cae2ed9aSIngo Molnar static void name##_21(void) { E2(); E1(); }
280cae2ed9aSIngo Molnar 
281cae2ed9aSIngo Molnar #define GENERATE_PERMUTATIONS_3_EVENTS(name)		\
282cae2ed9aSIngo Molnar 							\
283cae2ed9aSIngo Molnar static void name##_123(void) { E1(); E2(); E3(); }	\
284cae2ed9aSIngo Molnar static void name##_132(void) { E1(); E3(); E2(); }	\
285cae2ed9aSIngo Molnar static void name##_213(void) { E2(); E1(); E3(); }	\
286cae2ed9aSIngo Molnar static void name##_231(void) { E2(); E3(); E1(); }	\
287cae2ed9aSIngo Molnar static void name##_312(void) { E3(); E1(); E2(); }	\
288cae2ed9aSIngo Molnar static void name##_321(void) { E3(); E2(); E1(); }
289cae2ed9aSIngo Molnar 
290cae2ed9aSIngo Molnar /*
291cae2ed9aSIngo Molnar  * AA deadlock:
292cae2ed9aSIngo Molnar  */
293cae2ed9aSIngo Molnar 
294cae2ed9aSIngo Molnar #define E()					\
295cae2ed9aSIngo Molnar 						\
296cae2ed9aSIngo Molnar 	LOCK(X1);				\
297cae2ed9aSIngo Molnar 	LOCK(X2); /* this one should fail */
298cae2ed9aSIngo Molnar 
299cae2ed9aSIngo Molnar /*
300cae2ed9aSIngo Molnar  * 6 testcases:
301cae2ed9aSIngo Molnar  */
302cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
303cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_spin)
304cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
305cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_wlock)
306cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
307cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_rlock)
308cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
309cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_mutex)
310cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
311cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_wsem)
312cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
313cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_rsem)
314cae2ed9aSIngo Molnar 
315018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
316018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
317018956d6SPeter Zijlstra GENERATE_TESTCASE(AA_rtmutex);
318018956d6SPeter Zijlstra #endif
319018956d6SPeter Zijlstra 
320cae2ed9aSIngo Molnar #undef E
321cae2ed9aSIngo Molnar 
322cae2ed9aSIngo Molnar /*
323cae2ed9aSIngo Molnar  * Special-case for read-locking, they are
3246c9076ecSIngo Molnar  * allowed to recurse on the same lock class:
325cae2ed9aSIngo Molnar  */
326cae2ed9aSIngo Molnar static void rlock_AA1(void)
327cae2ed9aSIngo Molnar {
328cae2ed9aSIngo Molnar 	RL(X1);
329cae2ed9aSIngo Molnar 	RL(X1); // this one should NOT fail
330cae2ed9aSIngo Molnar }
331cae2ed9aSIngo Molnar 
332cae2ed9aSIngo Molnar static void rlock_AA1B(void)
333cae2ed9aSIngo Molnar {
334cae2ed9aSIngo Molnar 	RL(X1);
3356c9076ecSIngo Molnar 	RL(X2); // this one should NOT fail
336cae2ed9aSIngo Molnar }
337cae2ed9aSIngo Molnar 
338cae2ed9aSIngo Molnar static void rsem_AA1(void)
339cae2ed9aSIngo Molnar {
340cae2ed9aSIngo Molnar 	RSL(X1);
341cae2ed9aSIngo Molnar 	RSL(X1); // this one should fail
342cae2ed9aSIngo Molnar }
343cae2ed9aSIngo Molnar 
344cae2ed9aSIngo Molnar static void rsem_AA1B(void)
345cae2ed9aSIngo Molnar {
346cae2ed9aSIngo Molnar 	RSL(X1);
347cae2ed9aSIngo Molnar 	RSL(X2); // this one should fail
348cae2ed9aSIngo Molnar }
349cae2ed9aSIngo Molnar /*
350cae2ed9aSIngo Molnar  * The mixing of read and write locks is not allowed:
351cae2ed9aSIngo Molnar  */
352cae2ed9aSIngo Molnar static void rlock_AA2(void)
353cae2ed9aSIngo Molnar {
354cae2ed9aSIngo Molnar 	RL(X1);
355cae2ed9aSIngo Molnar 	WL(X2); // this one should fail
356cae2ed9aSIngo Molnar }
357cae2ed9aSIngo Molnar 
358cae2ed9aSIngo Molnar static void rsem_AA2(void)
359cae2ed9aSIngo Molnar {
360cae2ed9aSIngo Molnar 	RSL(X1);
361cae2ed9aSIngo Molnar 	WSL(X2); // this one should fail
362cae2ed9aSIngo Molnar }
363cae2ed9aSIngo Molnar 
364cae2ed9aSIngo Molnar static void rlock_AA3(void)
365cae2ed9aSIngo Molnar {
366cae2ed9aSIngo Molnar 	WL(X1);
367cae2ed9aSIngo Molnar 	RL(X2); // this one should fail
368cae2ed9aSIngo Molnar }
369cae2ed9aSIngo Molnar 
370cae2ed9aSIngo Molnar static void rsem_AA3(void)
371cae2ed9aSIngo Molnar {
372cae2ed9aSIngo Molnar 	WSL(X1);
373cae2ed9aSIngo Molnar 	RSL(X2); // this one should fail
374cae2ed9aSIngo Molnar }
375cae2ed9aSIngo Molnar 
376cae2ed9aSIngo Molnar /*
377e9149858SPeter Zijlstra  * read_lock(A)
378e9149858SPeter Zijlstra  * spin_lock(B)
379e9149858SPeter Zijlstra  *		spin_lock(B)
380e9149858SPeter Zijlstra  *		write_lock(A)
381e9149858SPeter Zijlstra  */
382e9149858SPeter Zijlstra static void rlock_ABBA1(void)
383e9149858SPeter Zijlstra {
384e9149858SPeter Zijlstra 	RL(X1);
385e9149858SPeter Zijlstra 	L(Y1);
386e9149858SPeter Zijlstra 	U(Y1);
387e9149858SPeter Zijlstra 	RU(X1);
388e9149858SPeter Zijlstra 
389e9149858SPeter Zijlstra 	L(Y1);
390e9149858SPeter Zijlstra 	WL(X1);
391e9149858SPeter Zijlstra 	WU(X1);
392e9149858SPeter Zijlstra 	U(Y1); // should fail
393e9149858SPeter Zijlstra }
394e9149858SPeter Zijlstra 
395e9149858SPeter Zijlstra static void rwsem_ABBA1(void)
396e9149858SPeter Zijlstra {
397e9149858SPeter Zijlstra 	RSL(X1);
398e9149858SPeter Zijlstra 	ML(Y1);
399e9149858SPeter Zijlstra 	MU(Y1);
400e9149858SPeter Zijlstra 	RSU(X1);
401e9149858SPeter Zijlstra 
402e9149858SPeter Zijlstra 	ML(Y1);
403e9149858SPeter Zijlstra 	WSL(X1);
404e9149858SPeter Zijlstra 	WSU(X1);
405e9149858SPeter Zijlstra 	MU(Y1); // should fail
406e9149858SPeter Zijlstra }
407e9149858SPeter Zijlstra 
408e9149858SPeter Zijlstra /*
409e9149858SPeter Zijlstra  * read_lock(A)
410e9149858SPeter Zijlstra  * spin_lock(B)
411e9149858SPeter Zijlstra  *		spin_lock(B)
412d4f200e5SBoqun Feng  *		write_lock(A)
413d4f200e5SBoqun Feng  *
414d4f200e5SBoqun Feng  * This test case is aimed at poking whether the chain cache prevents us from
415d4f200e5SBoqun Feng  * detecting a read-lock/lock-write deadlock: if the chain cache doesn't differ
416d4f200e5SBoqun Feng  * read/write locks, the following case may happen
417d4f200e5SBoqun Feng  *
418d4f200e5SBoqun Feng  * 	{ read_lock(A)->lock(B) dependency exists }
419d4f200e5SBoqun Feng  *
420d4f200e5SBoqun Feng  * 	P0:
421d4f200e5SBoqun Feng  * 	lock(B);
422d4f200e5SBoqun Feng  * 	read_lock(A);
423d4f200e5SBoqun Feng  *
424d4f200e5SBoqun Feng  *	{ Not a deadlock, B -> A is added in the chain cache }
425d4f200e5SBoqun Feng  *
426d4f200e5SBoqun Feng  *	P1:
427d4f200e5SBoqun Feng  *	lock(B);
428d4f200e5SBoqun Feng  *	write_lock(A);
429d4f200e5SBoqun Feng  *
430d4f200e5SBoqun Feng  *	{ B->A found in chain cache, not reported as a deadlock }
431d4f200e5SBoqun Feng  *
432d4f200e5SBoqun Feng  */
433d4f200e5SBoqun Feng static void rlock_chaincache_ABBA1(void)
434d4f200e5SBoqun Feng {
435d4f200e5SBoqun Feng 	RL(X1);
436d4f200e5SBoqun Feng 	L(Y1);
437d4f200e5SBoqun Feng 	U(Y1);
438d4f200e5SBoqun Feng 	RU(X1);
439d4f200e5SBoqun Feng 
440d4f200e5SBoqun Feng 	L(Y1);
441d4f200e5SBoqun Feng 	RL(X1);
442d4f200e5SBoqun Feng 	RU(X1);
443d4f200e5SBoqun Feng 	U(Y1);
444d4f200e5SBoqun Feng 
445d4f200e5SBoqun Feng 	L(Y1);
446d4f200e5SBoqun Feng 	WL(X1);
447d4f200e5SBoqun Feng 	WU(X1);
448d4f200e5SBoqun Feng 	U(Y1); // should fail
449d4f200e5SBoqun Feng }
450d4f200e5SBoqun Feng 
451d4f200e5SBoqun Feng /*
452d4f200e5SBoqun Feng  * read_lock(A)
453d4f200e5SBoqun Feng  * spin_lock(B)
454d4f200e5SBoqun Feng  *		spin_lock(B)
455e9149858SPeter Zijlstra  *		read_lock(A)
456e9149858SPeter Zijlstra  */
457e9149858SPeter Zijlstra static void rlock_ABBA2(void)
458e9149858SPeter Zijlstra {
459e9149858SPeter Zijlstra 	RL(X1);
460e9149858SPeter Zijlstra 	L(Y1);
461e9149858SPeter Zijlstra 	U(Y1);
462e9149858SPeter Zijlstra 	RU(X1);
463e9149858SPeter Zijlstra 
464e9149858SPeter Zijlstra 	L(Y1);
465e9149858SPeter Zijlstra 	RL(X1);
466e9149858SPeter Zijlstra 	RU(X1);
467e9149858SPeter Zijlstra 	U(Y1); // should NOT fail
468e9149858SPeter Zijlstra }
469e9149858SPeter Zijlstra 
470e9149858SPeter Zijlstra static void rwsem_ABBA2(void)
471e9149858SPeter Zijlstra {
472e9149858SPeter Zijlstra 	RSL(X1);
473e9149858SPeter Zijlstra 	ML(Y1);
474e9149858SPeter Zijlstra 	MU(Y1);
475e9149858SPeter Zijlstra 	RSU(X1);
476e9149858SPeter Zijlstra 
477e9149858SPeter Zijlstra 	ML(Y1);
478e9149858SPeter Zijlstra 	RSL(X1);
479e9149858SPeter Zijlstra 	RSU(X1);
480e9149858SPeter Zijlstra 	MU(Y1); // should fail
481e9149858SPeter Zijlstra }
482e9149858SPeter Zijlstra 
483e9149858SPeter Zijlstra 
484e9149858SPeter Zijlstra /*
485e9149858SPeter Zijlstra  * write_lock(A)
486e9149858SPeter Zijlstra  * spin_lock(B)
487e9149858SPeter Zijlstra  *		spin_lock(B)
488e9149858SPeter Zijlstra  *		write_lock(A)
489e9149858SPeter Zijlstra  */
490e9149858SPeter Zijlstra static void rlock_ABBA3(void)
491e9149858SPeter Zijlstra {
492e9149858SPeter Zijlstra 	WL(X1);
493e9149858SPeter Zijlstra 	L(Y1);
494e9149858SPeter Zijlstra 	U(Y1);
495e9149858SPeter Zijlstra 	WU(X1);
496e9149858SPeter Zijlstra 
497e9149858SPeter Zijlstra 	L(Y1);
498e9149858SPeter Zijlstra 	WL(X1);
499e9149858SPeter Zijlstra 	WU(X1);
500e9149858SPeter Zijlstra 	U(Y1); // should fail
501e9149858SPeter Zijlstra }
502e9149858SPeter Zijlstra 
503e9149858SPeter Zijlstra static void rwsem_ABBA3(void)
504e9149858SPeter Zijlstra {
505e9149858SPeter Zijlstra 	WSL(X1);
506e9149858SPeter Zijlstra 	ML(Y1);
507e9149858SPeter Zijlstra 	MU(Y1);
508e9149858SPeter Zijlstra 	WSU(X1);
509e9149858SPeter Zijlstra 
510e9149858SPeter Zijlstra 	ML(Y1);
511e9149858SPeter Zijlstra 	WSL(X1);
512e9149858SPeter Zijlstra 	WSU(X1);
513e9149858SPeter Zijlstra 	MU(Y1); // should fail
514e9149858SPeter Zijlstra }
515e9149858SPeter Zijlstra 
516e9149858SPeter Zijlstra /*
517cae2ed9aSIngo Molnar  * ABBA deadlock:
518cae2ed9aSIngo Molnar  */
519cae2ed9aSIngo Molnar 
520cae2ed9aSIngo Molnar #define E()					\
521cae2ed9aSIngo Molnar 						\
522cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
523cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, A); /* fail */
524cae2ed9aSIngo Molnar 
525cae2ed9aSIngo Molnar /*
526cae2ed9aSIngo Molnar  * 6 testcases:
527cae2ed9aSIngo Molnar  */
528cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
529cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_spin)
530cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
531cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_wlock)
532cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
533cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_rlock)
534cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
535cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_mutex)
536cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
537cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_wsem)
538cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
539cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_rsem)
540cae2ed9aSIngo Molnar 
541018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
542018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
543018956d6SPeter Zijlstra GENERATE_TESTCASE(ABBA_rtmutex);
544018956d6SPeter Zijlstra #endif
545018956d6SPeter Zijlstra 
546cae2ed9aSIngo Molnar #undef E
547cae2ed9aSIngo Molnar 
548cae2ed9aSIngo Molnar /*
549cae2ed9aSIngo Molnar  * AB BC CA deadlock:
550cae2ed9aSIngo Molnar  */
551cae2ed9aSIngo Molnar 
552cae2ed9aSIngo Molnar #define E()					\
553cae2ed9aSIngo Molnar 						\
554cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
555cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, C);			\
556cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, A); /* fail */
557cae2ed9aSIngo Molnar 
558cae2ed9aSIngo Molnar /*
559cae2ed9aSIngo Molnar  * 6 testcases:
560cae2ed9aSIngo Molnar  */
561cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
562cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_spin)
563cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
564cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_wlock)
565cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
566cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_rlock)
567cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
568cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_mutex)
569cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
570cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_wsem)
571cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
572cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_rsem)
573cae2ed9aSIngo Molnar 
574018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
575018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
576018956d6SPeter Zijlstra GENERATE_TESTCASE(ABBCCA_rtmutex);
577018956d6SPeter Zijlstra #endif
578018956d6SPeter Zijlstra 
579cae2ed9aSIngo Molnar #undef E
580cae2ed9aSIngo Molnar 
581cae2ed9aSIngo Molnar /*
582cae2ed9aSIngo Molnar  * AB CA BC deadlock:
583cae2ed9aSIngo Molnar  */
584cae2ed9aSIngo Molnar 
585cae2ed9aSIngo Molnar #define E()					\
586cae2ed9aSIngo Molnar 						\
587cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
588cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, A);			\
589cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, C); /* fail */
590cae2ed9aSIngo Molnar 
591cae2ed9aSIngo Molnar /*
592cae2ed9aSIngo Molnar  * 6 testcases:
593cae2ed9aSIngo Molnar  */
594cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
595cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_spin)
596cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
597cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_wlock)
598cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
599cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_rlock)
600cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
601cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_mutex)
602cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
603cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_wsem)
604cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
605cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_rsem)
606cae2ed9aSIngo Molnar 
607018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
608018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
609018956d6SPeter Zijlstra GENERATE_TESTCASE(ABCABC_rtmutex);
610018956d6SPeter Zijlstra #endif
611018956d6SPeter Zijlstra 
612cae2ed9aSIngo Molnar #undef E
613cae2ed9aSIngo Molnar 
614cae2ed9aSIngo Molnar /*
615cae2ed9aSIngo Molnar  * AB BC CD DA deadlock:
616cae2ed9aSIngo Molnar  */
617cae2ed9aSIngo Molnar 
618cae2ed9aSIngo Molnar #define E()					\
619cae2ed9aSIngo Molnar 						\
620cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
621cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, C);			\
622cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, D);			\
623cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(D, A); /* fail */
624cae2ed9aSIngo Molnar 
625cae2ed9aSIngo Molnar /*
626cae2ed9aSIngo Molnar  * 6 testcases:
627cae2ed9aSIngo Molnar  */
628cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
629cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_spin)
630cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
631cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_wlock)
632cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
633cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_rlock)
634cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
635cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_mutex)
636cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
637cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_wsem)
638cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
639cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_rsem)
640cae2ed9aSIngo Molnar 
641018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
642018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
643018956d6SPeter Zijlstra GENERATE_TESTCASE(ABBCCDDA_rtmutex);
644018956d6SPeter Zijlstra #endif
645018956d6SPeter Zijlstra 
646cae2ed9aSIngo Molnar #undef E
647cae2ed9aSIngo Molnar 
648cae2ed9aSIngo Molnar /*
649cae2ed9aSIngo Molnar  * AB CD BD DA deadlock:
650cae2ed9aSIngo Molnar  */
651cae2ed9aSIngo Molnar #define E()					\
652cae2ed9aSIngo Molnar 						\
653cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
654cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, D);			\
655cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, D);			\
656cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(D, A); /* fail */
657cae2ed9aSIngo Molnar 
658cae2ed9aSIngo Molnar /*
659cae2ed9aSIngo Molnar  * 6 testcases:
660cae2ed9aSIngo Molnar  */
661cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
662cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_spin)
663cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
664cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_wlock)
665cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
666cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_rlock)
667cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
668cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_mutex)
669cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
670cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_wsem)
671cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
672cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_rsem)
673cae2ed9aSIngo Molnar 
674018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
675018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
676018956d6SPeter Zijlstra GENERATE_TESTCASE(ABCDBDDA_rtmutex);
677018956d6SPeter Zijlstra #endif
678018956d6SPeter Zijlstra 
679cae2ed9aSIngo Molnar #undef E
680cae2ed9aSIngo Molnar 
681cae2ed9aSIngo Molnar /*
682cae2ed9aSIngo Molnar  * AB CD BC DA deadlock:
683cae2ed9aSIngo Molnar  */
684cae2ed9aSIngo Molnar #define E()					\
685cae2ed9aSIngo Molnar 						\
686cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(A, B);			\
687cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(C, D);			\
688cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(B, C);			\
689cae2ed9aSIngo Molnar 	LOCK_UNLOCK_2(D, A); /* fail */
690cae2ed9aSIngo Molnar 
691cae2ed9aSIngo Molnar /*
692cae2ed9aSIngo Molnar  * 6 testcases:
693cae2ed9aSIngo Molnar  */
694cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
695cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_spin)
696cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
697cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_wlock)
698cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
699cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_rlock)
700cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
701cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_mutex)
702cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
703cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_wsem)
704cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
705cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_rsem)
706cae2ed9aSIngo Molnar 
707018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
708018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
709018956d6SPeter Zijlstra GENERATE_TESTCASE(ABCDBCDA_rtmutex);
710018956d6SPeter Zijlstra #endif
711018956d6SPeter Zijlstra 
712cae2ed9aSIngo Molnar #undef E
713cae2ed9aSIngo Molnar 
714cae2ed9aSIngo Molnar /*
715cae2ed9aSIngo Molnar  * Double unlock:
716cae2ed9aSIngo Molnar  */
717cae2ed9aSIngo Molnar #define E()					\
718cae2ed9aSIngo Molnar 						\
719cae2ed9aSIngo Molnar 	LOCK(A);				\
720cae2ed9aSIngo Molnar 	UNLOCK(A);				\
721cae2ed9aSIngo Molnar 	UNLOCK(A); /* fail */
722cae2ed9aSIngo Molnar 
723cae2ed9aSIngo Molnar /*
724cae2ed9aSIngo Molnar  * 6 testcases:
725cae2ed9aSIngo Molnar  */
726cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
727cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_spin)
728cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
729cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_wlock)
730cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
731cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_rlock)
732cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
733cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_mutex)
734cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
735cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_wsem)
736cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
737cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_rsem)
738cae2ed9aSIngo Molnar 
739018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
740018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
741018956d6SPeter Zijlstra GENERATE_TESTCASE(double_unlock_rtmutex);
742018956d6SPeter Zijlstra #endif
743018956d6SPeter Zijlstra 
744cae2ed9aSIngo Molnar #undef E
745cae2ed9aSIngo Molnar 
746cae2ed9aSIngo Molnar /*
747cae2ed9aSIngo Molnar  * initializing a held lock:
748cae2ed9aSIngo Molnar  */
749cae2ed9aSIngo Molnar #define E()					\
750cae2ed9aSIngo Molnar 						\
751cae2ed9aSIngo Molnar 	LOCK(A);				\
752cae2ed9aSIngo Molnar 	INIT(A); /* fail */
753cae2ed9aSIngo Molnar 
754cae2ed9aSIngo Molnar /*
755cae2ed9aSIngo Molnar  * 6 testcases:
756cae2ed9aSIngo Molnar  */
757cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
758cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_spin)
759cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
760cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_wlock)
761cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
762cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_rlock)
763cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
764cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_mutex)
765cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
766cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_wsem)
767cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
768cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_rsem)
769cae2ed9aSIngo Molnar 
770018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
771018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
772018956d6SPeter Zijlstra GENERATE_TESTCASE(init_held_rtmutex);
773018956d6SPeter Zijlstra #endif
774018956d6SPeter Zijlstra 
775cae2ed9aSIngo Molnar #undef E
776cae2ed9aSIngo Molnar 
777cae2ed9aSIngo Molnar /*
778cae2ed9aSIngo Molnar  * locking an irq-safe lock with irqs enabled:
779cae2ed9aSIngo Molnar  */
780cae2ed9aSIngo Molnar #define E1()				\
781cae2ed9aSIngo Molnar 					\
782cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
783cae2ed9aSIngo Molnar 	LOCK(A);			\
784cae2ed9aSIngo Molnar 	UNLOCK(A);			\
785cae2ed9aSIngo Molnar 	IRQ_EXIT();
786cae2ed9aSIngo Molnar 
787cae2ed9aSIngo Molnar #define E2()				\
788cae2ed9aSIngo Molnar 					\
789cae2ed9aSIngo Molnar 	LOCK(A);			\
790cae2ed9aSIngo Molnar 	UNLOCK(A);
791cae2ed9aSIngo Molnar 
792cae2ed9aSIngo Molnar /*
793cae2ed9aSIngo Molnar  * Generate 24 testcases:
794cae2ed9aSIngo Molnar  */
795cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
796cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_spin)
797cae2ed9aSIngo Molnar 
798cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
799cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_rlock)
800cae2ed9aSIngo Molnar 
801cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
802cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_wlock)
803cae2ed9aSIngo Molnar 
804cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
805cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_spin)
806cae2ed9aSIngo Molnar 
807cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
808cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_rlock)
809cae2ed9aSIngo Molnar 
810cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
811cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_wlock)
812cae2ed9aSIngo Molnar 
813cae2ed9aSIngo Molnar #undef E1
814cae2ed9aSIngo Molnar #undef E2
815cae2ed9aSIngo Molnar 
816cae2ed9aSIngo Molnar /*
817cae2ed9aSIngo Molnar  * Enabling hardirqs with a softirq-safe lock held:
818cae2ed9aSIngo Molnar  */
819cae2ed9aSIngo Molnar #define E1()				\
820cae2ed9aSIngo Molnar 					\
821cae2ed9aSIngo Molnar 	SOFTIRQ_ENTER();		\
822cae2ed9aSIngo Molnar 	LOCK(A);			\
823cae2ed9aSIngo Molnar 	UNLOCK(A);			\
824cae2ed9aSIngo Molnar 	SOFTIRQ_EXIT();
825cae2ed9aSIngo Molnar 
826cae2ed9aSIngo Molnar #define E2()				\
827cae2ed9aSIngo Molnar 					\
828cae2ed9aSIngo Molnar 	HARDIRQ_DISABLE();		\
829cae2ed9aSIngo Molnar 	LOCK(A);			\
830cae2ed9aSIngo Molnar 	HARDIRQ_ENABLE();		\
831cae2ed9aSIngo Molnar 	UNLOCK(A);
832cae2ed9aSIngo Molnar 
833cae2ed9aSIngo Molnar /*
834cae2ed9aSIngo Molnar  * Generate 12 testcases:
835cae2ed9aSIngo Molnar  */
836cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
837cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_spin)
838cae2ed9aSIngo Molnar 
839cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
840cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_wlock)
841cae2ed9aSIngo Molnar 
842cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
843cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_rlock)
844cae2ed9aSIngo Molnar 
845cae2ed9aSIngo Molnar #undef E1
846cae2ed9aSIngo Molnar #undef E2
847cae2ed9aSIngo Molnar 
848cae2ed9aSIngo Molnar /*
849cae2ed9aSIngo Molnar  * Enabling irqs with an irq-safe lock held:
850cae2ed9aSIngo Molnar  */
851cae2ed9aSIngo Molnar #define E1()				\
852cae2ed9aSIngo Molnar 					\
853cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
854cae2ed9aSIngo Molnar 	LOCK(A);			\
855cae2ed9aSIngo Molnar 	UNLOCK(A);			\
856cae2ed9aSIngo Molnar 	IRQ_EXIT();
857cae2ed9aSIngo Molnar 
858cae2ed9aSIngo Molnar #define E2()				\
859cae2ed9aSIngo Molnar 					\
860cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
861cae2ed9aSIngo Molnar 	LOCK(A);			\
862cae2ed9aSIngo Molnar 	IRQ_ENABLE();			\
863cae2ed9aSIngo Molnar 	UNLOCK(A);
864cae2ed9aSIngo Molnar 
865cae2ed9aSIngo Molnar /*
866cae2ed9aSIngo Molnar  * Generate 24 testcases:
867cae2ed9aSIngo Molnar  */
868cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
869cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_spin)
870cae2ed9aSIngo Molnar 
871cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
872cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_rlock)
873cae2ed9aSIngo Molnar 
874cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
875cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_wlock)
876cae2ed9aSIngo Molnar 
877cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
878cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_spin)
879cae2ed9aSIngo Molnar 
880cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
881cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_rlock)
882cae2ed9aSIngo Molnar 
883cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
884cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock)
885cae2ed9aSIngo Molnar 
886cae2ed9aSIngo Molnar #undef E1
887cae2ed9aSIngo Molnar #undef E2
888cae2ed9aSIngo Molnar 
889cae2ed9aSIngo Molnar /*
890cae2ed9aSIngo Molnar  * Acquiring a irq-unsafe lock while holding an irq-safe-lock:
891cae2ed9aSIngo Molnar  */
892cae2ed9aSIngo Molnar #define E1()				\
893cae2ed9aSIngo Molnar 					\
894cae2ed9aSIngo Molnar 	LOCK(A);			\
895cae2ed9aSIngo Molnar 	LOCK(B);			\
896cae2ed9aSIngo Molnar 	UNLOCK(B);			\
897cae2ed9aSIngo Molnar 	UNLOCK(A);			\
898cae2ed9aSIngo Molnar 
899cae2ed9aSIngo Molnar #define E2()				\
900cae2ed9aSIngo Molnar 					\
901cae2ed9aSIngo Molnar 	LOCK(B);			\
902cae2ed9aSIngo Molnar 	UNLOCK(B);
903cae2ed9aSIngo Molnar 
904cae2ed9aSIngo Molnar #define E3()				\
905cae2ed9aSIngo Molnar 					\
906cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
907cae2ed9aSIngo Molnar 	LOCK(A);			\
908cae2ed9aSIngo Molnar 	UNLOCK(A);			\
909cae2ed9aSIngo Molnar 	IRQ_EXIT();
910cae2ed9aSIngo Molnar 
911cae2ed9aSIngo Molnar /*
912cae2ed9aSIngo Molnar  * Generate 36 testcases:
913cae2ed9aSIngo Molnar  */
914cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
915cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_spin)
916cae2ed9aSIngo Molnar 
917cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
918cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_rlock)
919cae2ed9aSIngo Molnar 
920cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
921cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_wlock)
922cae2ed9aSIngo Molnar 
923cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
924cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_spin)
925cae2ed9aSIngo Molnar 
926cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
927cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_rlock)
928cae2ed9aSIngo Molnar 
929cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
930cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock)
931cae2ed9aSIngo Molnar 
932cae2ed9aSIngo Molnar #undef E1
933cae2ed9aSIngo Molnar #undef E2
934cae2ed9aSIngo Molnar #undef E3
935cae2ed9aSIngo Molnar 
936cae2ed9aSIngo Molnar /*
937cae2ed9aSIngo Molnar  * If a lock turns into softirq-safe, but earlier it took
938cae2ed9aSIngo Molnar  * a softirq-unsafe lock:
939cae2ed9aSIngo Molnar  */
940cae2ed9aSIngo Molnar 
941cae2ed9aSIngo Molnar #define E1()				\
942cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
943cae2ed9aSIngo Molnar 	LOCK(A);			\
944cae2ed9aSIngo Molnar 	LOCK(B);			\
945cae2ed9aSIngo Molnar 	UNLOCK(B);			\
946cae2ed9aSIngo Molnar 	UNLOCK(A);			\
947cae2ed9aSIngo Molnar 	IRQ_ENABLE();
948cae2ed9aSIngo Molnar 
949cae2ed9aSIngo Molnar #define E2()				\
950cae2ed9aSIngo Molnar 	LOCK(B);			\
951cae2ed9aSIngo Molnar 	UNLOCK(B);
952cae2ed9aSIngo Molnar 
953cae2ed9aSIngo Molnar #define E3()				\
954cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
955cae2ed9aSIngo Molnar 	LOCK(A);			\
956cae2ed9aSIngo Molnar 	UNLOCK(A);			\
957cae2ed9aSIngo Molnar 	IRQ_EXIT();
958cae2ed9aSIngo Molnar 
959cae2ed9aSIngo Molnar /*
960cae2ed9aSIngo Molnar  * Generate 36 testcases:
961cae2ed9aSIngo Molnar  */
962cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
963cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_spin)
964cae2ed9aSIngo Molnar 
965cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
966cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_rlock)
967cae2ed9aSIngo Molnar 
968cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
969cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_wlock)
970cae2ed9aSIngo Molnar 
971cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
972cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_spin)
973cae2ed9aSIngo Molnar 
974cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
975cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_rlock)
976cae2ed9aSIngo Molnar 
977cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
978cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_wlock)
979cae2ed9aSIngo Molnar 
980cae2ed9aSIngo Molnar #undef E1
981cae2ed9aSIngo Molnar #undef E2
982cae2ed9aSIngo Molnar #undef E3
983cae2ed9aSIngo Molnar 
984cae2ed9aSIngo Molnar /*
985cae2ed9aSIngo Molnar  * read-lock / write-lock irq inversion.
986cae2ed9aSIngo Molnar  *
987cae2ed9aSIngo Molnar  * Deadlock scenario:
988cae2ed9aSIngo Molnar  *
989cae2ed9aSIngo Molnar  * CPU#1 is at #1, i.e. it has write-locked A, but has not
990cae2ed9aSIngo Molnar  * taken B yet.
991cae2ed9aSIngo Molnar  *
992cae2ed9aSIngo Molnar  * CPU#2 is at #2, i.e. it has locked B.
993cae2ed9aSIngo Molnar  *
994cae2ed9aSIngo Molnar  * Hardirq hits CPU#2 at point #2 and is trying to read-lock A.
995cae2ed9aSIngo Molnar  *
996cae2ed9aSIngo Molnar  * The deadlock occurs because CPU#1 will spin on B, and CPU#2
997cae2ed9aSIngo Molnar  * will spin on A.
998cae2ed9aSIngo Molnar  */
999cae2ed9aSIngo Molnar 
1000cae2ed9aSIngo Molnar #define E1()				\
1001cae2ed9aSIngo Molnar 					\
1002cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
1003cae2ed9aSIngo Molnar 	WL(A);				\
1004cae2ed9aSIngo Molnar 	LOCK(B);			\
1005cae2ed9aSIngo Molnar 	UNLOCK(B);			\
1006cae2ed9aSIngo Molnar 	WU(A);				\
1007cae2ed9aSIngo Molnar 	IRQ_ENABLE();
1008cae2ed9aSIngo Molnar 
1009cae2ed9aSIngo Molnar #define E2()				\
1010cae2ed9aSIngo Molnar 					\
1011cae2ed9aSIngo Molnar 	LOCK(B);			\
1012cae2ed9aSIngo Molnar 	UNLOCK(B);
1013cae2ed9aSIngo Molnar 
1014cae2ed9aSIngo Molnar #define E3()				\
1015cae2ed9aSIngo Molnar 					\
1016cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
1017cae2ed9aSIngo Molnar 	RL(A);				\
1018cae2ed9aSIngo Molnar 	RU(A);				\
1019cae2ed9aSIngo Molnar 	IRQ_EXIT();
1020cae2ed9aSIngo Molnar 
1021cae2ed9aSIngo Molnar /*
1022cae2ed9aSIngo Molnar  * Generate 36 testcases:
1023cae2ed9aSIngo Molnar  */
1024cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
1025cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_spin)
1026cae2ed9aSIngo Molnar 
1027cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
1028cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_rlock)
1029cae2ed9aSIngo Molnar 
1030cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
1031cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_wlock)
1032cae2ed9aSIngo Molnar 
1033cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
1034cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_spin)
1035cae2ed9aSIngo Molnar 
1036cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
1037cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_rlock)
1038cae2ed9aSIngo Molnar 
1039cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
1040cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_wlock)
1041cae2ed9aSIngo Molnar 
1042cae2ed9aSIngo Molnar #undef E1
1043cae2ed9aSIngo Molnar #undef E2
1044cae2ed9aSIngo Molnar #undef E3
1045cae2ed9aSIngo Molnar 
1046cae2ed9aSIngo Molnar /*
10478ef7ca75SBoqun Feng  * write-read / write-read / write-read deadlock even if read is recursive
10488ef7ca75SBoqun Feng  */
10498ef7ca75SBoqun Feng 
10508ef7ca75SBoqun Feng #define E1()				\
10518ef7ca75SBoqun Feng 					\
10528ef7ca75SBoqun Feng 	WL(X1);				\
10538ef7ca75SBoqun Feng 	RL(Y1);				\
10548ef7ca75SBoqun Feng 	RU(Y1);				\
10558ef7ca75SBoqun Feng 	WU(X1);
10568ef7ca75SBoqun Feng 
10578ef7ca75SBoqun Feng #define E2()				\
10588ef7ca75SBoqun Feng 					\
10598ef7ca75SBoqun Feng 	WL(Y1);				\
10608ef7ca75SBoqun Feng 	RL(Z1);				\
10618ef7ca75SBoqun Feng 	RU(Z1);				\
10628ef7ca75SBoqun Feng 	WU(Y1);
10638ef7ca75SBoqun Feng 
10648ef7ca75SBoqun Feng #define E3()				\
10658ef7ca75SBoqun Feng 					\
10668ef7ca75SBoqun Feng 	WL(Z1);				\
10678ef7ca75SBoqun Feng 	RL(X1);				\
10688ef7ca75SBoqun Feng 	RU(X1);				\
10698ef7ca75SBoqun Feng 	WU(Z1);
10708ef7ca75SBoqun Feng 
10718ef7ca75SBoqun Feng #include "locking-selftest-rlock.h"
10728ef7ca75SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(W1R2_W2R3_W3R1)
10738ef7ca75SBoqun Feng 
10748ef7ca75SBoqun Feng #undef E1
10758ef7ca75SBoqun Feng #undef E2
10768ef7ca75SBoqun Feng #undef E3
10778ef7ca75SBoqun Feng 
10788ef7ca75SBoqun Feng /*
10798ef7ca75SBoqun Feng  * write-write / read-read / write-read deadlock even if read is recursive
10808ef7ca75SBoqun Feng  */
10818ef7ca75SBoqun Feng 
10828ef7ca75SBoqun Feng #define E1()				\
10838ef7ca75SBoqun Feng 					\
10848ef7ca75SBoqun Feng 	WL(X1);				\
10858ef7ca75SBoqun Feng 	WL(Y1);				\
10868ef7ca75SBoqun Feng 	WU(Y1);				\
10878ef7ca75SBoqun Feng 	WU(X1);
10888ef7ca75SBoqun Feng 
10898ef7ca75SBoqun Feng #define E2()				\
10908ef7ca75SBoqun Feng 					\
10918ef7ca75SBoqun Feng 	RL(Y1);				\
10928ef7ca75SBoqun Feng 	RL(Z1);				\
10938ef7ca75SBoqun Feng 	RU(Z1);				\
10948ef7ca75SBoqun Feng 	RU(Y1);
10958ef7ca75SBoqun Feng 
10968ef7ca75SBoqun Feng #define E3()				\
10978ef7ca75SBoqun Feng 					\
10988ef7ca75SBoqun Feng 	WL(Z1);				\
10998ef7ca75SBoqun Feng 	RL(X1);				\
11008ef7ca75SBoqun Feng 	RU(X1);				\
11018ef7ca75SBoqun Feng 	WU(Z1);
11028ef7ca75SBoqun Feng 
11038ef7ca75SBoqun Feng #include "locking-selftest-rlock.h"
11048ef7ca75SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(W1W2_R2R3_W3R1)
11058ef7ca75SBoqun Feng 
11068ef7ca75SBoqun Feng #undef E1
11078ef7ca75SBoqun Feng #undef E2
11088ef7ca75SBoqun Feng #undef E3
11098ef7ca75SBoqun Feng 
11108ef7ca75SBoqun Feng /*
11118ef7ca75SBoqun Feng  * write-write / read-read / read-write is not deadlock when read is recursive
11128ef7ca75SBoqun Feng  */
11138ef7ca75SBoqun Feng 
11148ef7ca75SBoqun Feng #define E1()				\
11158ef7ca75SBoqun Feng 					\
11168ef7ca75SBoqun Feng 	WL(X1);				\
11178ef7ca75SBoqun Feng 	WL(Y1);				\
11188ef7ca75SBoqun Feng 	WU(Y1);				\
11198ef7ca75SBoqun Feng 	WU(X1);
11208ef7ca75SBoqun Feng 
11218ef7ca75SBoqun Feng #define E2()				\
11228ef7ca75SBoqun Feng 					\
11238ef7ca75SBoqun Feng 	RL(Y1);				\
11248ef7ca75SBoqun Feng 	RL(Z1);				\
11258ef7ca75SBoqun Feng 	RU(Z1);				\
11268ef7ca75SBoqun Feng 	RU(Y1);
11278ef7ca75SBoqun Feng 
11288ef7ca75SBoqun Feng #define E3()				\
11298ef7ca75SBoqun Feng 					\
11308ef7ca75SBoqun Feng 	RL(Z1);				\
11318ef7ca75SBoqun Feng 	WL(X1);				\
11328ef7ca75SBoqun Feng 	WU(X1);				\
11338ef7ca75SBoqun Feng 	RU(Z1);
11348ef7ca75SBoqun Feng 
11358ef7ca75SBoqun Feng #include "locking-selftest-rlock.h"
11368ef7ca75SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(W1R2_R2R3_W3W1)
11378ef7ca75SBoqun Feng 
11388ef7ca75SBoqun Feng #undef E1
11398ef7ca75SBoqun Feng #undef E2
11408ef7ca75SBoqun Feng #undef E3
11418ef7ca75SBoqun Feng 
11428ef7ca75SBoqun Feng /*
11438ef7ca75SBoqun Feng  * write-read / read-read / write-write is not deadlock when read is recursive
11448ef7ca75SBoqun Feng  */
11458ef7ca75SBoqun Feng 
11468ef7ca75SBoqun Feng #define E1()				\
11478ef7ca75SBoqun Feng 					\
11488ef7ca75SBoqun Feng 	WL(X1);				\
11498ef7ca75SBoqun Feng 	RL(Y1);				\
11508ef7ca75SBoqun Feng 	RU(Y1);				\
11518ef7ca75SBoqun Feng 	WU(X1);
11528ef7ca75SBoqun Feng 
11538ef7ca75SBoqun Feng #define E2()				\
11548ef7ca75SBoqun Feng 					\
11558ef7ca75SBoqun Feng 	RL(Y1);				\
11568ef7ca75SBoqun Feng 	RL(Z1);				\
11578ef7ca75SBoqun Feng 	RU(Z1);				\
11588ef7ca75SBoqun Feng 	RU(Y1);
11598ef7ca75SBoqun Feng 
11608ef7ca75SBoqun Feng #define E3()				\
11618ef7ca75SBoqun Feng 					\
11628ef7ca75SBoqun Feng 	WL(Z1);				\
11638ef7ca75SBoqun Feng 	WL(X1);				\
11648ef7ca75SBoqun Feng 	WU(X1);				\
11658ef7ca75SBoqun Feng 	WU(Z1);
11668ef7ca75SBoqun Feng 
11678ef7ca75SBoqun Feng #include "locking-selftest-rlock.h"
11688ef7ca75SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(W1W2_R2R3_R3W1)
11698ef7ca75SBoqun Feng 
11708ef7ca75SBoqun Feng #undef E1
11718ef7ca75SBoqun Feng #undef E2
11728ef7ca75SBoqun Feng #undef E3
11738ef7ca75SBoqun Feng /*
1174cae2ed9aSIngo Molnar  * read-lock / write-lock recursion that is actually safe.
1175cae2ed9aSIngo Molnar  */
1176cae2ed9aSIngo Molnar 
1177cae2ed9aSIngo Molnar #define E1()				\
1178cae2ed9aSIngo Molnar 					\
1179cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
1180cae2ed9aSIngo Molnar 	WL(A);				\
1181cae2ed9aSIngo Molnar 	WU(A);				\
1182cae2ed9aSIngo Molnar 	IRQ_ENABLE();
1183cae2ed9aSIngo Molnar 
1184cae2ed9aSIngo Molnar #define E2()				\
1185cae2ed9aSIngo Molnar 					\
1186cae2ed9aSIngo Molnar 	RL(A);				\
1187cae2ed9aSIngo Molnar 	RU(A);				\
1188cae2ed9aSIngo Molnar 
1189cae2ed9aSIngo Molnar #define E3()				\
1190cae2ed9aSIngo Molnar 					\
1191cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
119231e0d747SBoqun Feng 	LOCK(A);			\
1193cae2ed9aSIngo Molnar 	L(B);				\
1194cae2ed9aSIngo Molnar 	U(B);				\
119531e0d747SBoqun Feng 	UNLOCK(A);			\
1196cae2ed9aSIngo Molnar 	IRQ_EXIT();
1197cae2ed9aSIngo Molnar 
1198cae2ed9aSIngo Molnar /*
119931e0d747SBoqun Feng  * Generate 24 testcases:
1200cae2ed9aSIngo Molnar  */
1201cae2ed9aSIngo Molnar #include "locking-selftest-hardirq.h"
120231e0d747SBoqun Feng #include "locking-selftest-rlock.h"
120331e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard_rlock)
120431e0d747SBoqun Feng 
120531e0d747SBoqun Feng #include "locking-selftest-wlock.h"
120631e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard_wlock)
1207cae2ed9aSIngo Molnar 
1208cae2ed9aSIngo Molnar #include "locking-selftest-softirq.h"
120931e0d747SBoqun Feng #include "locking-selftest-rlock.h"
121031e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft_rlock)
121131e0d747SBoqun Feng 
121231e0d747SBoqun Feng #include "locking-selftest-wlock.h"
121331e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft_wlock)
1214cae2ed9aSIngo Molnar 
1215cae2ed9aSIngo Molnar #undef E1
1216cae2ed9aSIngo Molnar #undef E2
1217cae2ed9aSIngo Molnar #undef E3
1218cae2ed9aSIngo Molnar 
1219cae2ed9aSIngo Molnar /*
1220cae2ed9aSIngo Molnar  * read-lock / write-lock recursion that is unsafe.
1221cae2ed9aSIngo Molnar  */
1222cae2ed9aSIngo Molnar 
1223cae2ed9aSIngo Molnar #define E1()				\
1224cae2ed9aSIngo Molnar 					\
1225cae2ed9aSIngo Molnar 	IRQ_DISABLE();			\
1226cae2ed9aSIngo Molnar 	L(B);				\
122731e0d747SBoqun Feng 	LOCK(A);			\
122831e0d747SBoqun Feng 	UNLOCK(A);			\
1229cae2ed9aSIngo Molnar 	U(B);				\
1230cae2ed9aSIngo Molnar 	IRQ_ENABLE();
1231cae2ed9aSIngo Molnar 
1232cae2ed9aSIngo Molnar #define E2()				\
1233cae2ed9aSIngo Molnar 					\
1234cae2ed9aSIngo Molnar 	RL(A);				\
1235cae2ed9aSIngo Molnar 	RU(A);				\
1236cae2ed9aSIngo Molnar 
1237cae2ed9aSIngo Molnar #define E3()				\
1238cae2ed9aSIngo Molnar 					\
1239cae2ed9aSIngo Molnar 	IRQ_ENTER();			\
1240cae2ed9aSIngo Molnar 	L(B);				\
1241cae2ed9aSIngo Molnar 	U(B);				\
1242cae2ed9aSIngo Molnar 	IRQ_EXIT();
1243cae2ed9aSIngo Molnar 
1244cae2ed9aSIngo Molnar /*
124531e0d747SBoqun Feng  * Generate 24 testcases:
1246cae2ed9aSIngo Molnar  */
1247cae2ed9aSIngo Molnar #include "locking-selftest-hardirq.h"
124831e0d747SBoqun Feng #include "locking-selftest-rlock.h"
124931e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard_rlock)
125031e0d747SBoqun Feng 
125131e0d747SBoqun Feng #include "locking-selftest-wlock.h"
125231e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard_wlock)
1253cae2ed9aSIngo Molnar 
1254cae2ed9aSIngo Molnar #include "locking-selftest-softirq.h"
125531e0d747SBoqun Feng #include "locking-selftest-rlock.h"
125631e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft_rlock)
125731e0d747SBoqun Feng 
125831e0d747SBoqun Feng #include "locking-selftest-wlock.h"
125931e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft_wlock)
1260cae2ed9aSIngo Molnar 
126196a16f45SBoqun Feng #undef E1
126296a16f45SBoqun Feng #undef E2
126396a16f45SBoqun Feng #undef E3
126496a16f45SBoqun Feng /*
126596a16f45SBoqun Feng  * read-lock / write-lock recursion that is unsafe.
126696a16f45SBoqun Feng  *
126796a16f45SBoqun Feng  * A is a ENABLED_*_READ lock
126896a16f45SBoqun Feng  * B is a USED_IN_*_READ lock
126996a16f45SBoqun Feng  *
127096a16f45SBoqun Feng  * read_lock(A);
127196a16f45SBoqun Feng  *			write_lock(B);
127296a16f45SBoqun Feng  * <interrupt>
127396a16f45SBoqun Feng  * read_lock(B);
127496a16f45SBoqun Feng  * 			write_lock(A); // if this one is read_lock(), no deadlock
127596a16f45SBoqun Feng  */
127696a16f45SBoqun Feng 
127796a16f45SBoqun Feng #define E1()				\
127896a16f45SBoqun Feng 					\
127996a16f45SBoqun Feng 	IRQ_DISABLE();			\
128096a16f45SBoqun Feng 	WL(B);				\
128196a16f45SBoqun Feng 	LOCK(A);			\
128296a16f45SBoqun Feng 	UNLOCK(A);			\
128396a16f45SBoqun Feng 	WU(B);				\
128496a16f45SBoqun Feng 	IRQ_ENABLE();
128596a16f45SBoqun Feng 
128696a16f45SBoqun Feng #define E2()				\
128796a16f45SBoqun Feng 					\
128896a16f45SBoqun Feng 	RL(A);				\
128996a16f45SBoqun Feng 	RU(A);				\
129096a16f45SBoqun Feng 
129196a16f45SBoqun Feng #define E3()				\
129296a16f45SBoqun Feng 					\
129396a16f45SBoqun Feng 	IRQ_ENTER();			\
129496a16f45SBoqun Feng 	RL(B);				\
129596a16f45SBoqun Feng 	RU(B);				\
129696a16f45SBoqun Feng 	IRQ_EXIT();
129796a16f45SBoqun Feng 
129896a16f45SBoqun Feng /*
129996a16f45SBoqun Feng  * Generate 24 testcases:
130096a16f45SBoqun Feng  */
130196a16f45SBoqun Feng #include "locking-selftest-hardirq.h"
130296a16f45SBoqun Feng #include "locking-selftest-rlock.h"
130396a16f45SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_hard_rlock)
130496a16f45SBoqun Feng 
130596a16f45SBoqun Feng #include "locking-selftest-wlock.h"
130696a16f45SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_hard_wlock)
130796a16f45SBoqun Feng 
130896a16f45SBoqun Feng #include "locking-selftest-softirq.h"
130996a16f45SBoqun Feng #include "locking-selftest-rlock.h"
131096a16f45SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_soft_rlock)
131196a16f45SBoqun Feng 
131296a16f45SBoqun Feng #include "locking-selftest-wlock.h"
131396a16f45SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_soft_wlock)
131496a16f45SBoqun Feng 
1315cae2ed9aSIngo Molnar #ifdef CONFIG_DEBUG_LOCK_ALLOC
1316cae2ed9aSIngo Molnar # define I_SPINLOCK(x)	lockdep_reset_lock(&lock_##x.dep_map)
13179271a40dSBoqun Feng # define I_RAW_SPINLOCK(x)	lockdep_reset_lock(&raw_lock_##x.dep_map)
1318cae2ed9aSIngo Molnar # define I_RWLOCK(x)	lockdep_reset_lock(&rwlock_##x.dep_map)
1319cae2ed9aSIngo Molnar # define I_MUTEX(x)	lockdep_reset_lock(&mutex_##x.dep_map)
1320cae2ed9aSIngo Molnar # define I_RWSEM(x)	lockdep_reset_lock(&rwsem_##x.dep_map)
13211de99445SMaarten Lankhorst # define I_WW(x)	lockdep_reset_lock(&x.dep_map)
13227e923e6aSPeter Zijlstra # define I_LOCAL_LOCK(x) lockdep_reset_lock(&local_##x.dep_map)
1323018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
1324018956d6SPeter Zijlstra # define I_RTMUTEX(x)	lockdep_reset_lock(&rtmutex_##x.dep_map)
1325018956d6SPeter Zijlstra #endif
1326cae2ed9aSIngo Molnar #else
1327cae2ed9aSIngo Molnar # define I_SPINLOCK(x)
13289271a40dSBoqun Feng # define I_RAW_SPINLOCK(x)
1329cae2ed9aSIngo Molnar # define I_RWLOCK(x)
1330cae2ed9aSIngo Molnar # define I_MUTEX(x)
1331cae2ed9aSIngo Molnar # define I_RWSEM(x)
13321de99445SMaarten Lankhorst # define I_WW(x)
13337e923e6aSPeter Zijlstra # define I_LOCAL_LOCK(x)
1334cae2ed9aSIngo Molnar #endif
1335cae2ed9aSIngo Molnar 
1336018956d6SPeter Zijlstra #ifndef I_RTMUTEX
1337018956d6SPeter Zijlstra # define I_RTMUTEX(x)
1338018956d6SPeter Zijlstra #endif
1339018956d6SPeter Zijlstra 
1340018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
1341018956d6SPeter Zijlstra #define I2_RTMUTEX(x)	rt_mutex_init(&rtmutex_##x)
1342018956d6SPeter Zijlstra #else
1343018956d6SPeter Zijlstra #define I2_RTMUTEX(x)
1344018956d6SPeter Zijlstra #endif
1345018956d6SPeter Zijlstra 
1346cae2ed9aSIngo Molnar #define I1(x)					\
1347cae2ed9aSIngo Molnar 	do {					\
1348cae2ed9aSIngo Molnar 		I_SPINLOCK(x);			\
1349cae2ed9aSIngo Molnar 		I_RWLOCK(x);			\
1350cae2ed9aSIngo Molnar 		I_MUTEX(x);			\
1351cae2ed9aSIngo Molnar 		I_RWSEM(x);			\
1352018956d6SPeter Zijlstra 		I_RTMUTEX(x);			\
1353cae2ed9aSIngo Molnar 	} while (0)
1354cae2ed9aSIngo Molnar 
1355cae2ed9aSIngo Molnar #define I2(x)					\
1356cae2ed9aSIngo Molnar 	do {					\
1357a2e9ae58SPeter Zijlstra 		spin_lock_init(&lock_##x);	\
1358cae2ed9aSIngo Molnar 		rwlock_init(&rwlock_##x);	\
1359cae2ed9aSIngo Molnar 		mutex_init(&mutex_##x);		\
1360cae2ed9aSIngo Molnar 		init_rwsem(&rwsem_##x);		\
1361018956d6SPeter Zijlstra 		I2_RTMUTEX(x);			\
1362cae2ed9aSIngo Molnar 	} while (0)
1363cae2ed9aSIngo Molnar 
1364cae2ed9aSIngo Molnar static void reset_locks(void)
1365cae2ed9aSIngo Molnar {
1366cae2ed9aSIngo Molnar 	local_irq_disable();
13671de99445SMaarten Lankhorst 	lockdep_free_key_range(&ww_lockdep.acquire_key, 1);
13681de99445SMaarten Lankhorst 	lockdep_free_key_range(&ww_lockdep.mutex_key, 1);
13691de99445SMaarten Lankhorst 
1370cae2ed9aSIngo Molnar 	I1(A); I1(B); I1(C); I1(D);
1371cae2ed9aSIngo Molnar 	I1(X1); I1(X2); I1(Y1); I1(Y2); I1(Z1); I1(Z2);
1372f3cf139eSMaarten Lankhorst 	I_WW(t); I_WW(t2); I_WW(o.base); I_WW(o2.base); I_WW(o3.base);
13739271a40dSBoqun Feng 	I_RAW_SPINLOCK(A); I_RAW_SPINLOCK(B);
13747e923e6aSPeter Zijlstra 	I_LOCAL_LOCK(A);
13757e923e6aSPeter Zijlstra 
1376cae2ed9aSIngo Molnar 	lockdep_reset();
13777e923e6aSPeter Zijlstra 
1378cae2ed9aSIngo Molnar 	I2(A); I2(B); I2(C); I2(D);
1379cae2ed9aSIngo Molnar 	init_shared_classes();
13809271a40dSBoqun Feng 	raw_spin_lock_init(&raw_lock_A);
13819271a40dSBoqun Feng 	raw_spin_lock_init(&raw_lock_B);
13827e923e6aSPeter Zijlstra 	local_lock_init(&local_A);
13831de99445SMaarten Lankhorst 
1384f3cf139eSMaarten Lankhorst 	ww_mutex_init(&o, &ww_lockdep); ww_mutex_init(&o2, &ww_lockdep); ww_mutex_init(&o3, &ww_lockdep);
13851de99445SMaarten Lankhorst 	memset(&t, 0, sizeof(t)); memset(&t2, 0, sizeof(t2));
13861de99445SMaarten Lankhorst 	memset(&ww_lockdep.acquire_key, 0, sizeof(ww_lockdep.acquire_key));
13871de99445SMaarten Lankhorst 	memset(&ww_lockdep.mutex_key, 0, sizeof(ww_lockdep.mutex_key));
1388cae2ed9aSIngo Molnar 	local_irq_enable();
1389cae2ed9aSIngo Molnar }
1390cae2ed9aSIngo Molnar 
1391cae2ed9aSIngo Molnar #undef I
1392cae2ed9aSIngo Molnar 
1393cae2ed9aSIngo Molnar static int testcase_total;
1394cae2ed9aSIngo Molnar static int testcase_successes;
1395cae2ed9aSIngo Molnar static int expected_testcase_failures;
1396cae2ed9aSIngo Molnar static int unexpected_testcase_failures;
1397cae2ed9aSIngo Molnar 
1398cae2ed9aSIngo Molnar static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask)
1399cae2ed9aSIngo Molnar {
1400cae2ed9aSIngo Molnar 	unsigned long saved_preempt_count = preempt_count();
1401cae2ed9aSIngo Molnar 
1402cae2ed9aSIngo Molnar 	WARN_ON(irqs_disabled());
1403cae2ed9aSIngo Molnar 
14045831c0f7SPeter Zijlstra 	debug_locks_silent = !(debug_locks_verbose & lockclass_mask);
14055831c0f7SPeter Zijlstra 
1406cae2ed9aSIngo Molnar 	testcase_fn();
1407cae2ed9aSIngo Molnar 	/*
1408cae2ed9aSIngo Molnar 	 * Filter out expected failures:
1409cae2ed9aSIngo Molnar 	 */
14101de99445SMaarten Lankhorst #ifndef CONFIG_PROVE_LOCKING
1411166989e3SMaarten Lankhorst 	if (expected == FAILURE && debug_locks) {
1412cae2ed9aSIngo Molnar 		expected_testcase_failures++;
141325139409SMichael Ellerman 		pr_cont("failed|");
1414166989e3SMaarten Lankhorst 	}
1415166989e3SMaarten Lankhorst 	else
1416166989e3SMaarten Lankhorst #endif
1417166989e3SMaarten Lankhorst 	if (debug_locks != expected) {
1418cae2ed9aSIngo Molnar 		unexpected_testcase_failures++;
141925139409SMichael Ellerman 		pr_cont("FAILED|");
1420cae2ed9aSIngo Molnar 	} else {
1421cae2ed9aSIngo Molnar 		testcase_successes++;
142225139409SMichael Ellerman 		pr_cont("  ok  |");
1423cae2ed9aSIngo Molnar 	}
1424cae2ed9aSIngo Molnar 	testcase_total++;
1425cae2ed9aSIngo Molnar 
14265831c0f7SPeter Zijlstra 	if (debug_locks_verbose & lockclass_mask)
142725139409SMichael Ellerman 		pr_cont(" lockclass mask: %x, debug_locks: %d, expected: %d\n",
1428cae2ed9aSIngo Molnar 			lockclass_mask, debug_locks, expected);
1429cae2ed9aSIngo Molnar 	/*
1430cae2ed9aSIngo Molnar 	 * Some tests (e.g. double-unlock) might corrupt the preemption
1431cae2ed9aSIngo Molnar 	 * count, so restore it:
1432cae2ed9aSIngo Molnar 	 */
14334a2b4b22SPeter Zijlstra 	preempt_count_set(saved_preempt_count);
1434cae2ed9aSIngo Molnar #ifdef CONFIG_TRACE_IRQFLAGS
1435cae2ed9aSIngo Molnar 	if (softirq_count())
1436cae2ed9aSIngo Molnar 		current->softirqs_enabled = 0;
1437cae2ed9aSIngo Molnar 	else
1438cae2ed9aSIngo Molnar 		current->softirqs_enabled = 1;
1439cae2ed9aSIngo Molnar #endif
1440cae2ed9aSIngo Molnar 
1441cae2ed9aSIngo Molnar 	reset_locks();
1442cae2ed9aSIngo Molnar }
1443cae2ed9aSIngo Molnar 
1444018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
1445018956d6SPeter Zijlstra #define dotest_rt(fn, e, m)	dotest((fn), (e), (m))
1446018956d6SPeter Zijlstra #else
1447018956d6SPeter Zijlstra #define dotest_rt(fn, e, m)
1448018956d6SPeter Zijlstra #endif
1449018956d6SPeter Zijlstra 
1450cae2ed9aSIngo Molnar static inline void print_testname(const char *testname)
1451cae2ed9aSIngo Molnar {
1452cae2ed9aSIngo Molnar 	printk("%33s:", testname);
1453cae2ed9aSIngo Molnar }
1454cae2ed9aSIngo Molnar 
1455cae2ed9aSIngo Molnar #define DO_TESTCASE_1(desc, name, nr)				\
1456cae2ed9aSIngo Molnar 	print_testname(desc"/"#nr);				\
1457cae2ed9aSIngo Molnar 	dotest(name##_##nr, SUCCESS, LOCKTYPE_RWLOCK);		\
145825139409SMichael Ellerman 	pr_cont("\n");
1459cae2ed9aSIngo Molnar 
1460cae2ed9aSIngo Molnar #define DO_TESTCASE_1B(desc, name, nr)				\
1461cae2ed9aSIngo Molnar 	print_testname(desc"/"#nr);				\
1462cae2ed9aSIngo Molnar 	dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK);		\
146325139409SMichael Ellerman 	pr_cont("\n");
1464cae2ed9aSIngo Molnar 
14658ef7ca75SBoqun Feng #define DO_TESTCASE_1RR(desc, name, nr)				\
14668ef7ca75SBoqun Feng 	print_testname(desc"/"#nr);				\
14678ef7ca75SBoqun Feng 	pr_cont("             |");				\
14688ef7ca75SBoqun Feng 	dotest(name##_##nr, SUCCESS, LOCKTYPE_RWLOCK);		\
14698ef7ca75SBoqun Feng 	pr_cont("\n");
14708ef7ca75SBoqun Feng 
14718ef7ca75SBoqun Feng #define DO_TESTCASE_1RRB(desc, name, nr)			\
14728ef7ca75SBoqun Feng 	print_testname(desc"/"#nr);				\
14738ef7ca75SBoqun Feng 	pr_cont("             |");				\
14748ef7ca75SBoqun Feng 	dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK);		\
14758ef7ca75SBoqun Feng 	pr_cont("\n");
14768ef7ca75SBoqun Feng 
14778ef7ca75SBoqun Feng 
1478cae2ed9aSIngo Molnar #define DO_TESTCASE_3(desc, name, nr)				\
1479cae2ed9aSIngo Molnar 	print_testname(desc"/"#nr);				\
1480cae2ed9aSIngo Molnar 	dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN);	\
1481cae2ed9aSIngo Molnar 	dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK);	\
1482cae2ed9aSIngo Molnar 	dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK);	\
148325139409SMichael Ellerman 	pr_cont("\n");
1484cae2ed9aSIngo Molnar 
1485cae2ed9aSIngo Molnar #define DO_TESTCASE_3RW(desc, name, nr)				\
1486cae2ed9aSIngo Molnar 	print_testname(desc"/"#nr);				\
1487cae2ed9aSIngo Molnar 	dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN|LOCKTYPE_RWLOCK);\
1488cae2ed9aSIngo Molnar 	dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK);	\
1489cae2ed9aSIngo Molnar 	dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK);	\
149025139409SMichael Ellerman 	pr_cont("\n");
1491cae2ed9aSIngo Molnar 
149231e0d747SBoqun Feng #define DO_TESTCASE_2RW(desc, name, nr)				\
149331e0d747SBoqun Feng 	print_testname(desc"/"#nr);				\
149431e0d747SBoqun Feng 	pr_cont("      |");					\
149531e0d747SBoqun Feng 	dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK);	\
149631e0d747SBoqun Feng 	dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK);	\
149731e0d747SBoqun Feng 	pr_cont("\n");
149831e0d747SBoqun Feng 
149931e0d747SBoqun Feng #define DO_TESTCASE_2x2RW(desc, name, nr)			\
150031e0d747SBoqun Feng 	DO_TESTCASE_2RW("hard-"desc, name##_hard, nr)		\
150131e0d747SBoqun Feng 	DO_TESTCASE_2RW("soft-"desc, name##_soft, nr)		\
150231e0d747SBoqun Feng 
150331e0d747SBoqun Feng #define DO_TESTCASE_6x2x2RW(desc, name)				\
150431e0d747SBoqun Feng 	DO_TESTCASE_2x2RW(desc, name, 123);			\
150531e0d747SBoqun Feng 	DO_TESTCASE_2x2RW(desc, name, 132);			\
150631e0d747SBoqun Feng 	DO_TESTCASE_2x2RW(desc, name, 213);			\
150731e0d747SBoqun Feng 	DO_TESTCASE_2x2RW(desc, name, 231);			\
150831e0d747SBoqun Feng 	DO_TESTCASE_2x2RW(desc, name, 312);			\
150931e0d747SBoqun Feng 	DO_TESTCASE_2x2RW(desc, name, 321);
151031e0d747SBoqun Feng 
1511cae2ed9aSIngo Molnar #define DO_TESTCASE_6(desc, name)				\
1512cae2ed9aSIngo Molnar 	print_testname(desc);					\
1513cae2ed9aSIngo Molnar 	dotest(name##_spin, FAILURE, LOCKTYPE_SPIN);		\
1514cae2ed9aSIngo Molnar 	dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK);		\
1515cae2ed9aSIngo Molnar 	dotest(name##_rlock, FAILURE, LOCKTYPE_RWLOCK);		\
1516cae2ed9aSIngo Molnar 	dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX);		\
1517cae2ed9aSIngo Molnar 	dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM);		\
1518cae2ed9aSIngo Molnar 	dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM);		\
1519018956d6SPeter Zijlstra 	dotest_rt(name##_rtmutex, FAILURE, LOCKTYPE_RTMUTEX);	\
152025139409SMichael Ellerman 	pr_cont("\n");
1521cae2ed9aSIngo Molnar 
1522cae2ed9aSIngo Molnar #define DO_TESTCASE_6_SUCCESS(desc, name)			\
1523cae2ed9aSIngo Molnar 	print_testname(desc);					\
1524cae2ed9aSIngo Molnar 	dotest(name##_spin, SUCCESS, LOCKTYPE_SPIN);		\
1525cae2ed9aSIngo Molnar 	dotest(name##_wlock, SUCCESS, LOCKTYPE_RWLOCK);		\
1526cae2ed9aSIngo Molnar 	dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK);		\
1527cae2ed9aSIngo Molnar 	dotest(name##_mutex, SUCCESS, LOCKTYPE_MUTEX);		\
1528cae2ed9aSIngo Molnar 	dotest(name##_wsem, SUCCESS, LOCKTYPE_RWSEM);		\
1529cae2ed9aSIngo Molnar 	dotest(name##_rsem, SUCCESS, LOCKTYPE_RWSEM);		\
1530018956d6SPeter Zijlstra 	dotest_rt(name##_rtmutex, SUCCESS, LOCKTYPE_RTMUTEX);	\
153125139409SMichael Ellerman 	pr_cont("\n");
1532cae2ed9aSIngo Molnar 
1533cae2ed9aSIngo Molnar /*
1534cae2ed9aSIngo Molnar  * 'read' variant: rlocks must not trigger.
1535cae2ed9aSIngo Molnar  */
1536cae2ed9aSIngo Molnar #define DO_TESTCASE_6R(desc, name)				\
1537cae2ed9aSIngo Molnar 	print_testname(desc);					\
1538cae2ed9aSIngo Molnar 	dotest(name##_spin, FAILURE, LOCKTYPE_SPIN);		\
1539cae2ed9aSIngo Molnar 	dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK);		\
1540cae2ed9aSIngo Molnar 	dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK);		\
1541cae2ed9aSIngo Molnar 	dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX);		\
1542cae2ed9aSIngo Molnar 	dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM);		\
1543cae2ed9aSIngo Molnar 	dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM);		\
1544018956d6SPeter Zijlstra 	dotest_rt(name##_rtmutex, FAILURE, LOCKTYPE_RTMUTEX);	\
154525139409SMichael Ellerman 	pr_cont("\n");
1546cae2ed9aSIngo Molnar 
1547cae2ed9aSIngo Molnar #define DO_TESTCASE_2I(desc, name, nr)				\
1548cae2ed9aSIngo Molnar 	DO_TESTCASE_1("hard-"desc, name##_hard, nr);		\
1549cae2ed9aSIngo Molnar 	DO_TESTCASE_1("soft-"desc, name##_soft, nr);
1550cae2ed9aSIngo Molnar 
1551cae2ed9aSIngo Molnar #define DO_TESTCASE_2IB(desc, name, nr)				\
1552cae2ed9aSIngo Molnar 	DO_TESTCASE_1B("hard-"desc, name##_hard, nr);		\
1553cae2ed9aSIngo Molnar 	DO_TESTCASE_1B("soft-"desc, name##_soft, nr);
1554cae2ed9aSIngo Molnar 
1555cae2ed9aSIngo Molnar #define DO_TESTCASE_6I(desc, name, nr)				\
1556cae2ed9aSIngo Molnar 	DO_TESTCASE_3("hard-"desc, name##_hard, nr);		\
1557cae2ed9aSIngo Molnar 	DO_TESTCASE_3("soft-"desc, name##_soft, nr);
1558cae2ed9aSIngo Molnar 
1559cae2ed9aSIngo Molnar #define DO_TESTCASE_6IRW(desc, name, nr)			\
1560cae2ed9aSIngo Molnar 	DO_TESTCASE_3RW("hard-"desc, name##_hard, nr);		\
1561cae2ed9aSIngo Molnar 	DO_TESTCASE_3RW("soft-"desc, name##_soft, nr);
1562cae2ed9aSIngo Molnar 
1563cae2ed9aSIngo Molnar #define DO_TESTCASE_2x3(desc, name)				\
1564cae2ed9aSIngo Molnar 	DO_TESTCASE_3(desc, name, 12);				\
1565cae2ed9aSIngo Molnar 	DO_TESTCASE_3(desc, name, 21);
1566cae2ed9aSIngo Molnar 
1567cae2ed9aSIngo Molnar #define DO_TESTCASE_2x6(desc, name)				\
1568cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 12);				\
1569cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 21);
1570cae2ed9aSIngo Molnar 
1571cae2ed9aSIngo Molnar #define DO_TESTCASE_6x2(desc, name)				\
1572cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 123);			\
1573cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 132);			\
1574cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 213);			\
1575cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 231);			\
1576cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 312);			\
1577cae2ed9aSIngo Molnar 	DO_TESTCASE_2I(desc, name, 321);
1578cae2ed9aSIngo Molnar 
1579cae2ed9aSIngo Molnar #define DO_TESTCASE_6x2B(desc, name)				\
1580cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 123);			\
1581cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 132);			\
1582cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 213);			\
1583cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 231);			\
1584cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 312);			\
1585cae2ed9aSIngo Molnar 	DO_TESTCASE_2IB(desc, name, 321);
1586cae2ed9aSIngo Molnar 
15878ef7ca75SBoqun Feng #define DO_TESTCASE_6x1RR(desc, name)				\
15888ef7ca75SBoqun Feng 	DO_TESTCASE_1RR(desc, name, 123);			\
15898ef7ca75SBoqun Feng 	DO_TESTCASE_1RR(desc, name, 132);			\
15908ef7ca75SBoqun Feng 	DO_TESTCASE_1RR(desc, name, 213);			\
15918ef7ca75SBoqun Feng 	DO_TESTCASE_1RR(desc, name, 231);			\
15928ef7ca75SBoqun Feng 	DO_TESTCASE_1RR(desc, name, 312);			\
15938ef7ca75SBoqun Feng 	DO_TESTCASE_1RR(desc, name, 321);
15948ef7ca75SBoqun Feng 
15958ef7ca75SBoqun Feng #define DO_TESTCASE_6x1RRB(desc, name)				\
15968ef7ca75SBoqun Feng 	DO_TESTCASE_1RRB(desc, name, 123);			\
15978ef7ca75SBoqun Feng 	DO_TESTCASE_1RRB(desc, name, 132);			\
15988ef7ca75SBoqun Feng 	DO_TESTCASE_1RRB(desc, name, 213);			\
15998ef7ca75SBoqun Feng 	DO_TESTCASE_1RRB(desc, name, 231);			\
16008ef7ca75SBoqun Feng 	DO_TESTCASE_1RRB(desc, name, 312);			\
16018ef7ca75SBoqun Feng 	DO_TESTCASE_1RRB(desc, name, 321);
16028ef7ca75SBoqun Feng 
1603cae2ed9aSIngo Molnar #define DO_TESTCASE_6x6(desc, name)				\
1604cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 123);			\
1605cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 132);			\
1606cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 213);			\
1607cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 231);			\
1608cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 312);			\
1609cae2ed9aSIngo Molnar 	DO_TESTCASE_6I(desc, name, 321);
1610cae2ed9aSIngo Molnar 
1611cae2ed9aSIngo Molnar #define DO_TESTCASE_6x6RW(desc, name)				\
1612cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 123);			\
1613cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 132);			\
1614cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 213);			\
1615cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 231);			\
1616cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 312);			\
1617cae2ed9aSIngo Molnar 	DO_TESTCASE_6IRW(desc, name, 321);
1618cae2ed9aSIngo Molnar 
16191de99445SMaarten Lankhorst static void ww_test_fail_acquire(void)
16201de99445SMaarten Lankhorst {
16211de99445SMaarten Lankhorst 	int ret;
16221de99445SMaarten Lankhorst 
16231de99445SMaarten Lankhorst 	WWAI(&t);
16241de99445SMaarten Lankhorst 	t.stamp++;
16251de99445SMaarten Lankhorst 
16261de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
16271de99445SMaarten Lankhorst 
16281de99445SMaarten Lankhorst 	if (WARN_ON(!o.ctx) ||
16291de99445SMaarten Lankhorst 	    WARN_ON(ret))
16301de99445SMaarten Lankhorst 		return;
16311de99445SMaarten Lankhorst 
16321de99445SMaarten Lankhorst 	/* No lockdep test, pure API */
16331de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
16341de99445SMaarten Lankhorst 	WARN_ON(ret != -EALREADY);
16351de99445SMaarten Lankhorst 
16361de99445SMaarten Lankhorst 	ret = WWT(&o);
16371de99445SMaarten Lankhorst 	WARN_ON(ret);
16381de99445SMaarten Lankhorst 
16391de99445SMaarten Lankhorst 	t2 = t;
16401de99445SMaarten Lankhorst 	t2.stamp++;
16411de99445SMaarten Lankhorst 	ret = WWL(&o, &t2);
16421de99445SMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
16431de99445SMaarten Lankhorst 	WWU(&o);
16441de99445SMaarten Lankhorst 
16451de99445SMaarten Lankhorst 	if (WWT(&o))
16461de99445SMaarten Lankhorst 		WWU(&o);
16471de99445SMaarten Lankhorst #ifdef CONFIG_DEBUG_LOCK_ALLOC
16481de99445SMaarten Lankhorst 	else
16491de99445SMaarten Lankhorst 		DEBUG_LOCKS_WARN_ON(1);
16501de99445SMaarten Lankhorst #endif
16511de99445SMaarten Lankhorst }
16521de99445SMaarten Lankhorst 
16532fe3d4b1SMaarten Lankhorst static void ww_test_normal(void)
16542fe3d4b1SMaarten Lankhorst {
16552fe3d4b1SMaarten Lankhorst 	int ret;
16562fe3d4b1SMaarten Lankhorst 
16572fe3d4b1SMaarten Lankhorst 	WWAI(&t);
16582fe3d4b1SMaarten Lankhorst 
16592fe3d4b1SMaarten Lankhorst 	/*
16602fe3d4b1SMaarten Lankhorst 	 * None of the ww_mutex codepaths should be taken in the 'normal'
16612fe3d4b1SMaarten Lankhorst 	 * mutex calls. The easiest way to verify this is by using the
16622fe3d4b1SMaarten Lankhorst 	 * normal mutex calls, and making sure o.ctx is unmodified.
16632fe3d4b1SMaarten Lankhorst 	 */
16642fe3d4b1SMaarten Lankhorst 
16652fe3d4b1SMaarten Lankhorst 	/* mutex_lock (and indirectly, mutex_lock_nested) */
16662fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
16672fe3d4b1SMaarten Lankhorst 	mutex_lock(&o.base);
16682fe3d4b1SMaarten Lankhorst 	mutex_unlock(&o.base);
16692fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
16702fe3d4b1SMaarten Lankhorst 
16712fe3d4b1SMaarten Lankhorst 	/* mutex_lock_interruptible (and *_nested) */
16722fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
16732fe3d4b1SMaarten Lankhorst 	ret = mutex_lock_interruptible(&o.base);
16742fe3d4b1SMaarten Lankhorst 	if (!ret)
16752fe3d4b1SMaarten Lankhorst 		mutex_unlock(&o.base);
16762fe3d4b1SMaarten Lankhorst 	else
16772fe3d4b1SMaarten Lankhorst 		WARN_ON(1);
16782fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
16792fe3d4b1SMaarten Lankhorst 
16802fe3d4b1SMaarten Lankhorst 	/* mutex_lock_killable (and *_nested) */
16812fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
16822fe3d4b1SMaarten Lankhorst 	ret = mutex_lock_killable(&o.base);
16832fe3d4b1SMaarten Lankhorst 	if (!ret)
16842fe3d4b1SMaarten Lankhorst 		mutex_unlock(&o.base);
16852fe3d4b1SMaarten Lankhorst 	else
16862fe3d4b1SMaarten Lankhorst 		WARN_ON(1);
16872fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
16882fe3d4b1SMaarten Lankhorst 
16892fe3d4b1SMaarten Lankhorst 	/* trylock, succeeding */
16902fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
16912fe3d4b1SMaarten Lankhorst 	ret = mutex_trylock(&o.base);
16922fe3d4b1SMaarten Lankhorst 	WARN_ON(!ret);
16932fe3d4b1SMaarten Lankhorst 	if (ret)
16942fe3d4b1SMaarten Lankhorst 		mutex_unlock(&o.base);
16952fe3d4b1SMaarten Lankhorst 	else
16962fe3d4b1SMaarten Lankhorst 		WARN_ON(1);
16972fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
16982fe3d4b1SMaarten Lankhorst 
16992fe3d4b1SMaarten Lankhorst 	/* trylock, failing */
17002fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
17012fe3d4b1SMaarten Lankhorst 	mutex_lock(&o.base);
17022fe3d4b1SMaarten Lankhorst 	ret = mutex_trylock(&o.base);
17032fe3d4b1SMaarten Lankhorst 	WARN_ON(ret);
17042fe3d4b1SMaarten Lankhorst 	mutex_unlock(&o.base);
17052fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
17062fe3d4b1SMaarten Lankhorst 
17072fe3d4b1SMaarten Lankhorst 	/* nest_lock */
17082fe3d4b1SMaarten Lankhorst 	o.ctx = (void *)~0UL;
17092fe3d4b1SMaarten Lankhorst 	mutex_lock_nest_lock(&o.base, &t);
17102fe3d4b1SMaarten Lankhorst 	mutex_unlock(&o.base);
17112fe3d4b1SMaarten Lankhorst 	WARN_ON(o.ctx != (void *)~0UL);
17122fe3d4b1SMaarten Lankhorst }
17132fe3d4b1SMaarten Lankhorst 
17141de99445SMaarten Lankhorst static void ww_test_two_contexts(void)
17151de99445SMaarten Lankhorst {
17161de99445SMaarten Lankhorst 	WWAI(&t);
17171de99445SMaarten Lankhorst 	WWAI(&t2);
17181de99445SMaarten Lankhorst }
17191de99445SMaarten Lankhorst 
17201de99445SMaarten Lankhorst static void ww_test_diff_class(void)
17211de99445SMaarten Lankhorst {
17221de99445SMaarten Lankhorst 	WWAI(&t);
17231de99445SMaarten Lankhorst #ifdef CONFIG_DEBUG_MUTEXES
17241de99445SMaarten Lankhorst 	t.ww_class = NULL;
17251de99445SMaarten Lankhorst #endif
17261de99445SMaarten Lankhorst 	WWL(&o, &t);
17271de99445SMaarten Lankhorst }
17281de99445SMaarten Lankhorst 
17291de99445SMaarten Lankhorst static void ww_test_context_done_twice(void)
17301de99445SMaarten Lankhorst {
17311de99445SMaarten Lankhorst 	WWAI(&t);
17321de99445SMaarten Lankhorst 	WWAD(&t);
17331de99445SMaarten Lankhorst 	WWAD(&t);
17341de99445SMaarten Lankhorst 	WWAF(&t);
17351de99445SMaarten Lankhorst }
17361de99445SMaarten Lankhorst 
17371de99445SMaarten Lankhorst static void ww_test_context_unlock_twice(void)
17381de99445SMaarten Lankhorst {
17391de99445SMaarten Lankhorst 	WWAI(&t);
17401de99445SMaarten Lankhorst 	WWAD(&t);
17411de99445SMaarten Lankhorst 	WWAF(&t);
17421de99445SMaarten Lankhorst 	WWAF(&t);
17431de99445SMaarten Lankhorst }
17441de99445SMaarten Lankhorst 
17451de99445SMaarten Lankhorst static void ww_test_context_fini_early(void)
17461de99445SMaarten Lankhorst {
17471de99445SMaarten Lankhorst 	WWAI(&t);
17481de99445SMaarten Lankhorst 	WWL(&o, &t);
17491de99445SMaarten Lankhorst 	WWAD(&t);
17501de99445SMaarten Lankhorst 	WWAF(&t);
17511de99445SMaarten Lankhorst }
17521de99445SMaarten Lankhorst 
17531de99445SMaarten Lankhorst static void ww_test_context_lock_after_done(void)
17541de99445SMaarten Lankhorst {
17551de99445SMaarten Lankhorst 	WWAI(&t);
17561de99445SMaarten Lankhorst 	WWAD(&t);
17571de99445SMaarten Lankhorst 	WWL(&o, &t);
17581de99445SMaarten Lankhorst }
17591de99445SMaarten Lankhorst 
17601de99445SMaarten Lankhorst static void ww_test_object_unlock_twice(void)
17611de99445SMaarten Lankhorst {
17621de99445SMaarten Lankhorst 	WWL1(&o);
17631de99445SMaarten Lankhorst 	WWU(&o);
17641de99445SMaarten Lankhorst 	WWU(&o);
17651de99445SMaarten Lankhorst }
17661de99445SMaarten Lankhorst 
17671de99445SMaarten Lankhorst static void ww_test_object_lock_unbalanced(void)
17681de99445SMaarten Lankhorst {
17691de99445SMaarten Lankhorst 	WWAI(&t);
17701de99445SMaarten Lankhorst 	WWL(&o, &t);
17711de99445SMaarten Lankhorst 	t.acquired = 0;
17721de99445SMaarten Lankhorst 	WWU(&o);
17731de99445SMaarten Lankhorst 	WWAF(&t);
17741de99445SMaarten Lankhorst }
17751de99445SMaarten Lankhorst 
17761de99445SMaarten Lankhorst static void ww_test_object_lock_stale_context(void)
17771de99445SMaarten Lankhorst {
17781de99445SMaarten Lankhorst 	WWAI(&t);
17791de99445SMaarten Lankhorst 	o.ctx = &t2;
17801de99445SMaarten Lankhorst 	WWL(&o, &t);
17811de99445SMaarten Lankhorst }
17821de99445SMaarten Lankhorst 
1783f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_normal(void)
1784f3cf139eSMaarten Lankhorst {
1785f3cf139eSMaarten Lankhorst 	int ret;
1786f3cf139eSMaarten Lankhorst 
1787f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
1788f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
17895facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1790f3cf139eSMaarten Lankhorst 
1791f3cf139eSMaarten Lankhorst 	WWAI(&t);
1792f3cf139eSMaarten Lankhorst 	t2 = t;
1793f3cf139eSMaarten Lankhorst 	t2.stamp--;
1794f3cf139eSMaarten Lankhorst 
1795f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1796f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1797f3cf139eSMaarten Lankhorst 
1798f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1799f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1800f3cf139eSMaarten Lankhorst 
1801f3cf139eSMaarten Lankhorst 	o2.ctx = NULL;
1802f3cf139eSMaarten Lankhorst 	mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
1803f3cf139eSMaarten Lankhorst 	mutex_unlock(&o2.base);
1804f3cf139eSMaarten Lankhorst 	WWU(&o);
1805f3cf139eSMaarten Lankhorst 
1806f3cf139eSMaarten Lankhorst 	WWL(&o2, &t);
1807f3cf139eSMaarten Lankhorst }
1808f3cf139eSMaarten Lankhorst 
1809f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_normal_slow(void)
1810f3cf139eSMaarten Lankhorst {
1811f3cf139eSMaarten Lankhorst 	int ret;
1812f3cf139eSMaarten Lankhorst 
1813f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
18145facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1815f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1816f3cf139eSMaarten Lankhorst 
1817f3cf139eSMaarten Lankhorst 	WWAI(&t);
1818f3cf139eSMaarten Lankhorst 	t2 = t;
1819f3cf139eSMaarten Lankhorst 	t2.stamp--;
1820f3cf139eSMaarten Lankhorst 
1821f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1822f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1823f3cf139eSMaarten Lankhorst 
1824f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1825f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1826f3cf139eSMaarten Lankhorst 
1827f3cf139eSMaarten Lankhorst 	o2.ctx = NULL;
1828f3cf139eSMaarten Lankhorst 	mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
1829f3cf139eSMaarten Lankhorst 	mutex_unlock(&o2.base);
1830f3cf139eSMaarten Lankhorst 	WWU(&o);
1831f3cf139eSMaarten Lankhorst 
1832f3cf139eSMaarten Lankhorst 	ww_mutex_lock_slow(&o2, &t);
1833f3cf139eSMaarten Lankhorst }
1834f3cf139eSMaarten Lankhorst 
1835f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_no_unlock(void)
1836f3cf139eSMaarten Lankhorst {
1837f3cf139eSMaarten Lankhorst 	int ret;
1838f3cf139eSMaarten Lankhorst 
1839f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
1840f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
18415facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1842f3cf139eSMaarten Lankhorst 
1843f3cf139eSMaarten Lankhorst 	WWAI(&t);
1844f3cf139eSMaarten Lankhorst 	t2 = t;
1845f3cf139eSMaarten Lankhorst 	t2.stamp--;
1846f3cf139eSMaarten Lankhorst 
1847f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1848f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1849f3cf139eSMaarten Lankhorst 
1850f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1851f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1852f3cf139eSMaarten Lankhorst 
1853f3cf139eSMaarten Lankhorst 	o2.ctx = NULL;
1854f3cf139eSMaarten Lankhorst 	mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
1855f3cf139eSMaarten Lankhorst 	mutex_unlock(&o2.base);
1856f3cf139eSMaarten Lankhorst 
1857f3cf139eSMaarten Lankhorst 	WWL(&o2, &t);
1858f3cf139eSMaarten Lankhorst }
1859f3cf139eSMaarten Lankhorst 
1860f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_no_unlock_slow(void)
1861f3cf139eSMaarten Lankhorst {
1862f3cf139eSMaarten Lankhorst 	int ret;
1863f3cf139eSMaarten Lankhorst 
1864f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
18655facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1866f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1867f3cf139eSMaarten Lankhorst 
1868f3cf139eSMaarten Lankhorst 	WWAI(&t);
1869f3cf139eSMaarten Lankhorst 	t2 = t;
1870f3cf139eSMaarten Lankhorst 	t2.stamp--;
1871f3cf139eSMaarten Lankhorst 
1872f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1873f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1874f3cf139eSMaarten Lankhorst 
1875f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1876f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1877f3cf139eSMaarten Lankhorst 
1878f3cf139eSMaarten Lankhorst 	o2.ctx = NULL;
1879f3cf139eSMaarten Lankhorst 	mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
1880f3cf139eSMaarten Lankhorst 	mutex_unlock(&o2.base);
1881f3cf139eSMaarten Lankhorst 
1882f3cf139eSMaarten Lankhorst 	ww_mutex_lock_slow(&o2, &t);
1883f3cf139eSMaarten Lankhorst }
1884f3cf139eSMaarten Lankhorst 
1885f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_more(void)
1886f3cf139eSMaarten Lankhorst {
1887f3cf139eSMaarten Lankhorst 	int ret;
1888f3cf139eSMaarten Lankhorst 
1889f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
18905facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1891f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1892f3cf139eSMaarten Lankhorst 
1893f3cf139eSMaarten Lankhorst 	WWAI(&t);
1894f3cf139eSMaarten Lankhorst 	t2 = t;
1895f3cf139eSMaarten Lankhorst 	t2.stamp--;
1896f3cf139eSMaarten Lankhorst 
1897f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1898f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1899f3cf139eSMaarten Lankhorst 
1900f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1901f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1902f3cf139eSMaarten Lankhorst 
1903f3cf139eSMaarten Lankhorst 	ret = WWL(&o3, &t);
1904f3cf139eSMaarten Lankhorst }
1905f3cf139eSMaarten Lankhorst 
1906f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_more_slow(void)
1907f3cf139eSMaarten Lankhorst {
1908f3cf139eSMaarten Lankhorst 	int ret;
1909f3cf139eSMaarten Lankhorst 
1910f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
19115facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1912f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1913f3cf139eSMaarten Lankhorst 
1914f3cf139eSMaarten Lankhorst 	WWAI(&t);
1915f3cf139eSMaarten Lankhorst 	t2 = t;
1916f3cf139eSMaarten Lankhorst 	t2.stamp--;
1917f3cf139eSMaarten Lankhorst 
1918f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1919f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1920f3cf139eSMaarten Lankhorst 
1921f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1922f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1923f3cf139eSMaarten Lankhorst 
1924f3cf139eSMaarten Lankhorst 	ww_mutex_lock_slow(&o3, &t);
1925f3cf139eSMaarten Lankhorst }
1926f3cf139eSMaarten Lankhorst 
1927f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_more_edeadlk(void)
1928f3cf139eSMaarten Lankhorst {
1929f3cf139eSMaarten Lankhorst 	int ret;
1930f3cf139eSMaarten Lankhorst 
1931f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
19325facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1933f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1934f3cf139eSMaarten Lankhorst 
1935f3cf139eSMaarten Lankhorst 	mutex_lock(&o3.base);
19365facae4fSQian Cai 	mutex_release(&o3.base.dep_map, _THIS_IP_);
1937f3cf139eSMaarten Lankhorst 	o3.ctx = &t2;
1938f3cf139eSMaarten Lankhorst 
1939f3cf139eSMaarten Lankhorst 	WWAI(&t);
1940f3cf139eSMaarten Lankhorst 	t2 = t;
1941f3cf139eSMaarten Lankhorst 	t2.stamp--;
1942f3cf139eSMaarten Lankhorst 
1943f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1944f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1945f3cf139eSMaarten Lankhorst 
1946f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1947f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1948f3cf139eSMaarten Lankhorst 
1949f3cf139eSMaarten Lankhorst 	ret = WWL(&o3, &t);
1950f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1951f3cf139eSMaarten Lankhorst }
1952f3cf139eSMaarten Lankhorst 
1953f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_more_edeadlk_slow(void)
1954f3cf139eSMaarten Lankhorst {
1955f3cf139eSMaarten Lankhorst 	int ret;
1956f3cf139eSMaarten Lankhorst 
1957f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
19585facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1959f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1960f3cf139eSMaarten Lankhorst 
1961f3cf139eSMaarten Lankhorst 	mutex_lock(&o3.base);
19625facae4fSQian Cai 	mutex_release(&o3.base.dep_map, _THIS_IP_);
1963f3cf139eSMaarten Lankhorst 	o3.ctx = &t2;
1964f3cf139eSMaarten Lankhorst 
1965f3cf139eSMaarten Lankhorst 	WWAI(&t);
1966f3cf139eSMaarten Lankhorst 	t2 = t;
1967f3cf139eSMaarten Lankhorst 	t2.stamp--;
1968f3cf139eSMaarten Lankhorst 
1969f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1970f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1971f3cf139eSMaarten Lankhorst 
1972f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1973f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1974f3cf139eSMaarten Lankhorst 
1975f3cf139eSMaarten Lankhorst 	ww_mutex_lock_slow(&o3, &t);
1976f3cf139eSMaarten Lankhorst }
1977f3cf139eSMaarten Lankhorst 
1978f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_wrong(void)
1979f3cf139eSMaarten Lankhorst {
1980f3cf139eSMaarten Lankhorst 	int ret;
1981f3cf139eSMaarten Lankhorst 
1982f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
19835facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
1984f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
1985f3cf139eSMaarten Lankhorst 
1986f3cf139eSMaarten Lankhorst 	WWAI(&t);
1987f3cf139eSMaarten Lankhorst 	t2 = t;
1988f3cf139eSMaarten Lankhorst 	t2.stamp--;
1989f3cf139eSMaarten Lankhorst 
1990f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
1991f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
1992f3cf139eSMaarten Lankhorst 
1993f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
1994f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
1995f3cf139eSMaarten Lankhorst 	if (!ret)
1996f3cf139eSMaarten Lankhorst 		WWU(&o2);
1997f3cf139eSMaarten Lankhorst 
1998f3cf139eSMaarten Lankhorst 	WWU(&o);
1999f3cf139eSMaarten Lankhorst 
2000f3cf139eSMaarten Lankhorst 	ret = WWL(&o3, &t);
2001f3cf139eSMaarten Lankhorst }
2002f3cf139eSMaarten Lankhorst 
2003f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_wrong_slow(void)
2004f3cf139eSMaarten Lankhorst {
2005f3cf139eSMaarten Lankhorst 	int ret;
2006f3cf139eSMaarten Lankhorst 
2007f3cf139eSMaarten Lankhorst 	mutex_lock(&o2.base);
20085facae4fSQian Cai 	mutex_release(&o2.base.dep_map, _THIS_IP_);
2009f3cf139eSMaarten Lankhorst 	o2.ctx = &t2;
2010f3cf139eSMaarten Lankhorst 
2011f3cf139eSMaarten Lankhorst 	WWAI(&t);
2012f3cf139eSMaarten Lankhorst 	t2 = t;
2013f3cf139eSMaarten Lankhorst 	t2.stamp--;
2014f3cf139eSMaarten Lankhorst 
2015f3cf139eSMaarten Lankhorst 	ret = WWL(&o, &t);
2016f3cf139eSMaarten Lankhorst 	WARN_ON(ret);
2017f3cf139eSMaarten Lankhorst 
2018f3cf139eSMaarten Lankhorst 	ret = WWL(&o2, &t);
2019f3cf139eSMaarten Lankhorst 	WARN_ON(ret != -EDEADLK);
2020f3cf139eSMaarten Lankhorst 	if (!ret)
2021f3cf139eSMaarten Lankhorst 		WWU(&o2);
2022f3cf139eSMaarten Lankhorst 
2023f3cf139eSMaarten Lankhorst 	WWU(&o);
2024f3cf139eSMaarten Lankhorst 
2025f3cf139eSMaarten Lankhorst 	ww_mutex_lock_slow(&o3, &t);
2026f3cf139eSMaarten Lankhorst }
2027f3cf139eSMaarten Lankhorst 
20281de99445SMaarten Lankhorst static void ww_test_spin_nest_unlocked(void)
20291de99445SMaarten Lankhorst {
2030a2e9ae58SPeter Zijlstra 	spin_lock_nest_lock(&lock_A, &o.base);
20311de99445SMaarten Lankhorst 	U(A);
20321de99445SMaarten Lankhorst }
20331de99445SMaarten Lankhorst 
2034e04ce676SBoqun Feng /* This is not a deadlock, because we have X1 to serialize Y1 and Y2 */
2035e04ce676SBoqun Feng static void ww_test_spin_nest_lock(void)
2036e04ce676SBoqun Feng {
2037e04ce676SBoqun Feng 	spin_lock(&lock_X1);
2038e04ce676SBoqun Feng 	spin_lock_nest_lock(&lock_Y1, &lock_X1);
2039e04ce676SBoqun Feng 	spin_lock(&lock_A);
2040e04ce676SBoqun Feng 	spin_lock_nest_lock(&lock_Y2, &lock_X1);
2041e04ce676SBoqun Feng 	spin_unlock(&lock_A);
2042e04ce676SBoqun Feng 	spin_unlock(&lock_Y2);
2043e04ce676SBoqun Feng 	spin_unlock(&lock_Y1);
2044e04ce676SBoqun Feng 	spin_unlock(&lock_X1);
2045e04ce676SBoqun Feng }
2046e04ce676SBoqun Feng 
20471de99445SMaarten Lankhorst static void ww_test_unneeded_slow(void)
20481de99445SMaarten Lankhorst {
20491de99445SMaarten Lankhorst 	WWAI(&t);
20501de99445SMaarten Lankhorst 
20511de99445SMaarten Lankhorst 	ww_mutex_lock_slow(&o, &t);
20521de99445SMaarten Lankhorst }
20531de99445SMaarten Lankhorst 
20541de99445SMaarten Lankhorst static void ww_test_context_block(void)
20551de99445SMaarten Lankhorst {
20561de99445SMaarten Lankhorst 	int ret;
20571de99445SMaarten Lankhorst 
20581de99445SMaarten Lankhorst 	WWAI(&t);
20591de99445SMaarten Lankhorst 
20601de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
20611de99445SMaarten Lankhorst 	WARN_ON(ret);
20621de99445SMaarten Lankhorst 	WWL1(&o2);
20631de99445SMaarten Lankhorst }
20641de99445SMaarten Lankhorst 
20651de99445SMaarten Lankhorst static void ww_test_context_try(void)
20661de99445SMaarten Lankhorst {
20671de99445SMaarten Lankhorst 	int ret;
20681de99445SMaarten Lankhorst 
20691de99445SMaarten Lankhorst 	WWAI(&t);
20701de99445SMaarten Lankhorst 
20711de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
20721de99445SMaarten Lankhorst 	WARN_ON(ret);
20731de99445SMaarten Lankhorst 
20741de99445SMaarten Lankhorst 	ret = WWT(&o2);
20751de99445SMaarten Lankhorst 	WARN_ON(!ret);
20761de99445SMaarten Lankhorst 	WWU(&o2);
20771de99445SMaarten Lankhorst 	WWU(&o);
20781de99445SMaarten Lankhorst }
20791de99445SMaarten Lankhorst 
20801de99445SMaarten Lankhorst static void ww_test_context_context(void)
20811de99445SMaarten Lankhorst {
20821de99445SMaarten Lankhorst 	int ret;
20831de99445SMaarten Lankhorst 
20841de99445SMaarten Lankhorst 	WWAI(&t);
20851de99445SMaarten Lankhorst 
20861de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
20871de99445SMaarten Lankhorst 	WARN_ON(ret);
20881de99445SMaarten Lankhorst 
20891de99445SMaarten Lankhorst 	ret = WWL(&o2, &t);
20901de99445SMaarten Lankhorst 	WARN_ON(ret);
20911de99445SMaarten Lankhorst 
20921de99445SMaarten Lankhorst 	WWU(&o2);
20931de99445SMaarten Lankhorst 	WWU(&o);
20941de99445SMaarten Lankhorst }
20951de99445SMaarten Lankhorst 
20961de99445SMaarten Lankhorst static void ww_test_try_block(void)
20971de99445SMaarten Lankhorst {
20981de99445SMaarten Lankhorst 	bool ret;
20991de99445SMaarten Lankhorst 
21001de99445SMaarten Lankhorst 	ret = WWT(&o);
21011de99445SMaarten Lankhorst 	WARN_ON(!ret);
21021de99445SMaarten Lankhorst 
21031de99445SMaarten Lankhorst 	WWL1(&o2);
21041de99445SMaarten Lankhorst 	WWU(&o2);
21051de99445SMaarten Lankhorst 	WWU(&o);
21061de99445SMaarten Lankhorst }
21071de99445SMaarten Lankhorst 
21081de99445SMaarten Lankhorst static void ww_test_try_try(void)
21091de99445SMaarten Lankhorst {
21101de99445SMaarten Lankhorst 	bool ret;
21111de99445SMaarten Lankhorst 
21121de99445SMaarten Lankhorst 	ret = WWT(&o);
21131de99445SMaarten Lankhorst 	WARN_ON(!ret);
21141de99445SMaarten Lankhorst 	ret = WWT(&o2);
21151de99445SMaarten Lankhorst 	WARN_ON(!ret);
21161de99445SMaarten Lankhorst 	WWU(&o2);
21171de99445SMaarten Lankhorst 	WWU(&o);
21181de99445SMaarten Lankhorst }
21191de99445SMaarten Lankhorst 
21201de99445SMaarten Lankhorst static void ww_test_try_context(void)
21211de99445SMaarten Lankhorst {
21221de99445SMaarten Lankhorst 	int ret;
21231de99445SMaarten Lankhorst 
21241de99445SMaarten Lankhorst 	ret = WWT(&o);
21251de99445SMaarten Lankhorst 	WARN_ON(!ret);
21261de99445SMaarten Lankhorst 
21271de99445SMaarten Lankhorst 	WWAI(&t);
21281de99445SMaarten Lankhorst 
21291de99445SMaarten Lankhorst 	ret = WWL(&o2, &t);
21301de99445SMaarten Lankhorst 	WARN_ON(ret);
21311de99445SMaarten Lankhorst }
21321de99445SMaarten Lankhorst 
21331de99445SMaarten Lankhorst static void ww_test_block_block(void)
21341de99445SMaarten Lankhorst {
21351de99445SMaarten Lankhorst 	WWL1(&o);
21361de99445SMaarten Lankhorst 	WWL1(&o2);
21371de99445SMaarten Lankhorst }
21381de99445SMaarten Lankhorst 
21391de99445SMaarten Lankhorst static void ww_test_block_try(void)
21401de99445SMaarten Lankhorst {
21411de99445SMaarten Lankhorst 	bool ret;
21421de99445SMaarten Lankhorst 
21431de99445SMaarten Lankhorst 	WWL1(&o);
21441de99445SMaarten Lankhorst 	ret = WWT(&o2);
21451de99445SMaarten Lankhorst 	WARN_ON(!ret);
21461de99445SMaarten Lankhorst }
21471de99445SMaarten Lankhorst 
21481de99445SMaarten Lankhorst static void ww_test_block_context(void)
21491de99445SMaarten Lankhorst {
21501de99445SMaarten Lankhorst 	int ret;
21511de99445SMaarten Lankhorst 
21521de99445SMaarten Lankhorst 	WWL1(&o);
21531de99445SMaarten Lankhorst 	WWAI(&t);
21541de99445SMaarten Lankhorst 
21551de99445SMaarten Lankhorst 	ret = WWL(&o2, &t);
21561de99445SMaarten Lankhorst 	WARN_ON(ret);
21571de99445SMaarten Lankhorst }
21581de99445SMaarten Lankhorst 
21591de99445SMaarten Lankhorst static void ww_test_spin_block(void)
21601de99445SMaarten Lankhorst {
21611de99445SMaarten Lankhorst 	L(A);
21621de99445SMaarten Lankhorst 	U(A);
21631de99445SMaarten Lankhorst 
21641de99445SMaarten Lankhorst 	WWL1(&o);
21651de99445SMaarten Lankhorst 	L(A);
21661de99445SMaarten Lankhorst 	U(A);
21671de99445SMaarten Lankhorst 	WWU(&o);
21681de99445SMaarten Lankhorst 
21691de99445SMaarten Lankhorst 	L(A);
21701de99445SMaarten Lankhorst 	WWL1(&o);
21711de99445SMaarten Lankhorst 	WWU(&o);
21721de99445SMaarten Lankhorst 	U(A);
21731de99445SMaarten Lankhorst }
21741de99445SMaarten Lankhorst 
21751de99445SMaarten Lankhorst static void ww_test_spin_try(void)
21761de99445SMaarten Lankhorst {
21771de99445SMaarten Lankhorst 	bool ret;
21781de99445SMaarten Lankhorst 
21791de99445SMaarten Lankhorst 	L(A);
21801de99445SMaarten Lankhorst 	U(A);
21811de99445SMaarten Lankhorst 
21821de99445SMaarten Lankhorst 	ret = WWT(&o);
21831de99445SMaarten Lankhorst 	WARN_ON(!ret);
21841de99445SMaarten Lankhorst 	L(A);
21851de99445SMaarten Lankhorst 	U(A);
21861de99445SMaarten Lankhorst 	WWU(&o);
21871de99445SMaarten Lankhorst 
21881de99445SMaarten Lankhorst 	L(A);
21891de99445SMaarten Lankhorst 	ret = WWT(&o);
21901de99445SMaarten Lankhorst 	WARN_ON(!ret);
21911de99445SMaarten Lankhorst 	WWU(&o);
21921de99445SMaarten Lankhorst 	U(A);
21931de99445SMaarten Lankhorst }
21941de99445SMaarten Lankhorst 
21951de99445SMaarten Lankhorst static void ww_test_spin_context(void)
21961de99445SMaarten Lankhorst {
21971de99445SMaarten Lankhorst 	int ret;
21981de99445SMaarten Lankhorst 
21991de99445SMaarten Lankhorst 	L(A);
22001de99445SMaarten Lankhorst 	U(A);
22011de99445SMaarten Lankhorst 
22021de99445SMaarten Lankhorst 	WWAI(&t);
22031de99445SMaarten Lankhorst 
22041de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
22051de99445SMaarten Lankhorst 	WARN_ON(ret);
22061de99445SMaarten Lankhorst 	L(A);
22071de99445SMaarten Lankhorst 	U(A);
22081de99445SMaarten Lankhorst 	WWU(&o);
22091de99445SMaarten Lankhorst 
22101de99445SMaarten Lankhorst 	L(A);
22111de99445SMaarten Lankhorst 	ret = WWL(&o, &t);
22121de99445SMaarten Lankhorst 	WARN_ON(ret);
22131de99445SMaarten Lankhorst 	WWU(&o);
22141de99445SMaarten Lankhorst 	U(A);
22151de99445SMaarten Lankhorst }
22161de99445SMaarten Lankhorst 
22171de99445SMaarten Lankhorst static void ww_tests(void)
22181de99445SMaarten Lankhorst {
22191de99445SMaarten Lankhorst 	printk("  --------------------------------------------------------------------------\n");
22201de99445SMaarten Lankhorst 	printk("  | Wound/wait tests |\n");
22211de99445SMaarten Lankhorst 	printk("  ---------------------\n");
22221de99445SMaarten Lankhorst 
22231de99445SMaarten Lankhorst 	print_testname("ww api failures");
22241de99445SMaarten Lankhorst 	dotest(ww_test_fail_acquire, SUCCESS, LOCKTYPE_WW);
22252fe3d4b1SMaarten Lankhorst 	dotest(ww_test_normal, SUCCESS, LOCKTYPE_WW);
22261de99445SMaarten Lankhorst 	dotest(ww_test_unneeded_slow, FAILURE, LOCKTYPE_WW);
222725139409SMichael Ellerman 	pr_cont("\n");
22281de99445SMaarten Lankhorst 
22291de99445SMaarten Lankhorst 	print_testname("ww contexts mixing");
22301de99445SMaarten Lankhorst 	dotest(ww_test_two_contexts, FAILURE, LOCKTYPE_WW);
22311de99445SMaarten Lankhorst 	dotest(ww_test_diff_class, FAILURE, LOCKTYPE_WW);
223225139409SMichael Ellerman 	pr_cont("\n");
22331de99445SMaarten Lankhorst 
22341de99445SMaarten Lankhorst 	print_testname("finishing ww context");
22351de99445SMaarten Lankhorst 	dotest(ww_test_context_done_twice, FAILURE, LOCKTYPE_WW);
22361de99445SMaarten Lankhorst 	dotest(ww_test_context_unlock_twice, FAILURE, LOCKTYPE_WW);
22371de99445SMaarten Lankhorst 	dotest(ww_test_context_fini_early, FAILURE, LOCKTYPE_WW);
22381de99445SMaarten Lankhorst 	dotest(ww_test_context_lock_after_done, FAILURE, LOCKTYPE_WW);
223925139409SMichael Ellerman 	pr_cont("\n");
22401de99445SMaarten Lankhorst 
22411de99445SMaarten Lankhorst 	print_testname("locking mismatches");
22421de99445SMaarten Lankhorst 	dotest(ww_test_object_unlock_twice, FAILURE, LOCKTYPE_WW);
22431de99445SMaarten Lankhorst 	dotest(ww_test_object_lock_unbalanced, FAILURE, LOCKTYPE_WW);
22441de99445SMaarten Lankhorst 	dotest(ww_test_object_lock_stale_context, FAILURE, LOCKTYPE_WW);
224525139409SMichael Ellerman 	pr_cont("\n");
22461de99445SMaarten Lankhorst 
2247f3cf139eSMaarten Lankhorst 	print_testname("EDEADLK handling");
2248f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_normal, SUCCESS, LOCKTYPE_WW);
2249f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_normal_slow, SUCCESS, LOCKTYPE_WW);
2250f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_no_unlock, FAILURE, LOCKTYPE_WW);
2251f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_no_unlock_slow, FAILURE, LOCKTYPE_WW);
2252f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_more, FAILURE, LOCKTYPE_WW);
2253f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_more_slow, FAILURE, LOCKTYPE_WW);
2254f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_more_edeadlk, FAILURE, LOCKTYPE_WW);
2255f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_more_edeadlk_slow, FAILURE, LOCKTYPE_WW);
2256f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_wrong, FAILURE, LOCKTYPE_WW);
2257f3cf139eSMaarten Lankhorst 	dotest(ww_test_edeadlk_acquire_wrong_slow, FAILURE, LOCKTYPE_WW);
225825139409SMichael Ellerman 	pr_cont("\n");
2259f3cf139eSMaarten Lankhorst 
22601de99445SMaarten Lankhorst 	print_testname("spinlock nest unlocked");
22611de99445SMaarten Lankhorst 	dotest(ww_test_spin_nest_unlocked, FAILURE, LOCKTYPE_WW);
226225139409SMichael Ellerman 	pr_cont("\n");
22631de99445SMaarten Lankhorst 
2264e04ce676SBoqun Feng 	print_testname("spinlock nest test");
2265e04ce676SBoqun Feng 	dotest(ww_test_spin_nest_lock, SUCCESS, LOCKTYPE_WW);
2266e04ce676SBoqun Feng 	pr_cont("\n");
2267e04ce676SBoqun Feng 
22681de99445SMaarten Lankhorst 	printk("  -----------------------------------------------------\n");
22691de99445SMaarten Lankhorst 	printk("                                 |block | try  |context|\n");
22701de99445SMaarten Lankhorst 	printk("  -----------------------------------------------------\n");
22711de99445SMaarten Lankhorst 
22721de99445SMaarten Lankhorst 	print_testname("context");
22731de99445SMaarten Lankhorst 	dotest(ww_test_context_block, FAILURE, LOCKTYPE_WW);
22741de99445SMaarten Lankhorst 	dotest(ww_test_context_try, SUCCESS, LOCKTYPE_WW);
22751de99445SMaarten Lankhorst 	dotest(ww_test_context_context, SUCCESS, LOCKTYPE_WW);
227625139409SMichael Ellerman 	pr_cont("\n");
22771de99445SMaarten Lankhorst 
22781de99445SMaarten Lankhorst 	print_testname("try");
22791de99445SMaarten Lankhorst 	dotest(ww_test_try_block, FAILURE, LOCKTYPE_WW);
22801de99445SMaarten Lankhorst 	dotest(ww_test_try_try, SUCCESS, LOCKTYPE_WW);
22811de99445SMaarten Lankhorst 	dotest(ww_test_try_context, FAILURE, LOCKTYPE_WW);
228225139409SMichael Ellerman 	pr_cont("\n");
22831de99445SMaarten Lankhorst 
22841de99445SMaarten Lankhorst 	print_testname("block");
22851de99445SMaarten Lankhorst 	dotest(ww_test_block_block, FAILURE, LOCKTYPE_WW);
22861de99445SMaarten Lankhorst 	dotest(ww_test_block_try, SUCCESS, LOCKTYPE_WW);
22871de99445SMaarten Lankhorst 	dotest(ww_test_block_context, FAILURE, LOCKTYPE_WW);
228825139409SMichael Ellerman 	pr_cont("\n");
22891de99445SMaarten Lankhorst 
22901de99445SMaarten Lankhorst 	print_testname("spinlock");
22911de99445SMaarten Lankhorst 	dotest(ww_test_spin_block, FAILURE, LOCKTYPE_WW);
22921de99445SMaarten Lankhorst 	dotest(ww_test_spin_try, SUCCESS, LOCKTYPE_WW);
22931de99445SMaarten Lankhorst 	dotest(ww_test_spin_context, FAILURE, LOCKTYPE_WW);
229425139409SMichael Ellerman 	pr_cont("\n");
22951de99445SMaarten Lankhorst }
2296cae2ed9aSIngo Molnar 
2297ad56450dSBoqun Feng 
2298ad56450dSBoqun Feng /*
2299ad56450dSBoqun Feng  * <in hardirq handler>
2300ad56450dSBoqun Feng  * read_lock(&A);
2301ad56450dSBoqun Feng  *			<hardirq disable>
2302ad56450dSBoqun Feng  *			spin_lock(&B);
2303ad56450dSBoqun Feng  * spin_lock(&B);
2304ad56450dSBoqun Feng  *			read_lock(&A);
2305ad56450dSBoqun Feng  *
2306ad56450dSBoqun Feng  * is a deadlock.
2307ad56450dSBoqun Feng  */
2308ad56450dSBoqun Feng static void queued_read_lock_hardirq_RE_Er(void)
2309ad56450dSBoqun Feng {
2310ad56450dSBoqun Feng 	HARDIRQ_ENTER();
2311ad56450dSBoqun Feng 	read_lock(&rwlock_A);
2312ad56450dSBoqun Feng 	LOCK(B);
2313ad56450dSBoqun Feng 	UNLOCK(B);
2314ad56450dSBoqun Feng 	read_unlock(&rwlock_A);
2315ad56450dSBoqun Feng 	HARDIRQ_EXIT();
2316ad56450dSBoqun Feng 
2317ad56450dSBoqun Feng 	HARDIRQ_DISABLE();
2318ad56450dSBoqun Feng 	LOCK(B);
2319ad56450dSBoqun Feng 	read_lock(&rwlock_A);
2320ad56450dSBoqun Feng 	read_unlock(&rwlock_A);
2321ad56450dSBoqun Feng 	UNLOCK(B);
2322ad56450dSBoqun Feng 	HARDIRQ_ENABLE();
2323ad56450dSBoqun Feng }
2324ad56450dSBoqun Feng 
2325ad56450dSBoqun Feng /*
2326ad56450dSBoqun Feng  * <in hardirq handler>
2327ad56450dSBoqun Feng  * spin_lock(&B);
2328ad56450dSBoqun Feng  *			<hardirq disable>
2329ad56450dSBoqun Feng  *			read_lock(&A);
2330ad56450dSBoqun Feng  * read_lock(&A);
2331ad56450dSBoqun Feng  *			spin_lock(&B);
2332ad56450dSBoqun Feng  *
2333ad56450dSBoqun Feng  * is not a deadlock.
2334ad56450dSBoqun Feng  */
2335ad56450dSBoqun Feng static void queued_read_lock_hardirq_ER_rE(void)
2336ad56450dSBoqun Feng {
2337ad56450dSBoqun Feng 	HARDIRQ_ENTER();
2338ad56450dSBoqun Feng 	LOCK(B);
2339ad56450dSBoqun Feng 	read_lock(&rwlock_A);
2340ad56450dSBoqun Feng 	read_unlock(&rwlock_A);
2341ad56450dSBoqun Feng 	UNLOCK(B);
2342ad56450dSBoqun Feng 	HARDIRQ_EXIT();
2343ad56450dSBoqun Feng 
2344ad56450dSBoqun Feng 	HARDIRQ_DISABLE();
2345ad56450dSBoqun Feng 	read_lock(&rwlock_A);
2346ad56450dSBoqun Feng 	LOCK(B);
2347ad56450dSBoqun Feng 	UNLOCK(B);
2348ad56450dSBoqun Feng 	read_unlock(&rwlock_A);
2349ad56450dSBoqun Feng 	HARDIRQ_ENABLE();
2350ad56450dSBoqun Feng }
2351ad56450dSBoqun Feng 
2352ad56450dSBoqun Feng /*
2353ad56450dSBoqun Feng  * <hardirq disable>
2354ad56450dSBoqun Feng  * spin_lock(&B);
2355ad56450dSBoqun Feng  *			read_lock(&A);
2356ad56450dSBoqun Feng  *			<in hardirq handler>
2357ad56450dSBoqun Feng  *			spin_lock(&B);
2358ad56450dSBoqun Feng  * read_lock(&A);
2359ad56450dSBoqun Feng  *
2360ad56450dSBoqun Feng  * is a deadlock. Because the two read_lock()s are both non-recursive readers.
2361ad56450dSBoqun Feng  */
2362ad56450dSBoqun Feng static void queued_read_lock_hardirq_inversion(void)
2363ad56450dSBoqun Feng {
2364ad56450dSBoqun Feng 
2365ad56450dSBoqun Feng 	HARDIRQ_ENTER();
2366ad56450dSBoqun Feng 	LOCK(B);
2367ad56450dSBoqun Feng 	UNLOCK(B);
2368ad56450dSBoqun Feng 	HARDIRQ_EXIT();
2369ad56450dSBoqun Feng 
2370ad56450dSBoqun Feng 	HARDIRQ_DISABLE();
2371ad56450dSBoqun Feng 	LOCK(B);
2372ad56450dSBoqun Feng 	read_lock(&rwlock_A);
2373ad56450dSBoqun Feng 	read_unlock(&rwlock_A);
2374ad56450dSBoqun Feng 	UNLOCK(B);
2375ad56450dSBoqun Feng 	HARDIRQ_ENABLE();
2376ad56450dSBoqun Feng 
2377ad56450dSBoqun Feng 	read_lock(&rwlock_A);
2378ad56450dSBoqun Feng 	read_unlock(&rwlock_A);
2379ad56450dSBoqun Feng }
2380ad56450dSBoqun Feng 
2381ad56450dSBoqun Feng static void queued_read_lock_tests(void)
2382ad56450dSBoqun Feng {
2383ad56450dSBoqun Feng 	printk("  --------------------------------------------------------------------------\n");
2384ad56450dSBoqun Feng 	printk("  | queued read lock tests |\n");
2385ad56450dSBoqun Feng 	printk("  ---------------------------\n");
2386ad56450dSBoqun Feng 	print_testname("hardirq read-lock/lock-read");
2387ad56450dSBoqun Feng 	dotest(queued_read_lock_hardirq_RE_Er, FAILURE, LOCKTYPE_RWLOCK);
2388ad56450dSBoqun Feng 	pr_cont("\n");
2389ad56450dSBoqun Feng 
2390ad56450dSBoqun Feng 	print_testname("hardirq lock-read/read-lock");
2391ad56450dSBoqun Feng 	dotest(queued_read_lock_hardirq_ER_rE, SUCCESS, LOCKTYPE_RWLOCK);
2392ad56450dSBoqun Feng 	pr_cont("\n");
2393ad56450dSBoqun Feng 
2394ad56450dSBoqun Feng 	print_testname("hardirq inversion");
2395ad56450dSBoqun Feng 	dotest(queued_read_lock_hardirq_inversion, FAILURE, LOCKTYPE_RWLOCK);
2396ad56450dSBoqun Feng 	pr_cont("\n");
2397ad56450dSBoqun Feng }
2398ad56450dSBoqun Feng 
2399d5037d1dSDaniel Vetter static void fs_reclaim_correct_nesting(void)
2400d5037d1dSDaniel Vetter {
2401d5037d1dSDaniel Vetter 	fs_reclaim_acquire(GFP_KERNEL);
2402d5037d1dSDaniel Vetter 	might_alloc(GFP_NOFS);
2403d5037d1dSDaniel Vetter 	fs_reclaim_release(GFP_KERNEL);
2404d5037d1dSDaniel Vetter }
2405d5037d1dSDaniel Vetter 
2406d5037d1dSDaniel Vetter static void fs_reclaim_wrong_nesting(void)
2407d5037d1dSDaniel Vetter {
2408d5037d1dSDaniel Vetter 	fs_reclaim_acquire(GFP_KERNEL);
2409d5037d1dSDaniel Vetter 	might_alloc(GFP_KERNEL);
2410d5037d1dSDaniel Vetter 	fs_reclaim_release(GFP_KERNEL);
2411d5037d1dSDaniel Vetter }
2412d5037d1dSDaniel Vetter 
2413d5037d1dSDaniel Vetter static void fs_reclaim_protected_nesting(void)
2414d5037d1dSDaniel Vetter {
2415d5037d1dSDaniel Vetter 	unsigned int flags;
2416d5037d1dSDaniel Vetter 
2417d5037d1dSDaniel Vetter 	fs_reclaim_acquire(GFP_KERNEL);
2418d5037d1dSDaniel Vetter 	flags = memalloc_nofs_save();
2419d5037d1dSDaniel Vetter 	might_alloc(GFP_KERNEL);
2420d5037d1dSDaniel Vetter 	memalloc_nofs_restore(flags);
2421d5037d1dSDaniel Vetter 	fs_reclaim_release(GFP_KERNEL);
2422d5037d1dSDaniel Vetter }
2423d5037d1dSDaniel Vetter 
2424d5037d1dSDaniel Vetter static void fs_reclaim_tests(void)
2425d5037d1dSDaniel Vetter {
2426d5037d1dSDaniel Vetter 	printk("  --------------------\n");
2427d5037d1dSDaniel Vetter 	printk("  | fs_reclaim tests |\n");
2428d5037d1dSDaniel Vetter 	printk("  --------------------\n");
2429d5037d1dSDaniel Vetter 
2430d5037d1dSDaniel Vetter 	print_testname("correct nesting");
2431d5037d1dSDaniel Vetter 	dotest(fs_reclaim_correct_nesting, SUCCESS, 0);
2432d5037d1dSDaniel Vetter 	pr_cont("\n");
2433d5037d1dSDaniel Vetter 
2434d5037d1dSDaniel Vetter 	print_testname("wrong nesting");
2435d5037d1dSDaniel Vetter 	dotest(fs_reclaim_wrong_nesting, FAILURE, 0);
2436d5037d1dSDaniel Vetter 	pr_cont("\n");
2437d5037d1dSDaniel Vetter 
2438d5037d1dSDaniel Vetter 	print_testname("protected nesting");
2439d5037d1dSDaniel Vetter 	dotest(fs_reclaim_protected_nesting, SUCCESS, 0);
2440d5037d1dSDaniel Vetter 	pr_cont("\n");
2441d5037d1dSDaniel Vetter }
2442d5037d1dSDaniel Vetter 
24439271a40dSBoqun Feng #define __guard(cleanup) __maybe_unused __attribute__((__cleanup__(cleanup)))
24449271a40dSBoqun Feng 
24459271a40dSBoqun Feng static void hardirq_exit(int *_)
24469271a40dSBoqun Feng {
24479271a40dSBoqun Feng 	HARDIRQ_EXIT();
24489271a40dSBoqun Feng }
24499271a40dSBoqun Feng 
24509271a40dSBoqun Feng #define HARDIRQ_CONTEXT(name, ...)					\
24519271a40dSBoqun Feng 	int hardirq_guard_##name __guard(hardirq_exit);			\
24529271a40dSBoqun Feng 	HARDIRQ_ENTER();
24539271a40dSBoqun Feng 
24549271a40dSBoqun Feng #define NOTTHREADED_HARDIRQ_CONTEXT(name, ...)				\
24559271a40dSBoqun Feng 	int notthreaded_hardirq_guard_##name __guard(hardirq_exit);	\
24569271a40dSBoqun Feng 	local_irq_disable();						\
24579271a40dSBoqun Feng 	__irq_enter();							\
24589271a40dSBoqun Feng 	WARN_ON(!in_irq());
24599271a40dSBoqun Feng 
24609271a40dSBoqun Feng static void softirq_exit(int *_)
24619271a40dSBoqun Feng {
24629271a40dSBoqun Feng 	SOFTIRQ_EXIT();
24639271a40dSBoqun Feng }
24649271a40dSBoqun Feng 
24659271a40dSBoqun Feng #define SOFTIRQ_CONTEXT(name, ...)				\
24669271a40dSBoqun Feng 	int softirq_guard_##name __guard(softirq_exit);		\
24679271a40dSBoqun Feng 	SOFTIRQ_ENTER();
24689271a40dSBoqun Feng 
24699271a40dSBoqun Feng static void rcu_exit(int *_)
24709271a40dSBoqun Feng {
24719271a40dSBoqun Feng 	rcu_read_unlock();
24729271a40dSBoqun Feng }
24739271a40dSBoqun Feng 
24749271a40dSBoqun Feng #define RCU_CONTEXT(name, ...)					\
24759271a40dSBoqun Feng 	int rcu_guard_##name __guard(rcu_exit);			\
24769271a40dSBoqun Feng 	rcu_read_lock();
24779271a40dSBoqun Feng 
24789271a40dSBoqun Feng static void rcu_bh_exit(int *_)
24799271a40dSBoqun Feng {
24809271a40dSBoqun Feng 	rcu_read_unlock_bh();
24819271a40dSBoqun Feng }
24829271a40dSBoqun Feng 
24839271a40dSBoqun Feng #define RCU_BH_CONTEXT(name, ...)				\
24849271a40dSBoqun Feng 	int rcu_bh_guard_##name __guard(rcu_bh_exit);		\
24859271a40dSBoqun Feng 	rcu_read_lock_bh();
24869271a40dSBoqun Feng 
24879271a40dSBoqun Feng static void rcu_sched_exit(int *_)
24889271a40dSBoqun Feng {
24899271a40dSBoqun Feng 	rcu_read_unlock_sched();
24909271a40dSBoqun Feng }
24919271a40dSBoqun Feng 
24929271a40dSBoqun Feng #define RCU_SCHED_CONTEXT(name, ...)				\
24939271a40dSBoqun Feng 	int rcu_sched_guard_##name __guard(rcu_sched_exit);	\
24949271a40dSBoqun Feng 	rcu_read_lock_sched();
24959271a40dSBoqun Feng 
24969271a40dSBoqun Feng static void rcu_callback_exit(int *_)
24979271a40dSBoqun Feng {
24989271a40dSBoqun Feng 	rcu_lock_release(&rcu_callback_map);
24999271a40dSBoqun Feng }
25009271a40dSBoqun Feng 
25019271a40dSBoqun Feng #define RCU_CALLBACK_CONTEXT(name, ...)					\
25029271a40dSBoqun Feng 	int rcu_callback_guard_##name __guard(rcu_callback_exit);	\
25039271a40dSBoqun Feng 	rcu_lock_acquire(&rcu_callback_map);
25049271a40dSBoqun Feng 
25059271a40dSBoqun Feng 
25069271a40dSBoqun Feng static void raw_spinlock_exit(raw_spinlock_t **lock)
25079271a40dSBoqun Feng {
25089271a40dSBoqun Feng 	raw_spin_unlock(*lock);
25099271a40dSBoqun Feng }
25109271a40dSBoqun Feng 
25119271a40dSBoqun Feng #define RAW_SPINLOCK_CONTEXT(name, lock)						\
25129271a40dSBoqun Feng 	raw_spinlock_t *raw_spinlock_guard_##name __guard(raw_spinlock_exit) = &(lock);	\
25139271a40dSBoqun Feng 	raw_spin_lock(&(lock));
25149271a40dSBoqun Feng 
25159271a40dSBoqun Feng static void spinlock_exit(spinlock_t **lock)
25169271a40dSBoqun Feng {
25179271a40dSBoqun Feng 	spin_unlock(*lock);
25189271a40dSBoqun Feng }
25199271a40dSBoqun Feng 
25209271a40dSBoqun Feng #define SPINLOCK_CONTEXT(name, lock)						\
25219271a40dSBoqun Feng 	spinlock_t *spinlock_guard_##name __guard(spinlock_exit) = &(lock);	\
25229271a40dSBoqun Feng 	spin_lock(&(lock));
25239271a40dSBoqun Feng 
25249271a40dSBoqun Feng static void mutex_exit(struct mutex **lock)
25259271a40dSBoqun Feng {
25269271a40dSBoqun Feng 	mutex_unlock(*lock);
25279271a40dSBoqun Feng }
25289271a40dSBoqun Feng 
25299271a40dSBoqun Feng #define MUTEX_CONTEXT(name, lock)					\
25309271a40dSBoqun Feng 	struct mutex *mutex_guard_##name __guard(mutex_exit) = &(lock);	\
25319271a40dSBoqun Feng 	mutex_lock(&(lock));
25329271a40dSBoqun Feng 
25339271a40dSBoqun Feng #define GENERATE_2_CONTEXT_TESTCASE(outer, outer_lock, inner, inner_lock)	\
25349271a40dSBoqun Feng 										\
25359271a40dSBoqun Feng static void __maybe_unused inner##_in_##outer(void)				\
25369271a40dSBoqun Feng {										\
25379271a40dSBoqun Feng 	outer##_CONTEXT(_, outer_lock);						\
25389271a40dSBoqun Feng 	{									\
25399271a40dSBoqun Feng 		inner##_CONTEXT(_, inner_lock);					\
25409271a40dSBoqun Feng 	}									\
25419271a40dSBoqun Feng }
25429271a40dSBoqun Feng 
25439271a40dSBoqun Feng /*
25449271a40dSBoqun Feng  * wait contexts (considering PREEMPT_RT)
25459271a40dSBoqun Feng  *
25469271a40dSBoqun Feng  * o: inner is allowed in outer
25479271a40dSBoqun Feng  * x: inner is disallowed in outer
25489271a40dSBoqun Feng  *
25499271a40dSBoqun Feng  *       \  inner |  RCU  | RAW_SPIN | SPIN | MUTEX
25509271a40dSBoqun Feng  * outer  \       |       |          |      |
25519271a40dSBoqun Feng  * ---------------+-------+----------+------+-------
25529271a40dSBoqun Feng  * HARDIRQ        |   o   |    o     |  o   |  x
25539271a40dSBoqun Feng  * ---------------+-------+----------+------+-------
25549271a40dSBoqun Feng  * NOTTHREADED_IRQ|   o   |    o     |  x   |  x
25559271a40dSBoqun Feng  * ---------------+-------+----------+------+-------
25569271a40dSBoqun Feng  * SOFTIRQ        |   o   |    o     |  o   |  x
25579271a40dSBoqun Feng  * ---------------+-------+----------+------+-------
25589271a40dSBoqun Feng  * RCU            |   o   |    o     |  o   |  x
25599271a40dSBoqun Feng  * ---------------+-------+----------+------+-------
25609271a40dSBoqun Feng  * RCU_BH         |   o   |    o     |  o   |  x
25619271a40dSBoqun Feng  * ---------------+-------+----------+------+-------
25629271a40dSBoqun Feng  * RCU_CALLBACK   |   o   |    o     |  o   |  x
25639271a40dSBoqun Feng  * ---------------+-------+----------+------+-------
25649271a40dSBoqun Feng  * RCU_SCHED      |   o   |    o     |  x   |  x
25659271a40dSBoqun Feng  * ---------------+-------+----------+------+-------
25669271a40dSBoqun Feng  * RAW_SPIN       |   o   |    o     |  x   |  x
25679271a40dSBoqun Feng  * ---------------+-------+----------+------+-------
25689271a40dSBoqun Feng  * SPIN           |   o   |    o     |  o   |  x
25699271a40dSBoqun Feng  * ---------------+-------+----------+------+-------
25709271a40dSBoqun Feng  * MUTEX          |   o   |    o     |  o   |  o
25719271a40dSBoqun Feng  * ---------------+-------+----------+------+-------
25729271a40dSBoqun Feng  */
25739271a40dSBoqun Feng 
25749271a40dSBoqun Feng #define GENERATE_2_CONTEXT_TESTCASE_FOR_ALL_OUTER(inner, inner_lock)		\
25759271a40dSBoqun Feng GENERATE_2_CONTEXT_TESTCASE(HARDIRQ, , inner, inner_lock)			\
25769271a40dSBoqun Feng GENERATE_2_CONTEXT_TESTCASE(NOTTHREADED_HARDIRQ, , inner, inner_lock)		\
25779271a40dSBoqun Feng GENERATE_2_CONTEXT_TESTCASE(SOFTIRQ, , inner, inner_lock)			\
25789271a40dSBoqun Feng GENERATE_2_CONTEXT_TESTCASE(RCU, , inner, inner_lock)				\
25799271a40dSBoqun Feng GENERATE_2_CONTEXT_TESTCASE(RCU_BH, , inner, inner_lock)			\
25809271a40dSBoqun Feng GENERATE_2_CONTEXT_TESTCASE(RCU_CALLBACK, , inner, inner_lock)			\
25819271a40dSBoqun Feng GENERATE_2_CONTEXT_TESTCASE(RCU_SCHED, , inner, inner_lock)			\
25829271a40dSBoqun Feng GENERATE_2_CONTEXT_TESTCASE(RAW_SPINLOCK, raw_lock_A, inner, inner_lock)	\
25839271a40dSBoqun Feng GENERATE_2_CONTEXT_TESTCASE(SPINLOCK, lock_A, inner, inner_lock)		\
25849271a40dSBoqun Feng GENERATE_2_CONTEXT_TESTCASE(MUTEX, mutex_A, inner, inner_lock)
25859271a40dSBoqun Feng 
25869271a40dSBoqun Feng GENERATE_2_CONTEXT_TESTCASE_FOR_ALL_OUTER(RCU, )
25879271a40dSBoqun Feng GENERATE_2_CONTEXT_TESTCASE_FOR_ALL_OUTER(RAW_SPINLOCK, raw_lock_B)
25889271a40dSBoqun Feng GENERATE_2_CONTEXT_TESTCASE_FOR_ALL_OUTER(SPINLOCK, lock_B)
25899271a40dSBoqun Feng GENERATE_2_CONTEXT_TESTCASE_FOR_ALL_OUTER(MUTEX, mutex_B)
25909271a40dSBoqun Feng 
25919271a40dSBoqun Feng /* the outer context allows all kinds of preemption */
25929271a40dSBoqun Feng #define DO_CONTEXT_TESTCASE_OUTER_PREEMPTIBLE(outer)			\
25939271a40dSBoqun Feng 	dotest(RCU_in_##outer, SUCCESS, LOCKTYPE_RWLOCK);		\
25949271a40dSBoqun Feng 	dotest(RAW_SPINLOCK_in_##outer, SUCCESS, LOCKTYPE_SPIN);	\
25959271a40dSBoqun Feng 	dotest(SPINLOCK_in_##outer, SUCCESS, LOCKTYPE_SPIN);		\
25969271a40dSBoqun Feng 	dotest(MUTEX_in_##outer, SUCCESS, LOCKTYPE_MUTEX);		\
25979271a40dSBoqun Feng 
25989271a40dSBoqun Feng /*
25999271a40dSBoqun Feng  * the outer context only allows the preemption introduced by spinlock_t (which
26009271a40dSBoqun Feng  * is a sleepable lock for PREEMPT_RT)
26019271a40dSBoqun Feng  */
26029271a40dSBoqun Feng #define DO_CONTEXT_TESTCASE_OUTER_LIMITED_PREEMPTIBLE(outer)		\
26039271a40dSBoqun Feng 	dotest(RCU_in_##outer, SUCCESS, LOCKTYPE_RWLOCK);		\
26049271a40dSBoqun Feng 	dotest(RAW_SPINLOCK_in_##outer, SUCCESS, LOCKTYPE_SPIN);	\
26059271a40dSBoqun Feng 	dotest(SPINLOCK_in_##outer, SUCCESS, LOCKTYPE_SPIN);		\
26069271a40dSBoqun Feng 	dotest(MUTEX_in_##outer, FAILURE, LOCKTYPE_MUTEX);		\
26079271a40dSBoqun Feng 
26089271a40dSBoqun Feng /* the outer doesn't allows any kind of preemption */
26099271a40dSBoqun Feng #define DO_CONTEXT_TESTCASE_OUTER_NOT_PREEMPTIBLE(outer)			\
26109271a40dSBoqun Feng 	dotest(RCU_in_##outer, SUCCESS, LOCKTYPE_RWLOCK);		\
26119271a40dSBoqun Feng 	dotest(RAW_SPINLOCK_in_##outer, SUCCESS, LOCKTYPE_SPIN);	\
26129271a40dSBoqun Feng 	dotest(SPINLOCK_in_##outer, FAILURE, LOCKTYPE_SPIN);		\
26139271a40dSBoqun Feng 	dotest(MUTEX_in_##outer, FAILURE, LOCKTYPE_MUTEX);		\
26149271a40dSBoqun Feng 
26159271a40dSBoqun Feng static void wait_context_tests(void)
26169271a40dSBoqun Feng {
26179271a40dSBoqun Feng 	printk("  --------------------------------------------------------------------------\n");
26189271a40dSBoqun Feng 	printk("  | wait context tests |\n");
26199271a40dSBoqun Feng 	printk("  --------------------------------------------------------------------------\n");
26209271a40dSBoqun Feng 	printk("                                 | rcu  | raw  | spin |mutex |\n");
26219271a40dSBoqun Feng 	printk("  --------------------------------------------------------------------------\n");
26229271a40dSBoqun Feng 	print_testname("in hardirq context");
26239271a40dSBoqun Feng 	DO_CONTEXT_TESTCASE_OUTER_LIMITED_PREEMPTIBLE(HARDIRQ);
26249271a40dSBoqun Feng 	pr_cont("\n");
26259271a40dSBoqun Feng 
26269271a40dSBoqun Feng 	print_testname("in hardirq context (not threaded)");
26279271a40dSBoqun Feng 	DO_CONTEXT_TESTCASE_OUTER_NOT_PREEMPTIBLE(NOTTHREADED_HARDIRQ);
26289271a40dSBoqun Feng 	pr_cont("\n");
26299271a40dSBoqun Feng 
26309271a40dSBoqun Feng 	print_testname("in softirq context");
26319271a40dSBoqun Feng 	DO_CONTEXT_TESTCASE_OUTER_LIMITED_PREEMPTIBLE(SOFTIRQ);
26329271a40dSBoqun Feng 	pr_cont("\n");
26339271a40dSBoqun Feng 
26349271a40dSBoqun Feng 	print_testname("in RCU context");
26359271a40dSBoqun Feng 	DO_CONTEXT_TESTCASE_OUTER_LIMITED_PREEMPTIBLE(RCU);
26369271a40dSBoqun Feng 	pr_cont("\n");
26379271a40dSBoqun Feng 
26389271a40dSBoqun Feng 	print_testname("in RCU-bh context");
26399271a40dSBoqun Feng 	DO_CONTEXT_TESTCASE_OUTER_LIMITED_PREEMPTIBLE(RCU_BH);
26409271a40dSBoqun Feng 	pr_cont("\n");
26419271a40dSBoqun Feng 
26429271a40dSBoqun Feng 	print_testname("in RCU callback context");
26439271a40dSBoqun Feng 	DO_CONTEXT_TESTCASE_OUTER_LIMITED_PREEMPTIBLE(RCU_CALLBACK);
26449271a40dSBoqun Feng 	pr_cont("\n");
26459271a40dSBoqun Feng 
26469271a40dSBoqun Feng 	print_testname("in RCU-sched context");
26479271a40dSBoqun Feng 	DO_CONTEXT_TESTCASE_OUTER_NOT_PREEMPTIBLE(RCU_SCHED);
26489271a40dSBoqun Feng 	pr_cont("\n");
26499271a40dSBoqun Feng 
26509271a40dSBoqun Feng 	print_testname("in RAW_SPINLOCK context");
26519271a40dSBoqun Feng 	DO_CONTEXT_TESTCASE_OUTER_NOT_PREEMPTIBLE(RAW_SPINLOCK);
26529271a40dSBoqun Feng 	pr_cont("\n");
26539271a40dSBoqun Feng 
26549271a40dSBoqun Feng 	print_testname("in SPINLOCK context");
26559271a40dSBoqun Feng 	DO_CONTEXT_TESTCASE_OUTER_LIMITED_PREEMPTIBLE(SPINLOCK);
26569271a40dSBoqun Feng 	pr_cont("\n");
26579271a40dSBoqun Feng 
26589271a40dSBoqun Feng 	print_testname("in MUTEX context");
26599271a40dSBoqun Feng 	DO_CONTEXT_TESTCASE_OUTER_PREEMPTIBLE(MUTEX);
26609271a40dSBoqun Feng 	pr_cont("\n");
26619271a40dSBoqun Feng }
26629271a40dSBoqun Feng 
26637e923e6aSPeter Zijlstra static void local_lock_2(void)
26647e923e6aSPeter Zijlstra {
26657e923e6aSPeter Zijlstra 	local_lock_acquire(&local_A);	/* IRQ-ON */
26667e923e6aSPeter Zijlstra 	local_lock_release(&local_A);
26677e923e6aSPeter Zijlstra 
26687e923e6aSPeter Zijlstra 	HARDIRQ_ENTER();
26697e923e6aSPeter Zijlstra 	spin_lock(&lock_A);		/* IN-IRQ */
26707e923e6aSPeter Zijlstra 	spin_unlock(&lock_A);
26717e923e6aSPeter Zijlstra 	HARDIRQ_EXIT()
26727e923e6aSPeter Zijlstra 
26737e923e6aSPeter Zijlstra 	HARDIRQ_DISABLE();
26747e923e6aSPeter Zijlstra 	spin_lock(&lock_A);
26757e923e6aSPeter Zijlstra 	local_lock_acquire(&local_A);	/* IN-IRQ <-> IRQ-ON cycle, false */
26767e923e6aSPeter Zijlstra 	local_lock_release(&local_A);
26777e923e6aSPeter Zijlstra 	spin_unlock(&lock_A);
26787e923e6aSPeter Zijlstra 	HARDIRQ_ENABLE();
26797e923e6aSPeter Zijlstra }
26807e923e6aSPeter Zijlstra 
26817e923e6aSPeter Zijlstra static void local_lock_3A(void)
26827e923e6aSPeter Zijlstra {
26837e923e6aSPeter Zijlstra 	local_lock_acquire(&local_A);	/* IRQ-ON */
26847e923e6aSPeter Zijlstra 	spin_lock(&lock_B);		/* IRQ-ON */
26857e923e6aSPeter Zijlstra 	spin_unlock(&lock_B);
26867e923e6aSPeter Zijlstra 	local_lock_release(&local_A);
26877e923e6aSPeter Zijlstra 
26887e923e6aSPeter Zijlstra 	HARDIRQ_ENTER();
26897e923e6aSPeter Zijlstra 	spin_lock(&lock_A);		/* IN-IRQ */
26907e923e6aSPeter Zijlstra 	spin_unlock(&lock_A);
26917e923e6aSPeter Zijlstra 	HARDIRQ_EXIT()
26927e923e6aSPeter Zijlstra 
26937e923e6aSPeter Zijlstra 	HARDIRQ_DISABLE();
26947e923e6aSPeter Zijlstra 	spin_lock(&lock_A);
26957e923e6aSPeter Zijlstra 	local_lock_acquire(&local_A);	/* IN-IRQ <-> IRQ-ON cycle only if we count local_lock(), false */
26967e923e6aSPeter Zijlstra 	local_lock_release(&local_A);
26977e923e6aSPeter Zijlstra 	spin_unlock(&lock_A);
26987e923e6aSPeter Zijlstra 	HARDIRQ_ENABLE();
26997e923e6aSPeter Zijlstra }
27007e923e6aSPeter Zijlstra 
27017e923e6aSPeter Zijlstra static void local_lock_3B(void)
27027e923e6aSPeter Zijlstra {
27037e923e6aSPeter Zijlstra 	local_lock_acquire(&local_A);	/* IRQ-ON */
27047e923e6aSPeter Zijlstra 	spin_lock(&lock_B);		/* IRQ-ON */
27057e923e6aSPeter Zijlstra 	spin_unlock(&lock_B);
27067e923e6aSPeter Zijlstra 	local_lock_release(&local_A);
27077e923e6aSPeter Zijlstra 
27087e923e6aSPeter Zijlstra 	HARDIRQ_ENTER();
27097e923e6aSPeter Zijlstra 	spin_lock(&lock_A);		/* IN-IRQ */
27107e923e6aSPeter Zijlstra 	spin_unlock(&lock_A);
27117e923e6aSPeter Zijlstra 	HARDIRQ_EXIT()
27127e923e6aSPeter Zijlstra 
27137e923e6aSPeter Zijlstra 	HARDIRQ_DISABLE();
27147e923e6aSPeter Zijlstra 	spin_lock(&lock_A);
27157e923e6aSPeter Zijlstra 	local_lock_acquire(&local_A);	/* IN-IRQ <-> IRQ-ON cycle only if we count local_lock(), false */
27167e923e6aSPeter Zijlstra 	local_lock_release(&local_A);
27177e923e6aSPeter Zijlstra 	spin_unlock(&lock_A);
27187e923e6aSPeter Zijlstra 	HARDIRQ_ENABLE();
27197e923e6aSPeter Zijlstra 
27207e923e6aSPeter Zijlstra 	HARDIRQ_DISABLE();
27217e923e6aSPeter Zijlstra 	spin_lock(&lock_A);
27227e923e6aSPeter Zijlstra 	spin_lock(&lock_B);		/* IN-IRQ <-> IRQ-ON cycle, true */
27237e923e6aSPeter Zijlstra 	spin_unlock(&lock_B);
27247e923e6aSPeter Zijlstra 	spin_unlock(&lock_A);
27257e923e6aSPeter Zijlstra 	HARDIRQ_DISABLE();
27267e923e6aSPeter Zijlstra 
27277e923e6aSPeter Zijlstra }
27287e923e6aSPeter Zijlstra 
27297e923e6aSPeter Zijlstra static void local_lock_tests(void)
27307e923e6aSPeter Zijlstra {
27317e923e6aSPeter Zijlstra 	printk("  --------------------------------------------------------------------------\n");
27327e923e6aSPeter Zijlstra 	printk("  | local_lock tests |\n");
27337e923e6aSPeter Zijlstra 	printk("  ---------------------\n");
27347e923e6aSPeter Zijlstra 
27357e923e6aSPeter Zijlstra 	print_testname("local_lock inversion  2");
27367e923e6aSPeter Zijlstra 	dotest(local_lock_2, SUCCESS, LOCKTYPE_LL);
27377e923e6aSPeter Zijlstra 	pr_cont("\n");
27387e923e6aSPeter Zijlstra 
27397e923e6aSPeter Zijlstra 	print_testname("local_lock inversion 3A");
27407e923e6aSPeter Zijlstra 	dotest(local_lock_3A, SUCCESS, LOCKTYPE_LL);
27417e923e6aSPeter Zijlstra 	pr_cont("\n");
27427e923e6aSPeter Zijlstra 
27437e923e6aSPeter Zijlstra 	print_testname("local_lock inversion 3B");
27447e923e6aSPeter Zijlstra 	dotest(local_lock_3B, FAILURE, LOCKTYPE_LL);
27457e923e6aSPeter Zijlstra 	pr_cont("\n");
27467e923e6aSPeter Zijlstra }
27477e923e6aSPeter Zijlstra 
2748*8946ccc2SBoqun Feng static void hardirq_deadlock_softirq_not_deadlock(void)
2749*8946ccc2SBoqun Feng {
2750*8946ccc2SBoqun Feng 	/* mutex_A is hardirq-unsafe and softirq-unsafe */
2751*8946ccc2SBoqun Feng 	/* mutex_A -> lock_C */
2752*8946ccc2SBoqun Feng 	mutex_lock(&mutex_A);
2753*8946ccc2SBoqun Feng 	HARDIRQ_DISABLE();
2754*8946ccc2SBoqun Feng 	spin_lock(&lock_C);
2755*8946ccc2SBoqun Feng 	spin_unlock(&lock_C);
2756*8946ccc2SBoqun Feng 	HARDIRQ_ENABLE();
2757*8946ccc2SBoqun Feng 	mutex_unlock(&mutex_A);
2758*8946ccc2SBoqun Feng 
2759*8946ccc2SBoqun Feng 	/* lock_A is hardirq-safe */
2760*8946ccc2SBoqun Feng 	HARDIRQ_ENTER();
2761*8946ccc2SBoqun Feng 	spin_lock(&lock_A);
2762*8946ccc2SBoqun Feng 	spin_unlock(&lock_A);
2763*8946ccc2SBoqun Feng 	HARDIRQ_EXIT();
2764*8946ccc2SBoqun Feng 
2765*8946ccc2SBoqun Feng 	/* lock_A -> lock_B */
2766*8946ccc2SBoqun Feng 	HARDIRQ_DISABLE();
2767*8946ccc2SBoqun Feng 	spin_lock(&lock_A);
2768*8946ccc2SBoqun Feng 	spin_lock(&lock_B);
2769*8946ccc2SBoqun Feng 	spin_unlock(&lock_B);
2770*8946ccc2SBoqun Feng 	spin_unlock(&lock_A);
2771*8946ccc2SBoqun Feng 	HARDIRQ_ENABLE();
2772*8946ccc2SBoqun Feng 
2773*8946ccc2SBoqun Feng 	/* lock_B -> lock_C */
2774*8946ccc2SBoqun Feng 	HARDIRQ_DISABLE();
2775*8946ccc2SBoqun Feng 	spin_lock(&lock_B);
2776*8946ccc2SBoqun Feng 	spin_lock(&lock_C);
2777*8946ccc2SBoqun Feng 	spin_unlock(&lock_C);
2778*8946ccc2SBoqun Feng 	spin_unlock(&lock_B);
2779*8946ccc2SBoqun Feng 	HARDIRQ_ENABLE();
2780*8946ccc2SBoqun Feng 
2781*8946ccc2SBoqun Feng 	/* lock_D is softirq-safe */
2782*8946ccc2SBoqun Feng 	SOFTIRQ_ENTER();
2783*8946ccc2SBoqun Feng 	spin_lock(&lock_D);
2784*8946ccc2SBoqun Feng 	spin_unlock(&lock_D);
2785*8946ccc2SBoqun Feng 	SOFTIRQ_EXIT();
2786*8946ccc2SBoqun Feng 
2787*8946ccc2SBoqun Feng 	/* And lock_D is hardirq-unsafe */
2788*8946ccc2SBoqun Feng 	SOFTIRQ_DISABLE();
2789*8946ccc2SBoqun Feng 	spin_lock(&lock_D);
2790*8946ccc2SBoqun Feng 	spin_unlock(&lock_D);
2791*8946ccc2SBoqun Feng 	SOFTIRQ_ENABLE();
2792*8946ccc2SBoqun Feng 
2793*8946ccc2SBoqun Feng 	/*
2794*8946ccc2SBoqun Feng 	 * mutex_A -> lock_C -> lock_D is softirq-unsafe -> softirq-safe, not
2795*8946ccc2SBoqun Feng 	 * deadlock.
2796*8946ccc2SBoqun Feng 	 *
2797*8946ccc2SBoqun Feng 	 * lock_A -> lock_B -> lock_C -> lock_D is hardirq-safe ->
2798*8946ccc2SBoqun Feng 	 * hardirq-unsafe, deadlock.
2799*8946ccc2SBoqun Feng 	 */
2800*8946ccc2SBoqun Feng 	HARDIRQ_DISABLE();
2801*8946ccc2SBoqun Feng 	spin_lock(&lock_C);
2802*8946ccc2SBoqun Feng 	spin_lock(&lock_D);
2803*8946ccc2SBoqun Feng 	spin_unlock(&lock_D);
2804*8946ccc2SBoqun Feng 	spin_unlock(&lock_C);
2805*8946ccc2SBoqun Feng 	HARDIRQ_ENABLE();
2806*8946ccc2SBoqun Feng }
2807*8946ccc2SBoqun Feng 
2808cae2ed9aSIngo Molnar void locking_selftest(void)
2809cae2ed9aSIngo Molnar {
2810cae2ed9aSIngo Molnar 	/*
2811cae2ed9aSIngo Molnar 	 * Got a locking failure before the selftest ran?
2812cae2ed9aSIngo Molnar 	 */
2813cae2ed9aSIngo Molnar 	if (!debug_locks) {
2814cae2ed9aSIngo Molnar 		printk("----------------------------------\n");
2815cae2ed9aSIngo Molnar 		printk("| Locking API testsuite disabled |\n");
2816cae2ed9aSIngo Molnar 		printk("----------------------------------\n");
2817cae2ed9aSIngo Molnar 		return;
2818cae2ed9aSIngo Molnar 	}
2819cae2ed9aSIngo Molnar 
2820cae2ed9aSIngo Molnar 	/*
2821e9181886SBoqun Feng 	 * treats read_lock() as recursive read locks for testing purpose
2822e9181886SBoqun Feng 	 */
2823e9181886SBoqun Feng 	force_read_lock_recursive = 1;
2824e9181886SBoqun Feng 
2825e9181886SBoqun Feng 	/*
2826cae2ed9aSIngo Molnar 	 * Run the testsuite:
2827cae2ed9aSIngo Molnar 	 */
2828cae2ed9aSIngo Molnar 	printk("------------------------\n");
2829cae2ed9aSIngo Molnar 	printk("| Locking API testsuite:\n");
2830cae2ed9aSIngo Molnar 	printk("----------------------------------------------------------------------------\n");
2831cae2ed9aSIngo Molnar 	printk("                                 | spin |wlock |rlock |mutex | wsem | rsem |\n");
2832cae2ed9aSIngo Molnar 	printk("  --------------------------------------------------------------------------\n");
2833cae2ed9aSIngo Molnar 
2834cae2ed9aSIngo Molnar 	init_shared_classes();
2835cdc84d79SBart Van Assche 	lockdep_set_selftest_task(current);
2836cae2ed9aSIngo Molnar 
28376c9076ecSIngo Molnar 	DO_TESTCASE_6R("A-A deadlock", AA);
2838cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-B-A deadlock", ABBA);
2839cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-B-C-C-A deadlock", ABBCCA);
2840cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-C-A-B-C deadlock", ABCABC);
2841cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-B-C-C-D-D-A deadlock", ABBCCDDA);
2842cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-C-D-B-D-D-A deadlock", ABCDBDDA);
2843cae2ed9aSIngo Molnar 	DO_TESTCASE_6R("A-B-C-D-B-C-D-A deadlock", ABCDBCDA);
2844cae2ed9aSIngo Molnar 	DO_TESTCASE_6("double unlock", double_unlock);
2845cae2ed9aSIngo Molnar 	DO_TESTCASE_6("initialize held", init_held);
2846cae2ed9aSIngo Molnar 
2847cae2ed9aSIngo Molnar 	printk("  --------------------------------------------------------------------------\n");
2848cae2ed9aSIngo Molnar 	print_testname("recursive read-lock");
284925139409SMichael Ellerman 	pr_cont("             |");
2850cae2ed9aSIngo Molnar 	dotest(rlock_AA1, SUCCESS, LOCKTYPE_RWLOCK);
285125139409SMichael Ellerman 	pr_cont("             |");
2852cae2ed9aSIngo Molnar 	dotest(rsem_AA1, FAILURE, LOCKTYPE_RWSEM);
285325139409SMichael Ellerman 	pr_cont("\n");
2854cae2ed9aSIngo Molnar 
2855cae2ed9aSIngo Molnar 	print_testname("recursive read-lock #2");
285625139409SMichael Ellerman 	pr_cont("             |");
28576c9076ecSIngo Molnar 	dotest(rlock_AA1B, SUCCESS, LOCKTYPE_RWLOCK);
285825139409SMichael Ellerman 	pr_cont("             |");
2859cae2ed9aSIngo Molnar 	dotest(rsem_AA1B, FAILURE, LOCKTYPE_RWSEM);
286025139409SMichael Ellerman 	pr_cont("\n");
2861cae2ed9aSIngo Molnar 
2862cae2ed9aSIngo Molnar 	print_testname("mixed read-write-lock");
286325139409SMichael Ellerman 	pr_cont("             |");
2864cae2ed9aSIngo Molnar 	dotest(rlock_AA2, FAILURE, LOCKTYPE_RWLOCK);
286525139409SMichael Ellerman 	pr_cont("             |");
2866cae2ed9aSIngo Molnar 	dotest(rsem_AA2, FAILURE, LOCKTYPE_RWSEM);
286725139409SMichael Ellerman 	pr_cont("\n");
2868cae2ed9aSIngo Molnar 
2869cae2ed9aSIngo Molnar 	print_testname("mixed write-read-lock");
287025139409SMichael Ellerman 	pr_cont("             |");
2871cae2ed9aSIngo Molnar 	dotest(rlock_AA3, FAILURE, LOCKTYPE_RWLOCK);
287225139409SMichael Ellerman 	pr_cont("             |");
2873cae2ed9aSIngo Molnar 	dotest(rsem_AA3, FAILURE, LOCKTYPE_RWSEM);
287425139409SMichael Ellerman 	pr_cont("\n");
2875cae2ed9aSIngo Molnar 
2876e9149858SPeter Zijlstra 	print_testname("mixed read-lock/lock-write ABBA");
2877e9149858SPeter Zijlstra 	pr_cont("             |");
2878e9149858SPeter Zijlstra 	dotest(rlock_ABBA1, FAILURE, LOCKTYPE_RWLOCK);
2879e9149858SPeter Zijlstra 	pr_cont("             |");
2880e9149858SPeter Zijlstra 	dotest(rwsem_ABBA1, FAILURE, LOCKTYPE_RWSEM);
2881e9149858SPeter Zijlstra 
2882e9149858SPeter Zijlstra 	print_testname("mixed read-lock/lock-read ABBA");
2883e9149858SPeter Zijlstra 	pr_cont("             |");
2884e9149858SPeter Zijlstra 	dotest(rlock_ABBA2, SUCCESS, LOCKTYPE_RWLOCK);
2885e9149858SPeter Zijlstra 	pr_cont("             |");
2886e9149858SPeter Zijlstra 	dotest(rwsem_ABBA2, FAILURE, LOCKTYPE_RWSEM);
2887e9149858SPeter Zijlstra 
2888e9149858SPeter Zijlstra 	print_testname("mixed write-lock/lock-write ABBA");
2889e9149858SPeter Zijlstra 	pr_cont("             |");
2890e9149858SPeter Zijlstra 	dotest(rlock_ABBA3, FAILURE, LOCKTYPE_RWLOCK);
2891e9149858SPeter Zijlstra 	pr_cont("             |");
2892e9149858SPeter Zijlstra 	dotest(rwsem_ABBA3, FAILURE, LOCKTYPE_RWSEM);
2893e9149858SPeter Zijlstra 
2894d4f200e5SBoqun Feng 	print_testname("chain cached mixed R-L/L-W ABBA");
2895d4f200e5SBoqun Feng 	pr_cont("             |");
2896d4f200e5SBoqun Feng 	dotest(rlock_chaincache_ABBA1, FAILURE, LOCKTYPE_RWLOCK);
2897d4f200e5SBoqun Feng 
28988ef7ca75SBoqun Feng 	DO_TESTCASE_6x1RRB("rlock W1R2/W2R3/W3R1", W1R2_W2R3_W3R1);
28998ef7ca75SBoqun Feng 	DO_TESTCASE_6x1RRB("rlock W1W2/R2R3/W3R1", W1W2_R2R3_W3R1);
29008ef7ca75SBoqun Feng 	DO_TESTCASE_6x1RR("rlock W1W2/R2R3/R3W1", W1W2_R2R3_R3W1);
29018ef7ca75SBoqun Feng 	DO_TESTCASE_6x1RR("rlock W1R2/R2R3/W3W1", W1R2_R2R3_W3W1);
29028ef7ca75SBoqun Feng 
2903cae2ed9aSIngo Molnar 	printk("  --------------------------------------------------------------------------\n");
2904cae2ed9aSIngo Molnar 
2905cae2ed9aSIngo Molnar 	/*
2906cae2ed9aSIngo Molnar 	 * irq-context testcases:
2907cae2ed9aSIngo Molnar 	 */
2908cae2ed9aSIngo Molnar 	DO_TESTCASE_2x6("irqs-on + irq-safe-A", irqsafe1);
2909cae2ed9aSIngo Molnar 	DO_TESTCASE_2x3("sirq-safe-A => hirqs-on", irqsafe2A);
2910cae2ed9aSIngo Molnar 	DO_TESTCASE_2x6("safe-A + irqs-on", irqsafe2B);
2911cae2ed9aSIngo Molnar 	DO_TESTCASE_6x6("safe-A + unsafe-B #1", irqsafe3);
2912cae2ed9aSIngo Molnar 	DO_TESTCASE_6x6("safe-A + unsafe-B #2", irqsafe4);
2913cae2ed9aSIngo Molnar 	DO_TESTCASE_6x6RW("irq lock-inversion", irq_inversion);
2914cae2ed9aSIngo Molnar 
291531e0d747SBoqun Feng 	DO_TESTCASE_6x2x2RW("irq read-recursion", irq_read_recursion);
291631e0d747SBoqun Feng 	DO_TESTCASE_6x2x2RW("irq read-recursion #2", irq_read_recursion2);
291796a16f45SBoqun Feng 	DO_TESTCASE_6x2x2RW("irq read-recursion #3", irq_read_recursion3);
2918cae2ed9aSIngo Molnar 
29191de99445SMaarten Lankhorst 	ww_tests();
29201de99445SMaarten Lankhorst 
2921e9181886SBoqun Feng 	force_read_lock_recursive = 0;
2922e9181886SBoqun Feng 	/*
2923e9181886SBoqun Feng 	 * queued_read_lock() specific test cases can be put here
2924e9181886SBoqun Feng 	 */
2925ad56450dSBoqun Feng 	if (IS_ENABLED(CONFIG_QUEUED_RWLOCKS))
2926ad56450dSBoqun Feng 		queued_read_lock_tests();
2927e9181886SBoqun Feng 
2928d5037d1dSDaniel Vetter 	fs_reclaim_tests();
2929d5037d1dSDaniel Vetter 
29309271a40dSBoqun Feng 	/* Wait context test cases that are specific for RAW_LOCK_NESTING */
29319271a40dSBoqun Feng 	if (IS_ENABLED(CONFIG_PROVE_RAW_LOCK_NESTING))
29329271a40dSBoqun Feng 		wait_context_tests();
29339271a40dSBoqun Feng 
29347e923e6aSPeter Zijlstra 	local_lock_tests();
29357e923e6aSPeter Zijlstra 
2936*8946ccc2SBoqun Feng 	print_testname("hardirq_unsafe_softirq_safe");
2937*8946ccc2SBoqun Feng 	dotest(hardirq_deadlock_softirq_not_deadlock, FAILURE, LOCKTYPE_SPECIAL);
2938*8946ccc2SBoqun Feng 	pr_cont("\n");
2939*8946ccc2SBoqun Feng 
2940cae2ed9aSIngo Molnar 	if (unexpected_testcase_failures) {
2941cae2ed9aSIngo Molnar 		printk("-----------------------------------------------------------------\n");
2942cae2ed9aSIngo Molnar 		debug_locks = 0;
2943cae2ed9aSIngo Molnar 		printk("BUG: %3d unexpected failures (out of %3d) - debugging disabled! |\n",
2944cae2ed9aSIngo Molnar 			unexpected_testcase_failures, testcase_total);
2945cae2ed9aSIngo Molnar 		printk("-----------------------------------------------------------------\n");
2946cae2ed9aSIngo Molnar 	} else if (expected_testcase_failures && testcase_successes) {
2947cae2ed9aSIngo Molnar 		printk("--------------------------------------------------------\n");
2948cae2ed9aSIngo Molnar 		printk("%3d out of %3d testcases failed, as expected. |\n",
2949cae2ed9aSIngo Molnar 			expected_testcase_failures, testcase_total);
2950cae2ed9aSIngo Molnar 		printk("----------------------------------------------------\n");
2951cae2ed9aSIngo Molnar 		debug_locks = 1;
2952cae2ed9aSIngo Molnar 	} else if (expected_testcase_failures && !testcase_successes) {
2953cae2ed9aSIngo Molnar 		printk("--------------------------------------------------------\n");
2954cae2ed9aSIngo Molnar 		printk("All %3d testcases failed, as expected. |\n",
2955cae2ed9aSIngo Molnar 			expected_testcase_failures);
2956cae2ed9aSIngo Molnar 		printk("----------------------------------------\n");
2957cae2ed9aSIngo Molnar 		debug_locks = 1;
2958cae2ed9aSIngo Molnar 	} else {
2959cae2ed9aSIngo Molnar 		printk("-------------------------------------------------------\n");
2960cae2ed9aSIngo Molnar 		printk("Good, all %3d testcases passed! |\n",
2961cae2ed9aSIngo Molnar 			testcase_successes);
2962cae2ed9aSIngo Molnar 		printk("---------------------------------\n");
2963cae2ed9aSIngo Molnar 		debug_locks = 1;
2964cae2ed9aSIngo Molnar 	}
2965cdc84d79SBart Van Assche 	lockdep_set_selftest_task(NULL);
2966cae2ed9aSIngo Molnar 	debug_locks_silent = 0;
2967cae2ed9aSIngo Molnar }
2968