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 <mingo@redhat.com>
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
29a529f8dbSSebastian Andrzej Siewior #ifdef CONFIG_PREEMPT_RT
30a529f8dbSSebastian Andrzej Siewior # define NON_RT(...)
31a529f8dbSSebastian Andrzej Siewior #else
32a529f8dbSSebastian Andrzej Siewior # define NON_RT(...) __VA_ARGS__
33a529f8dbSSebastian Andrzej Siewior #endif
34a529f8dbSSebastian Andrzej Siewior
35cae2ed9aSIngo Molnar /*
36cae2ed9aSIngo Molnar * Change this to 1 if you want to see the failure printouts:
37cae2ed9aSIngo Molnar */
38cae2ed9aSIngo Molnar static unsigned int debug_locks_verbose;
39e9181886SBoqun Feng unsigned int force_read_lock_recursive;
40cae2ed9aSIngo Molnar
4108295b3bSThomas Hellstrom static DEFINE_WD_CLASS(ww_lockdep);
421de99445SMaarten Lankhorst
setup_debug_locks_verbose(char * str)43cae2ed9aSIngo Molnar static int __init setup_debug_locks_verbose(char *str)
44cae2ed9aSIngo Molnar {
45cae2ed9aSIngo Molnar get_option(&str, &debug_locks_verbose);
46cae2ed9aSIngo Molnar
47cae2ed9aSIngo Molnar return 1;
48cae2ed9aSIngo Molnar }
49cae2ed9aSIngo Molnar
50cae2ed9aSIngo Molnar __setup("debug_locks_verbose=", setup_debug_locks_verbose);
51cae2ed9aSIngo Molnar
52cae2ed9aSIngo Molnar #define FAILURE 0
53cae2ed9aSIngo Molnar #define SUCCESS 1
54cae2ed9aSIngo Molnar
55cae2ed9aSIngo Molnar #define LOCKTYPE_SPIN 0x1
56cae2ed9aSIngo Molnar #define LOCKTYPE_RWLOCK 0x2
57cae2ed9aSIngo Molnar #define LOCKTYPE_MUTEX 0x4
58cae2ed9aSIngo Molnar #define LOCKTYPE_RWSEM 0x8
591de99445SMaarten Lankhorst #define LOCKTYPE_WW 0x10
60018956d6SPeter Zijlstra #define LOCKTYPE_RTMUTEX 0x20
617e923e6aSPeter Zijlstra #define LOCKTYPE_LL 0x40
628946ccc2SBoqun Feng #define LOCKTYPE_SPECIAL 0x80
631de99445SMaarten Lankhorst
641de99445SMaarten Lankhorst static struct ww_acquire_ctx t, t2;
65f3cf139eSMaarten Lankhorst static struct ww_mutex o, o2, o3;
66cae2ed9aSIngo Molnar
67cae2ed9aSIngo Molnar /*
68cae2ed9aSIngo Molnar * Normal standalone locks, for the circular and irq-context
69cae2ed9aSIngo Molnar * dependency tests:
70cae2ed9aSIngo Molnar */
71a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_A);
72a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_B);
73a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_C);
74a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_D);
75cae2ed9aSIngo Molnar
769271a40dSBoqun Feng static DEFINE_RAW_SPINLOCK(raw_lock_A);
779271a40dSBoqun Feng static DEFINE_RAW_SPINLOCK(raw_lock_B);
789271a40dSBoqun Feng
79cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_A);
80cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_B);
81cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_C);
82cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_D);
83cae2ed9aSIngo Molnar
84cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_A);
85cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_B);
86cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_C);
87cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_D);
88cae2ed9aSIngo Molnar
89cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_A);
90cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_B);
91cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_C);
92cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_D);
93cae2ed9aSIngo Molnar
94018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
95018956d6SPeter Zijlstra
96018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_A);
97018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_B);
98018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_C);
99018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_D);
100018956d6SPeter Zijlstra
101018956d6SPeter Zijlstra #endif
102018956d6SPeter Zijlstra
103cae2ed9aSIngo Molnar /*
104cae2ed9aSIngo Molnar * Locks that we initialize dynamically as well so that
105cae2ed9aSIngo Molnar * e.g. X1 and X2 becomes two instances of the same class,
106cae2ed9aSIngo Molnar * but X* and Y* are different classes. We do this so that
107cae2ed9aSIngo Molnar * we do not trigger a real lockup:
108cae2ed9aSIngo Molnar */
109a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_X1);
110a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_X2);
111a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_Y1);
112a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_Y2);
113a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_Z1);
114a2e9ae58SPeter Zijlstra static DEFINE_SPINLOCK(lock_Z2);
115cae2ed9aSIngo Molnar
116cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_X1);
117cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_X2);
118cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Y1);
119cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Y2);
120cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Z1);
121cae2ed9aSIngo Molnar static DEFINE_RWLOCK(rwlock_Z2);
122cae2ed9aSIngo Molnar
123cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_X1);
124cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_X2);
125cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Y1);
126cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Y2);
127cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Z1);
128cae2ed9aSIngo Molnar static DEFINE_MUTEX(mutex_Z2);
129cae2ed9aSIngo Molnar
130cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_X1);
131cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_X2);
132cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Y1);
133cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Y2);
134cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Z1);
135cae2ed9aSIngo Molnar static DECLARE_RWSEM(rwsem_Z2);
136cae2ed9aSIngo Molnar
137018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
138018956d6SPeter Zijlstra
139018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_X1);
140018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_X2);
141018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_Y1);
142018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_Y2);
143018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_Z1);
144018956d6SPeter Zijlstra static DEFINE_RT_MUTEX(rtmutex_Z2);
145018956d6SPeter Zijlstra
146018956d6SPeter Zijlstra #endif
147018956d6SPeter Zijlstra
148fc78dd08SSebastian Andrzej Siewior static DEFINE_PER_CPU(local_lock_t, local_A);
1497e923e6aSPeter Zijlstra
150cae2ed9aSIngo Molnar /*
151cae2ed9aSIngo Molnar * non-inlined runtime initializers, to let separate locks share
152cae2ed9aSIngo Molnar * the same lock-class:
153cae2ed9aSIngo Molnar */
154cae2ed9aSIngo Molnar #define INIT_CLASS_FUNC(class) \
155cae2ed9aSIngo Molnar static noinline void \
156a2e9ae58SPeter Zijlstra init_class_##class(spinlock_t *lock, rwlock_t *rwlock, \
1579fb1b90cSYong Zhang struct mutex *mutex, struct rw_semaphore *rwsem)\
158cae2ed9aSIngo Molnar { \
159a2e9ae58SPeter Zijlstra spin_lock_init(lock); \
160cae2ed9aSIngo Molnar rwlock_init(rwlock); \
161cae2ed9aSIngo Molnar mutex_init(mutex); \
162cae2ed9aSIngo Molnar init_rwsem(rwsem); \
163cae2ed9aSIngo Molnar }
164cae2ed9aSIngo Molnar
165cae2ed9aSIngo Molnar INIT_CLASS_FUNC(X)
INIT_CLASS_FUNC(Y)166cae2ed9aSIngo Molnar INIT_CLASS_FUNC(Y)
167cae2ed9aSIngo Molnar INIT_CLASS_FUNC(Z)
168cae2ed9aSIngo Molnar
169cae2ed9aSIngo Molnar static void init_shared_classes(void)
170cae2ed9aSIngo Molnar {
171018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
172018956d6SPeter Zijlstra static struct lock_class_key rt_X, rt_Y, rt_Z;
173018956d6SPeter Zijlstra
174018956d6SPeter Zijlstra __rt_mutex_init(&rtmutex_X1, __func__, &rt_X);
175018956d6SPeter Zijlstra __rt_mutex_init(&rtmutex_X2, __func__, &rt_X);
176018956d6SPeter Zijlstra __rt_mutex_init(&rtmutex_Y1, __func__, &rt_Y);
177018956d6SPeter Zijlstra __rt_mutex_init(&rtmutex_Y2, __func__, &rt_Y);
178018956d6SPeter Zijlstra __rt_mutex_init(&rtmutex_Z1, __func__, &rt_Z);
179018956d6SPeter Zijlstra __rt_mutex_init(&rtmutex_Z2, __func__, &rt_Z);
180018956d6SPeter Zijlstra #endif
181018956d6SPeter Zijlstra
182cae2ed9aSIngo Molnar init_class_X(&lock_X1, &rwlock_X1, &mutex_X1, &rwsem_X1);
183cae2ed9aSIngo Molnar init_class_X(&lock_X2, &rwlock_X2, &mutex_X2, &rwsem_X2);
184cae2ed9aSIngo Molnar
185cae2ed9aSIngo Molnar init_class_Y(&lock_Y1, &rwlock_Y1, &mutex_Y1, &rwsem_Y1);
186cae2ed9aSIngo Molnar init_class_Y(&lock_Y2, &rwlock_Y2, &mutex_Y2, &rwsem_Y2);
187cae2ed9aSIngo Molnar
188cae2ed9aSIngo Molnar init_class_Z(&lock_Z1, &rwlock_Z1, &mutex_Z1, &rwsem_Z1);
189cae2ed9aSIngo Molnar init_class_Z(&lock_Z2, &rwlock_Z2, &mutex_Z2, &rwsem_Z2);
190cae2ed9aSIngo Molnar }
191cae2ed9aSIngo Molnar
192cae2ed9aSIngo Molnar /*
193cae2ed9aSIngo Molnar * For spinlocks and rwlocks we also do hardirq-safe / softirq-safe tests.
194cae2ed9aSIngo Molnar * The following functions use a lock from a simulated hardirq/softirq
195cae2ed9aSIngo Molnar * context, causing the locks to be marked as hardirq-safe/softirq-safe:
196cae2ed9aSIngo Molnar */
197cae2ed9aSIngo Molnar
198cae2ed9aSIngo Molnar #define HARDIRQ_DISABLE local_irq_disable
199cae2ed9aSIngo Molnar #define HARDIRQ_ENABLE local_irq_enable
200cae2ed9aSIngo Molnar
201cae2ed9aSIngo Molnar #define HARDIRQ_ENTER() \
202cae2ed9aSIngo Molnar local_irq_disable(); \
203ba9f207cSFrederic Weisbecker __irq_enter(); \
204c0c2c0daSPeter Zijlstra lockdep_hardirq_threaded(); \
205cae2ed9aSIngo Molnar WARN_ON(!in_irq());
206cae2ed9aSIngo Molnar
207cae2ed9aSIngo Molnar #define HARDIRQ_EXIT() \
208cae2ed9aSIngo Molnar __irq_exit(); \
209cae2ed9aSIngo Molnar local_irq_enable();
210cae2ed9aSIngo Molnar
211cae2ed9aSIngo Molnar #define SOFTIRQ_DISABLE local_bh_disable
212cae2ed9aSIngo Molnar #define SOFTIRQ_ENABLE local_bh_enable
213cae2ed9aSIngo Molnar
214cae2ed9aSIngo Molnar #define SOFTIRQ_ENTER() \
215cae2ed9aSIngo Molnar local_bh_disable(); \
216cae2ed9aSIngo Molnar local_irq_disable(); \
217d820ac4cSIngo Molnar lockdep_softirq_enter(); \
218cae2ed9aSIngo Molnar WARN_ON(!in_softirq());
219cae2ed9aSIngo Molnar
220cae2ed9aSIngo Molnar #define SOFTIRQ_EXIT() \
221d820ac4cSIngo Molnar lockdep_softirq_exit(); \
222cae2ed9aSIngo Molnar local_irq_enable(); \
223cae2ed9aSIngo Molnar local_bh_enable();
224cae2ed9aSIngo Molnar
225cae2ed9aSIngo Molnar /*
226cae2ed9aSIngo Molnar * Shortcuts for lock/unlock API variants, to keep
227cae2ed9aSIngo Molnar * the testcases compact:
228cae2ed9aSIngo Molnar */
229a2e9ae58SPeter Zijlstra #define L(x) spin_lock(&lock_##x)
230a2e9ae58SPeter Zijlstra #define U(x) spin_unlock(&lock_##x)
231cae2ed9aSIngo Molnar #define LU(x) L(x); U(x)
232a2e9ae58SPeter Zijlstra #define SI(x) spin_lock_init(&lock_##x)
233cae2ed9aSIngo Molnar
234cae2ed9aSIngo Molnar #define WL(x) write_lock(&rwlock_##x)
235cae2ed9aSIngo Molnar #define WU(x) write_unlock(&rwlock_##x)
236cae2ed9aSIngo Molnar #define WLU(x) WL(x); WU(x)
237cae2ed9aSIngo Molnar
238cae2ed9aSIngo Molnar #define RL(x) read_lock(&rwlock_##x)
239cae2ed9aSIngo Molnar #define RU(x) read_unlock(&rwlock_##x)
240cae2ed9aSIngo Molnar #define RLU(x) RL(x); RU(x)
241cae2ed9aSIngo Molnar #define RWI(x) rwlock_init(&rwlock_##x)
242cae2ed9aSIngo Molnar
243cae2ed9aSIngo Molnar #define ML(x) mutex_lock(&mutex_##x)
244cae2ed9aSIngo Molnar #define MU(x) mutex_unlock(&mutex_##x)
245cae2ed9aSIngo Molnar #define MI(x) mutex_init(&mutex_##x)
246cae2ed9aSIngo Molnar
247018956d6SPeter Zijlstra #define RTL(x) rt_mutex_lock(&rtmutex_##x)
248018956d6SPeter Zijlstra #define RTU(x) rt_mutex_unlock(&rtmutex_##x)
249018956d6SPeter Zijlstra #define RTI(x) rt_mutex_init(&rtmutex_##x)
250018956d6SPeter Zijlstra
251cae2ed9aSIngo Molnar #define WSL(x) down_write(&rwsem_##x)
252cae2ed9aSIngo Molnar #define WSU(x) up_write(&rwsem_##x)
253cae2ed9aSIngo Molnar
254cae2ed9aSIngo Molnar #define RSL(x) down_read(&rwsem_##x)
255cae2ed9aSIngo Molnar #define RSU(x) up_read(&rwsem_##x)
256cae2ed9aSIngo Molnar #define RWSI(x) init_rwsem(&rwsem_##x)
257cae2ed9aSIngo Molnar
2581de99445SMaarten Lankhorst #ifndef CONFIG_DEBUG_WW_MUTEX_SLOWPATH
2591de99445SMaarten Lankhorst #define WWAI(x) ww_acquire_init(x, &ww_lockdep)
2601de99445SMaarten Lankhorst #else
2611de99445SMaarten Lankhorst #define WWAI(x) do { ww_acquire_init(x, &ww_lockdep); (x)->deadlock_inject_countdown = ~0U; } while (0)
2621de99445SMaarten Lankhorst #endif
2631de99445SMaarten Lankhorst #define WWAD(x) ww_acquire_done(x)
2641de99445SMaarten Lankhorst #define WWAF(x) ww_acquire_fini(x)
2651de99445SMaarten Lankhorst
2661de99445SMaarten Lankhorst #define WWL(x, c) ww_mutex_lock(x, c)
26712235da8SMaarten Lankhorst #define WWT(x) ww_mutex_trylock(x, NULL)
2681de99445SMaarten Lankhorst #define WWL1(x) ww_mutex_lock(x, NULL)
2691de99445SMaarten Lankhorst #define WWU(x) ww_mutex_unlock(x)
2701de99445SMaarten Lankhorst
2711de99445SMaarten Lankhorst
272cae2ed9aSIngo Molnar #define LOCK_UNLOCK_2(x,y) LOCK(x); LOCK(y); UNLOCK(y); UNLOCK(x)
273cae2ed9aSIngo Molnar
274cae2ed9aSIngo Molnar /*
275cae2ed9aSIngo Molnar * Generate different permutations of the same testcase, using
276cae2ed9aSIngo Molnar * the same basic lock-dependency/state events:
277cae2ed9aSIngo Molnar */
278cae2ed9aSIngo Molnar
279cae2ed9aSIngo Molnar #define GENERATE_TESTCASE(name) \
280cae2ed9aSIngo Molnar \
281cae2ed9aSIngo Molnar static void name(void) { E(); }
282cae2ed9aSIngo Molnar
283cae2ed9aSIngo Molnar #define GENERATE_PERMUTATIONS_2_EVENTS(name) \
284cae2ed9aSIngo Molnar \
285cae2ed9aSIngo Molnar static void name##_12(void) { E1(); E2(); } \
286cae2ed9aSIngo Molnar static void name##_21(void) { E2(); E1(); }
287cae2ed9aSIngo Molnar
288cae2ed9aSIngo Molnar #define GENERATE_PERMUTATIONS_3_EVENTS(name) \
289cae2ed9aSIngo Molnar \
290cae2ed9aSIngo Molnar static void name##_123(void) { E1(); E2(); E3(); } \
291cae2ed9aSIngo Molnar static void name##_132(void) { E1(); E3(); E2(); } \
292cae2ed9aSIngo Molnar static void name##_213(void) { E2(); E1(); E3(); } \
293cae2ed9aSIngo Molnar static void name##_231(void) { E2(); E3(); E1(); } \
294cae2ed9aSIngo Molnar static void name##_312(void) { E3(); E1(); E2(); } \
295cae2ed9aSIngo Molnar static void name##_321(void) { E3(); E2(); E1(); }
296cae2ed9aSIngo Molnar
297cae2ed9aSIngo Molnar /*
298cae2ed9aSIngo Molnar * AA deadlock:
299cae2ed9aSIngo Molnar */
300cae2ed9aSIngo Molnar
301cae2ed9aSIngo Molnar #define E() \
302cae2ed9aSIngo Molnar \
303cae2ed9aSIngo Molnar LOCK(X1); \
304cae2ed9aSIngo Molnar LOCK(X2); /* this one should fail */
305cae2ed9aSIngo Molnar
306cae2ed9aSIngo Molnar /*
307cae2ed9aSIngo Molnar * 6 testcases:
308cae2ed9aSIngo Molnar */
309cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
310cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_spin)
311cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
312cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_wlock)
313cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
314cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_rlock)
315cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
316cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_mutex)
317cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
318cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_wsem)
319cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
320cae2ed9aSIngo Molnar GENERATE_TESTCASE(AA_rsem)
321cae2ed9aSIngo Molnar
322018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
323018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
324018956d6SPeter Zijlstra GENERATE_TESTCASE(AA_rtmutex);
325018956d6SPeter Zijlstra #endif
326018956d6SPeter Zijlstra
327cae2ed9aSIngo Molnar #undef E
328cae2ed9aSIngo Molnar
329cae2ed9aSIngo Molnar /*
330cae2ed9aSIngo Molnar * Special-case for read-locking, they are
3316c9076ecSIngo Molnar * allowed to recurse on the same lock class:
332cae2ed9aSIngo Molnar */
rlock_AA1(void)333cae2ed9aSIngo Molnar static void rlock_AA1(void)
334cae2ed9aSIngo Molnar {
335cae2ed9aSIngo Molnar RL(X1);
336cae2ed9aSIngo Molnar RL(X1); // this one should NOT fail
337cae2ed9aSIngo Molnar }
338cae2ed9aSIngo Molnar
rlock_AA1B(void)339cae2ed9aSIngo Molnar static void rlock_AA1B(void)
340cae2ed9aSIngo Molnar {
341cae2ed9aSIngo Molnar RL(X1);
3426c9076ecSIngo Molnar RL(X2); // this one should NOT fail
343cae2ed9aSIngo Molnar }
344cae2ed9aSIngo Molnar
rsem_AA1(void)345cae2ed9aSIngo Molnar static void rsem_AA1(void)
346cae2ed9aSIngo Molnar {
347cae2ed9aSIngo Molnar RSL(X1);
348cae2ed9aSIngo Molnar RSL(X1); // this one should fail
349cae2ed9aSIngo Molnar }
350cae2ed9aSIngo Molnar
rsem_AA1B(void)351cae2ed9aSIngo Molnar static void rsem_AA1B(void)
352cae2ed9aSIngo Molnar {
353cae2ed9aSIngo Molnar RSL(X1);
354cae2ed9aSIngo Molnar RSL(X2); // this one should fail
355cae2ed9aSIngo Molnar }
356cae2ed9aSIngo Molnar /*
357cae2ed9aSIngo Molnar * The mixing of read and write locks is not allowed:
358cae2ed9aSIngo Molnar */
rlock_AA2(void)359cae2ed9aSIngo Molnar static void rlock_AA2(void)
360cae2ed9aSIngo Molnar {
361cae2ed9aSIngo Molnar RL(X1);
362cae2ed9aSIngo Molnar WL(X2); // this one should fail
363cae2ed9aSIngo Molnar }
364cae2ed9aSIngo Molnar
rsem_AA2(void)365cae2ed9aSIngo Molnar static void rsem_AA2(void)
366cae2ed9aSIngo Molnar {
367cae2ed9aSIngo Molnar RSL(X1);
368cae2ed9aSIngo Molnar WSL(X2); // this one should fail
369cae2ed9aSIngo Molnar }
370cae2ed9aSIngo Molnar
rlock_AA3(void)371cae2ed9aSIngo Molnar static void rlock_AA3(void)
372cae2ed9aSIngo Molnar {
373cae2ed9aSIngo Molnar WL(X1);
374cae2ed9aSIngo Molnar RL(X2); // this one should fail
375cae2ed9aSIngo Molnar }
376cae2ed9aSIngo Molnar
rsem_AA3(void)377cae2ed9aSIngo Molnar static void rsem_AA3(void)
378cae2ed9aSIngo Molnar {
379cae2ed9aSIngo Molnar WSL(X1);
380cae2ed9aSIngo Molnar RSL(X2); // this one should fail
381cae2ed9aSIngo Molnar }
382cae2ed9aSIngo Molnar
383cae2ed9aSIngo Molnar /*
384e9149858SPeter Zijlstra * read_lock(A)
385e9149858SPeter Zijlstra * spin_lock(B)
386e9149858SPeter Zijlstra * spin_lock(B)
387e9149858SPeter Zijlstra * write_lock(A)
388e9149858SPeter Zijlstra */
rlock_ABBA1(void)389e9149858SPeter Zijlstra static void rlock_ABBA1(void)
390e9149858SPeter Zijlstra {
391e9149858SPeter Zijlstra RL(X1);
392e9149858SPeter Zijlstra L(Y1);
393e9149858SPeter Zijlstra U(Y1);
394e9149858SPeter Zijlstra RU(X1);
395e9149858SPeter Zijlstra
396e9149858SPeter Zijlstra L(Y1);
397e9149858SPeter Zijlstra WL(X1);
398e9149858SPeter Zijlstra WU(X1);
399e9149858SPeter Zijlstra U(Y1); // should fail
400e9149858SPeter Zijlstra }
401e9149858SPeter Zijlstra
rwsem_ABBA1(void)402e9149858SPeter Zijlstra static void rwsem_ABBA1(void)
403e9149858SPeter Zijlstra {
404e9149858SPeter Zijlstra RSL(X1);
405e9149858SPeter Zijlstra ML(Y1);
406e9149858SPeter Zijlstra MU(Y1);
407e9149858SPeter Zijlstra RSU(X1);
408e9149858SPeter Zijlstra
409e9149858SPeter Zijlstra ML(Y1);
410e9149858SPeter Zijlstra WSL(X1);
411e9149858SPeter Zijlstra WSU(X1);
412e9149858SPeter Zijlstra MU(Y1); // should fail
413e9149858SPeter Zijlstra }
414e9149858SPeter Zijlstra
415e9149858SPeter Zijlstra /*
416e9149858SPeter Zijlstra * read_lock(A)
417e9149858SPeter Zijlstra * spin_lock(B)
418e9149858SPeter Zijlstra * spin_lock(B)
419d4f200e5SBoqun Feng * write_lock(A)
420d4f200e5SBoqun Feng *
421d4f200e5SBoqun Feng * This test case is aimed at poking whether the chain cache prevents us from
422d4f200e5SBoqun Feng * detecting a read-lock/lock-write deadlock: if the chain cache doesn't differ
423d4f200e5SBoqun Feng * read/write locks, the following case may happen
424d4f200e5SBoqun Feng *
425d4f200e5SBoqun Feng * { read_lock(A)->lock(B) dependency exists }
426d4f200e5SBoqun Feng *
427d4f200e5SBoqun Feng * P0:
428d4f200e5SBoqun Feng * lock(B);
429d4f200e5SBoqun Feng * read_lock(A);
430d4f200e5SBoqun Feng *
431d4f200e5SBoqun Feng * { Not a deadlock, B -> A is added in the chain cache }
432d4f200e5SBoqun Feng *
433d4f200e5SBoqun Feng * P1:
434d4f200e5SBoqun Feng * lock(B);
435d4f200e5SBoqun Feng * write_lock(A);
436d4f200e5SBoqun Feng *
437d4f200e5SBoqun Feng * { B->A found in chain cache, not reported as a deadlock }
438d4f200e5SBoqun Feng *
439d4f200e5SBoqun Feng */
rlock_chaincache_ABBA1(void)440d4f200e5SBoqun Feng static void rlock_chaincache_ABBA1(void)
441d4f200e5SBoqun Feng {
442d4f200e5SBoqun Feng RL(X1);
443d4f200e5SBoqun Feng L(Y1);
444d4f200e5SBoqun Feng U(Y1);
445d4f200e5SBoqun Feng RU(X1);
446d4f200e5SBoqun Feng
447d4f200e5SBoqun Feng L(Y1);
448d4f200e5SBoqun Feng RL(X1);
449d4f200e5SBoqun Feng RU(X1);
450d4f200e5SBoqun Feng U(Y1);
451d4f200e5SBoqun Feng
452d4f200e5SBoqun Feng L(Y1);
453d4f200e5SBoqun Feng WL(X1);
454d4f200e5SBoqun Feng WU(X1);
455d4f200e5SBoqun Feng U(Y1); // should fail
456d4f200e5SBoqun Feng }
457d4f200e5SBoqun Feng
458d4f200e5SBoqun Feng /*
459d4f200e5SBoqun Feng * read_lock(A)
460d4f200e5SBoqun Feng * spin_lock(B)
461d4f200e5SBoqun Feng * spin_lock(B)
462e9149858SPeter Zijlstra * read_lock(A)
463e9149858SPeter Zijlstra */
rlock_ABBA2(void)464e9149858SPeter Zijlstra static void rlock_ABBA2(void)
465e9149858SPeter Zijlstra {
466e9149858SPeter Zijlstra RL(X1);
467e9149858SPeter Zijlstra L(Y1);
468e9149858SPeter Zijlstra U(Y1);
469e9149858SPeter Zijlstra RU(X1);
470e9149858SPeter Zijlstra
471e9149858SPeter Zijlstra L(Y1);
472e9149858SPeter Zijlstra RL(X1);
473e9149858SPeter Zijlstra RU(X1);
474e9149858SPeter Zijlstra U(Y1); // should NOT fail
475e9149858SPeter Zijlstra }
476e9149858SPeter Zijlstra
rwsem_ABBA2(void)477e9149858SPeter Zijlstra static void rwsem_ABBA2(void)
478e9149858SPeter Zijlstra {
479e9149858SPeter Zijlstra RSL(X1);
480e9149858SPeter Zijlstra ML(Y1);
481e9149858SPeter Zijlstra MU(Y1);
482e9149858SPeter Zijlstra RSU(X1);
483e9149858SPeter Zijlstra
484e9149858SPeter Zijlstra ML(Y1);
485e9149858SPeter Zijlstra RSL(X1);
486e9149858SPeter Zijlstra RSU(X1);
487e9149858SPeter Zijlstra MU(Y1); // should fail
488e9149858SPeter Zijlstra }
489e9149858SPeter Zijlstra
490e9149858SPeter Zijlstra
491e9149858SPeter Zijlstra /*
492e9149858SPeter Zijlstra * write_lock(A)
493e9149858SPeter Zijlstra * spin_lock(B)
494e9149858SPeter Zijlstra * spin_lock(B)
495e9149858SPeter Zijlstra * write_lock(A)
496e9149858SPeter Zijlstra */
rlock_ABBA3(void)497e9149858SPeter Zijlstra static void rlock_ABBA3(void)
498e9149858SPeter Zijlstra {
499e9149858SPeter Zijlstra WL(X1);
500e9149858SPeter Zijlstra L(Y1);
501e9149858SPeter Zijlstra U(Y1);
502e9149858SPeter Zijlstra WU(X1);
503e9149858SPeter Zijlstra
504e9149858SPeter Zijlstra L(Y1);
505e9149858SPeter Zijlstra WL(X1);
506e9149858SPeter Zijlstra WU(X1);
507e9149858SPeter Zijlstra U(Y1); // should fail
508e9149858SPeter Zijlstra }
509e9149858SPeter Zijlstra
rwsem_ABBA3(void)510e9149858SPeter Zijlstra static void rwsem_ABBA3(void)
511e9149858SPeter Zijlstra {
512e9149858SPeter Zijlstra WSL(X1);
513e9149858SPeter Zijlstra ML(Y1);
514e9149858SPeter Zijlstra MU(Y1);
515e9149858SPeter Zijlstra WSU(X1);
516e9149858SPeter Zijlstra
517e9149858SPeter Zijlstra ML(Y1);
518e9149858SPeter Zijlstra WSL(X1);
519e9149858SPeter Zijlstra WSU(X1);
520e9149858SPeter Zijlstra MU(Y1); // should fail
521e9149858SPeter Zijlstra }
522e9149858SPeter Zijlstra
523e9149858SPeter Zijlstra /*
524cae2ed9aSIngo Molnar * ABBA deadlock:
525cae2ed9aSIngo Molnar */
526cae2ed9aSIngo Molnar
527cae2ed9aSIngo Molnar #define E() \
528cae2ed9aSIngo Molnar \
529cae2ed9aSIngo Molnar LOCK_UNLOCK_2(A, B); \
530cae2ed9aSIngo Molnar LOCK_UNLOCK_2(B, A); /* fail */
531cae2ed9aSIngo Molnar
532cae2ed9aSIngo Molnar /*
533cae2ed9aSIngo Molnar * 6 testcases:
534cae2ed9aSIngo Molnar */
535cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
536cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_spin)
537cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
538cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_wlock)
539cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
540cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_rlock)
541cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
542cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_mutex)
543cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
544cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_wsem)
545cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
546cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBA_rsem)
547cae2ed9aSIngo Molnar
548018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
549018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
550018956d6SPeter Zijlstra GENERATE_TESTCASE(ABBA_rtmutex);
551018956d6SPeter Zijlstra #endif
552018956d6SPeter Zijlstra
553cae2ed9aSIngo Molnar #undef E
554cae2ed9aSIngo Molnar
555cae2ed9aSIngo Molnar /*
556cae2ed9aSIngo Molnar * AB BC CA deadlock:
557cae2ed9aSIngo Molnar */
558cae2ed9aSIngo Molnar
559cae2ed9aSIngo Molnar #define E() \
560cae2ed9aSIngo Molnar \
561cae2ed9aSIngo Molnar LOCK_UNLOCK_2(A, B); \
562cae2ed9aSIngo Molnar LOCK_UNLOCK_2(B, C); \
563cae2ed9aSIngo Molnar LOCK_UNLOCK_2(C, A); /* fail */
564cae2ed9aSIngo Molnar
565cae2ed9aSIngo Molnar /*
566cae2ed9aSIngo Molnar * 6 testcases:
567cae2ed9aSIngo Molnar */
568cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
569cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_spin)
570cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
571cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_wlock)
572cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
573cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_rlock)
574cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
575cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_mutex)
576cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
577cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_wsem)
578cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
579cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCA_rsem)
580cae2ed9aSIngo Molnar
581018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
582018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
583018956d6SPeter Zijlstra GENERATE_TESTCASE(ABBCCA_rtmutex);
584018956d6SPeter Zijlstra #endif
585018956d6SPeter Zijlstra
586cae2ed9aSIngo Molnar #undef E
587cae2ed9aSIngo Molnar
588cae2ed9aSIngo Molnar /*
589cae2ed9aSIngo Molnar * AB CA BC deadlock:
590cae2ed9aSIngo Molnar */
591cae2ed9aSIngo Molnar
592cae2ed9aSIngo Molnar #define E() \
593cae2ed9aSIngo Molnar \
594cae2ed9aSIngo Molnar LOCK_UNLOCK_2(A, B); \
595cae2ed9aSIngo Molnar LOCK_UNLOCK_2(C, A); \
596cae2ed9aSIngo Molnar LOCK_UNLOCK_2(B, C); /* fail */
597cae2ed9aSIngo Molnar
598cae2ed9aSIngo Molnar /*
599cae2ed9aSIngo Molnar * 6 testcases:
600cae2ed9aSIngo Molnar */
601cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
602cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_spin)
603cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
604cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_wlock)
605cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
606cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_rlock)
607cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
608cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_mutex)
609cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
610cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_wsem)
611cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
612cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCABC_rsem)
613cae2ed9aSIngo Molnar
614018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
615018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
616018956d6SPeter Zijlstra GENERATE_TESTCASE(ABCABC_rtmutex);
617018956d6SPeter Zijlstra #endif
618018956d6SPeter Zijlstra
619cae2ed9aSIngo Molnar #undef E
620cae2ed9aSIngo Molnar
621cae2ed9aSIngo Molnar /*
622cae2ed9aSIngo Molnar * AB BC CD DA deadlock:
623cae2ed9aSIngo Molnar */
624cae2ed9aSIngo Molnar
625cae2ed9aSIngo Molnar #define E() \
626cae2ed9aSIngo Molnar \
627cae2ed9aSIngo Molnar LOCK_UNLOCK_2(A, B); \
628cae2ed9aSIngo Molnar LOCK_UNLOCK_2(B, C); \
629cae2ed9aSIngo Molnar LOCK_UNLOCK_2(C, D); \
630cae2ed9aSIngo Molnar LOCK_UNLOCK_2(D, A); /* fail */
631cae2ed9aSIngo Molnar
632cae2ed9aSIngo Molnar /*
633cae2ed9aSIngo Molnar * 6 testcases:
634cae2ed9aSIngo Molnar */
635cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
636cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_spin)
637cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
638cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_wlock)
639cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
640cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_rlock)
641cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
642cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_mutex)
643cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
644cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_wsem)
645cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
646cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABBCCDDA_rsem)
647cae2ed9aSIngo Molnar
648018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
649018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
650018956d6SPeter Zijlstra GENERATE_TESTCASE(ABBCCDDA_rtmutex);
651018956d6SPeter Zijlstra #endif
652018956d6SPeter Zijlstra
653cae2ed9aSIngo Molnar #undef E
654cae2ed9aSIngo Molnar
655cae2ed9aSIngo Molnar /*
656cae2ed9aSIngo Molnar * AB CD BD DA deadlock:
657cae2ed9aSIngo Molnar */
658cae2ed9aSIngo Molnar #define E() \
659cae2ed9aSIngo Molnar \
660cae2ed9aSIngo Molnar LOCK_UNLOCK_2(A, B); \
661cae2ed9aSIngo Molnar LOCK_UNLOCK_2(C, D); \
662cae2ed9aSIngo Molnar LOCK_UNLOCK_2(B, D); \
663cae2ed9aSIngo Molnar LOCK_UNLOCK_2(D, A); /* fail */
664cae2ed9aSIngo Molnar
665cae2ed9aSIngo Molnar /*
666cae2ed9aSIngo Molnar * 6 testcases:
667cae2ed9aSIngo Molnar */
668cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
669cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_spin)
670cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
671cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_wlock)
672cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
673cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_rlock)
674cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
675cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_mutex)
676cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
677cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_wsem)
678cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
679cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBDDA_rsem)
680cae2ed9aSIngo Molnar
681018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
682018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
683018956d6SPeter Zijlstra GENERATE_TESTCASE(ABCDBDDA_rtmutex);
684018956d6SPeter Zijlstra #endif
685018956d6SPeter Zijlstra
686cae2ed9aSIngo Molnar #undef E
687cae2ed9aSIngo Molnar
688cae2ed9aSIngo Molnar /*
689cae2ed9aSIngo Molnar * AB CD BC DA deadlock:
690cae2ed9aSIngo Molnar */
691cae2ed9aSIngo Molnar #define E() \
692cae2ed9aSIngo Molnar \
693cae2ed9aSIngo Molnar LOCK_UNLOCK_2(A, B); \
694cae2ed9aSIngo Molnar LOCK_UNLOCK_2(C, D); \
695cae2ed9aSIngo Molnar LOCK_UNLOCK_2(B, C); \
696cae2ed9aSIngo Molnar LOCK_UNLOCK_2(D, A); /* fail */
697cae2ed9aSIngo Molnar
698cae2ed9aSIngo Molnar /*
699cae2ed9aSIngo Molnar * 6 testcases:
700cae2ed9aSIngo Molnar */
701cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
702cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_spin)
703cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
704cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_wlock)
705cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
706cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_rlock)
707cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
708cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_mutex)
709cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
710cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_wsem)
711cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
712cae2ed9aSIngo Molnar GENERATE_TESTCASE(ABCDBCDA_rsem)
713cae2ed9aSIngo Molnar
714018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
715018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
716018956d6SPeter Zijlstra GENERATE_TESTCASE(ABCDBCDA_rtmutex);
717018956d6SPeter Zijlstra #endif
718018956d6SPeter Zijlstra
719cae2ed9aSIngo Molnar #undef E
720cae2ed9aSIngo Molnar
721512bf713SSebastian Andrzej Siewior #ifdef CONFIG_PREEMPT_RT
722512bf713SSebastian Andrzej Siewior # define RT_PREPARE_DBL_UNLOCK() { migrate_disable(); rcu_read_lock(); }
723512bf713SSebastian Andrzej Siewior #else
724512bf713SSebastian Andrzej Siewior # define RT_PREPARE_DBL_UNLOCK()
725512bf713SSebastian Andrzej Siewior #endif
726cae2ed9aSIngo Molnar /*
727cae2ed9aSIngo Molnar * Double unlock:
728cae2ed9aSIngo Molnar */
729cae2ed9aSIngo Molnar #define E() \
730cae2ed9aSIngo Molnar \
731cae2ed9aSIngo Molnar LOCK(A); \
732512bf713SSebastian Andrzej Siewior RT_PREPARE_DBL_UNLOCK(); \
733cae2ed9aSIngo Molnar UNLOCK(A); \
734cae2ed9aSIngo Molnar UNLOCK(A); /* fail */
735cae2ed9aSIngo Molnar
736cae2ed9aSIngo Molnar /*
737cae2ed9aSIngo Molnar * 6 testcases:
738cae2ed9aSIngo Molnar */
739cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
740cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_spin)
741cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
742cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_wlock)
743cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
744cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_rlock)
745cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
746cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_mutex)
747cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
748cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_wsem)
749cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
750cae2ed9aSIngo Molnar GENERATE_TESTCASE(double_unlock_rsem)
751cae2ed9aSIngo Molnar
752018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
753018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
754018956d6SPeter Zijlstra GENERATE_TESTCASE(double_unlock_rtmutex);
755018956d6SPeter Zijlstra #endif
756018956d6SPeter Zijlstra
757cae2ed9aSIngo Molnar #undef E
758cae2ed9aSIngo Molnar
759cae2ed9aSIngo Molnar /*
760cae2ed9aSIngo Molnar * initializing a held lock:
761cae2ed9aSIngo Molnar */
762cae2ed9aSIngo Molnar #define E() \
763cae2ed9aSIngo Molnar \
764cae2ed9aSIngo Molnar LOCK(A); \
765cae2ed9aSIngo Molnar INIT(A); /* fail */
766cae2ed9aSIngo Molnar
767cae2ed9aSIngo Molnar /*
768cae2ed9aSIngo Molnar * 6 testcases:
769cae2ed9aSIngo Molnar */
770cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
771cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_spin)
772cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
773cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_wlock)
774cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
775cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_rlock)
776cae2ed9aSIngo Molnar #include "locking-selftest-mutex.h"
777cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_mutex)
778cae2ed9aSIngo Molnar #include "locking-selftest-wsem.h"
779cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_wsem)
780cae2ed9aSIngo Molnar #include "locking-selftest-rsem.h"
781cae2ed9aSIngo Molnar GENERATE_TESTCASE(init_held_rsem)
782cae2ed9aSIngo Molnar
783018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
784018956d6SPeter Zijlstra #include "locking-selftest-rtmutex.h"
785018956d6SPeter Zijlstra GENERATE_TESTCASE(init_held_rtmutex);
786018956d6SPeter Zijlstra #endif
787018956d6SPeter Zijlstra
788cae2ed9aSIngo Molnar #undef E
789cae2ed9aSIngo Molnar
790cae2ed9aSIngo Molnar /*
791cae2ed9aSIngo Molnar * locking an irq-safe lock with irqs enabled:
792cae2ed9aSIngo Molnar */
793cae2ed9aSIngo Molnar #define E1() \
794cae2ed9aSIngo Molnar \
795cae2ed9aSIngo Molnar IRQ_ENTER(); \
796cae2ed9aSIngo Molnar LOCK(A); \
797cae2ed9aSIngo Molnar UNLOCK(A); \
798cae2ed9aSIngo Molnar IRQ_EXIT();
799cae2ed9aSIngo Molnar
800cae2ed9aSIngo Molnar #define E2() \
801cae2ed9aSIngo Molnar \
802cae2ed9aSIngo Molnar LOCK(A); \
803cae2ed9aSIngo Molnar UNLOCK(A);
804cae2ed9aSIngo Molnar
805cae2ed9aSIngo Molnar /*
806cae2ed9aSIngo Molnar * Generate 24 testcases:
807cae2ed9aSIngo Molnar */
808cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
809cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_spin)
810cae2ed9aSIngo Molnar
811cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_rlock)812cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_rlock)
813cae2ed9aSIngo Molnar
814cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
815cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_wlock)
816cae2ed9aSIngo Molnar
817a529f8dbSSebastian Andrzej Siewior #ifndef CONFIG_PREEMPT_RT
818cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
819cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_spin)
820cae2ed9aSIngo Molnar
821cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
822cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_rlock)
823cae2ed9aSIngo Molnar
824cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
825cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_wlock)
826a529f8dbSSebastian Andrzej Siewior #endif
827cae2ed9aSIngo Molnar
828cae2ed9aSIngo Molnar #undef E1
829cae2ed9aSIngo Molnar #undef E2
830cae2ed9aSIngo Molnar
831a529f8dbSSebastian Andrzej Siewior #ifndef CONFIG_PREEMPT_RT
832cae2ed9aSIngo Molnar /*
833cae2ed9aSIngo Molnar * Enabling hardirqs with a softirq-safe lock held:
834cae2ed9aSIngo Molnar */
835cae2ed9aSIngo Molnar #define E1() \
836cae2ed9aSIngo Molnar \
837cae2ed9aSIngo Molnar SOFTIRQ_ENTER(); \
838cae2ed9aSIngo Molnar LOCK(A); \
839cae2ed9aSIngo Molnar UNLOCK(A); \
840cae2ed9aSIngo Molnar SOFTIRQ_EXIT();
841cae2ed9aSIngo Molnar
842cae2ed9aSIngo Molnar #define E2() \
843cae2ed9aSIngo Molnar \
844cae2ed9aSIngo Molnar HARDIRQ_DISABLE(); \
845cae2ed9aSIngo Molnar LOCK(A); \
846cae2ed9aSIngo Molnar HARDIRQ_ENABLE(); \
847cae2ed9aSIngo Molnar UNLOCK(A);
848cae2ed9aSIngo Molnar
849cae2ed9aSIngo Molnar /*
850cae2ed9aSIngo Molnar * Generate 12 testcases:
851cae2ed9aSIngo Molnar */
852cae2ed9aSIngo Molnar #include "locking-selftest-spin.h"
853cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_spin)
854cae2ed9aSIngo Molnar
855cae2ed9aSIngo Molnar #include "locking-selftest-wlock.h"
856cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_wlock)
857cae2ed9aSIngo Molnar
858cae2ed9aSIngo Molnar #include "locking-selftest-rlock.h"
859cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_rlock)
860cae2ed9aSIngo Molnar
861cae2ed9aSIngo Molnar #undef E1
862cae2ed9aSIngo Molnar #undef E2
863cae2ed9aSIngo Molnar
864a529f8dbSSebastian Andrzej Siewior #endif
865a529f8dbSSebastian Andrzej Siewior
866cae2ed9aSIngo Molnar /*
867cae2ed9aSIngo Molnar * Enabling irqs with an irq-safe lock held:
868cae2ed9aSIngo Molnar */
869cae2ed9aSIngo Molnar #define E1() \
870cae2ed9aSIngo Molnar \
871cae2ed9aSIngo Molnar IRQ_ENTER(); \
872cae2ed9aSIngo Molnar LOCK(A); \
873cae2ed9aSIngo Molnar UNLOCK(A); \
874cae2ed9aSIngo Molnar IRQ_EXIT();
875cae2ed9aSIngo Molnar
876cae2ed9aSIngo Molnar #define E2() \
877cae2ed9aSIngo Molnar \
878cae2ed9aSIngo Molnar IRQ_DISABLE(); \
879cae2ed9aSIngo Molnar LOCK(A); \
880cae2ed9aSIngo Molnar IRQ_ENABLE(); \
881cae2ed9aSIngo Molnar UNLOCK(A);
882cae2ed9aSIngo Molnar
883cae2ed9aSIngo Molnar /*
884cae2ed9aSIngo Molnar * Generate 24 testcases:
885cae2ed9aSIngo Molnar */
886cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
887cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_spin)
888cae2ed9aSIngo Molnar
889cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
890cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_rlock)
891cae2ed9aSIngo Molnar
892cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
893cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_wlock)
894cae2ed9aSIngo Molnar
895a529f8dbSSebastian Andrzej Siewior #ifndef CONFIG_PREEMPT_RT
896cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
897cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_spin)
898cae2ed9aSIngo Molnar
899cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
900cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_rlock)
901cae2ed9aSIngo Molnar
902cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
903cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock)
904a529f8dbSSebastian Andrzej Siewior #endif
905cae2ed9aSIngo Molnar
906cae2ed9aSIngo Molnar #undef E1
907cae2ed9aSIngo Molnar #undef E2
908cae2ed9aSIngo Molnar
909cae2ed9aSIngo Molnar /*
910cae2ed9aSIngo Molnar * Acquiring a irq-unsafe lock while holding an irq-safe-lock:
911cae2ed9aSIngo Molnar */
912cae2ed9aSIngo Molnar #define E1() \
913cae2ed9aSIngo Molnar \
914cae2ed9aSIngo Molnar LOCK(A); \
915cae2ed9aSIngo Molnar LOCK(B); \
916cae2ed9aSIngo Molnar UNLOCK(B); \
917cae2ed9aSIngo Molnar UNLOCK(A); \
918cae2ed9aSIngo Molnar
919cae2ed9aSIngo Molnar #define E2() \
920cae2ed9aSIngo Molnar \
921cae2ed9aSIngo Molnar LOCK(B); \
922cae2ed9aSIngo Molnar UNLOCK(B);
923cae2ed9aSIngo Molnar
924cae2ed9aSIngo Molnar #define E3() \
925cae2ed9aSIngo Molnar \
926cae2ed9aSIngo Molnar IRQ_ENTER(); \
927cae2ed9aSIngo Molnar LOCK(A); \
928cae2ed9aSIngo Molnar UNLOCK(A); \
929cae2ed9aSIngo Molnar IRQ_EXIT();
930cae2ed9aSIngo Molnar
931cae2ed9aSIngo Molnar /*
932cae2ed9aSIngo Molnar * Generate 36 testcases:
933cae2ed9aSIngo Molnar */
934cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
935cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_spin)
936cae2ed9aSIngo Molnar
937cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
938cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_rlock)
939cae2ed9aSIngo Molnar
940cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
941cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_wlock)
942cae2ed9aSIngo Molnar
943a529f8dbSSebastian Andrzej Siewior #ifndef CONFIG_PREEMPT_RT
944cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
945cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_spin)
946cae2ed9aSIngo Molnar
947cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
948cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_rlock)
949cae2ed9aSIngo Molnar
950cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
951cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock)
952a529f8dbSSebastian Andrzej Siewior #endif
953cae2ed9aSIngo Molnar
954cae2ed9aSIngo Molnar #undef E1
955cae2ed9aSIngo Molnar #undef E2
956cae2ed9aSIngo Molnar #undef E3
957cae2ed9aSIngo Molnar
958cae2ed9aSIngo Molnar /*
959cae2ed9aSIngo Molnar * If a lock turns into softirq-safe, but earlier it took
960cae2ed9aSIngo Molnar * a softirq-unsafe lock:
961cae2ed9aSIngo Molnar */
962cae2ed9aSIngo Molnar
963cae2ed9aSIngo Molnar #define E1() \
964cae2ed9aSIngo Molnar IRQ_DISABLE(); \
965cae2ed9aSIngo Molnar LOCK(A); \
966cae2ed9aSIngo Molnar LOCK(B); \
967cae2ed9aSIngo Molnar UNLOCK(B); \
968cae2ed9aSIngo Molnar UNLOCK(A); \
969cae2ed9aSIngo Molnar IRQ_ENABLE();
970cae2ed9aSIngo Molnar
971cae2ed9aSIngo Molnar #define E2() \
972cae2ed9aSIngo Molnar LOCK(B); \
973cae2ed9aSIngo Molnar UNLOCK(B);
974cae2ed9aSIngo Molnar
975cae2ed9aSIngo Molnar #define E3() \
976cae2ed9aSIngo Molnar IRQ_ENTER(); \
977cae2ed9aSIngo Molnar LOCK(A); \
978cae2ed9aSIngo Molnar UNLOCK(A); \
979cae2ed9aSIngo Molnar IRQ_EXIT();
980cae2ed9aSIngo Molnar
981cae2ed9aSIngo Molnar /*
982cae2ed9aSIngo Molnar * Generate 36 testcases:
983cae2ed9aSIngo Molnar */
984cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
985cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_spin)
986cae2ed9aSIngo Molnar
987cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
988cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_rlock)
989cae2ed9aSIngo Molnar
990cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
991cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_wlock)
992cae2ed9aSIngo Molnar
993a529f8dbSSebastian Andrzej Siewior #ifndef CONFIG_PREEMPT_RT
994cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
995cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_spin)
996cae2ed9aSIngo Molnar
997cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
998cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_rlock)
999cae2ed9aSIngo Molnar
1000cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
1001cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_wlock)
1002a529f8dbSSebastian Andrzej Siewior #endif
1003cae2ed9aSIngo Molnar
1004cae2ed9aSIngo Molnar #undef E1
1005cae2ed9aSIngo Molnar #undef E2
1006cae2ed9aSIngo Molnar #undef E3
1007cae2ed9aSIngo Molnar
1008cae2ed9aSIngo Molnar /*
1009cae2ed9aSIngo Molnar * read-lock / write-lock irq inversion.
1010cae2ed9aSIngo Molnar *
1011cae2ed9aSIngo Molnar * Deadlock scenario:
1012cae2ed9aSIngo Molnar *
1013cae2ed9aSIngo Molnar * CPU#1 is at #1, i.e. it has write-locked A, but has not
1014cae2ed9aSIngo Molnar * taken B yet.
1015cae2ed9aSIngo Molnar *
1016cae2ed9aSIngo Molnar * CPU#2 is at #2, i.e. it has locked B.
1017cae2ed9aSIngo Molnar *
1018cae2ed9aSIngo Molnar * Hardirq hits CPU#2 at point #2 and is trying to read-lock A.
1019cae2ed9aSIngo Molnar *
1020cae2ed9aSIngo Molnar * The deadlock occurs because CPU#1 will spin on B, and CPU#2
1021cae2ed9aSIngo Molnar * will spin on A.
1022cae2ed9aSIngo Molnar */
1023cae2ed9aSIngo Molnar
1024cae2ed9aSIngo Molnar #define E1() \
1025cae2ed9aSIngo Molnar \
1026cae2ed9aSIngo Molnar IRQ_DISABLE(); \
1027cae2ed9aSIngo Molnar WL(A); \
1028cae2ed9aSIngo Molnar LOCK(B); \
1029cae2ed9aSIngo Molnar UNLOCK(B); \
1030cae2ed9aSIngo Molnar WU(A); \
1031cae2ed9aSIngo Molnar IRQ_ENABLE();
1032cae2ed9aSIngo Molnar
1033cae2ed9aSIngo Molnar #define E2() \
1034cae2ed9aSIngo Molnar \
1035cae2ed9aSIngo Molnar LOCK(B); \
1036cae2ed9aSIngo Molnar UNLOCK(B);
1037cae2ed9aSIngo Molnar
1038cae2ed9aSIngo Molnar #define E3() \
1039cae2ed9aSIngo Molnar \
1040cae2ed9aSIngo Molnar IRQ_ENTER(); \
1041cae2ed9aSIngo Molnar RL(A); \
1042cae2ed9aSIngo Molnar RU(A); \
1043cae2ed9aSIngo Molnar IRQ_EXIT();
1044cae2ed9aSIngo Molnar
1045cae2ed9aSIngo Molnar /*
1046cae2ed9aSIngo Molnar * Generate 36 testcases:
1047cae2ed9aSIngo Molnar */
1048cae2ed9aSIngo Molnar #include "locking-selftest-spin-hardirq.h"
1049cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_spin)
1050cae2ed9aSIngo Molnar
1051cae2ed9aSIngo Molnar #include "locking-selftest-rlock-hardirq.h"
1052cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_rlock)
1053cae2ed9aSIngo Molnar
1054cae2ed9aSIngo Molnar #include "locking-selftest-wlock-hardirq.h"
1055cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_wlock)
1056cae2ed9aSIngo Molnar
1057a529f8dbSSebastian Andrzej Siewior #ifndef CONFIG_PREEMPT_RT
1058cae2ed9aSIngo Molnar #include "locking-selftest-spin-softirq.h"
1059cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_spin)
1060cae2ed9aSIngo Molnar
1061cae2ed9aSIngo Molnar #include "locking-selftest-rlock-softirq.h"
1062cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_rlock)
1063cae2ed9aSIngo Molnar
1064cae2ed9aSIngo Molnar #include "locking-selftest-wlock-softirq.h"
1065cae2ed9aSIngo Molnar GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_wlock)
1066a529f8dbSSebastian Andrzej Siewior #endif
1067cae2ed9aSIngo Molnar
1068cae2ed9aSIngo Molnar #undef E1
1069cae2ed9aSIngo Molnar #undef E2
1070cae2ed9aSIngo Molnar #undef E3
1071cae2ed9aSIngo Molnar
1072cae2ed9aSIngo Molnar /*
10738ef7ca75SBoqun Feng * write-read / write-read / write-read deadlock even if read is recursive
10748ef7ca75SBoqun Feng */
10758ef7ca75SBoqun Feng
10768ef7ca75SBoqun Feng #define E1() \
10778ef7ca75SBoqun Feng \
10788ef7ca75SBoqun Feng WL(X1); \
10798ef7ca75SBoqun Feng RL(Y1); \
10808ef7ca75SBoqun Feng RU(Y1); \
10818ef7ca75SBoqun Feng WU(X1);
10828ef7ca75SBoqun Feng
10838ef7ca75SBoqun Feng #define E2() \
10848ef7ca75SBoqun Feng \
10858ef7ca75SBoqun Feng WL(Y1); \
10868ef7ca75SBoqun Feng RL(Z1); \
10878ef7ca75SBoqun Feng RU(Z1); \
10888ef7ca75SBoqun Feng WU(Y1);
10898ef7ca75SBoqun Feng
10908ef7ca75SBoqun Feng #define E3() \
10918ef7ca75SBoqun Feng \
10928ef7ca75SBoqun Feng WL(Z1); \
10938ef7ca75SBoqun Feng RL(X1); \
10948ef7ca75SBoqun Feng RU(X1); \
10958ef7ca75SBoqun Feng WU(Z1);
10968ef7ca75SBoqun Feng
10978ef7ca75SBoqun Feng #include "locking-selftest-rlock.h"
10988ef7ca75SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(W1R2_W2R3_W3R1)
10998ef7ca75SBoqun Feng
11008ef7ca75SBoqun Feng #undef E1
11018ef7ca75SBoqun Feng #undef E2
11028ef7ca75SBoqun Feng #undef E3
11038ef7ca75SBoqun Feng
11048ef7ca75SBoqun Feng /*
11058ef7ca75SBoqun Feng * write-write / read-read / write-read deadlock even if read is recursive
11068ef7ca75SBoqun Feng */
11078ef7ca75SBoqun Feng
11088ef7ca75SBoqun Feng #define E1() \
11098ef7ca75SBoqun Feng \
11108ef7ca75SBoqun Feng WL(X1); \
11118ef7ca75SBoqun Feng WL(Y1); \
11128ef7ca75SBoqun Feng WU(Y1); \
11138ef7ca75SBoqun Feng WU(X1);
11148ef7ca75SBoqun Feng
11158ef7ca75SBoqun Feng #define E2() \
11168ef7ca75SBoqun Feng \
11178ef7ca75SBoqun Feng RL(Y1); \
11188ef7ca75SBoqun Feng RL(Z1); \
11198ef7ca75SBoqun Feng RU(Z1); \
11208ef7ca75SBoqun Feng RU(Y1);
11218ef7ca75SBoqun Feng
11228ef7ca75SBoqun Feng #define E3() \
11238ef7ca75SBoqun Feng \
11248ef7ca75SBoqun Feng WL(Z1); \
11258ef7ca75SBoqun Feng RL(X1); \
11268ef7ca75SBoqun Feng RU(X1); \
11278ef7ca75SBoqun Feng WU(Z1);
11288ef7ca75SBoqun Feng
11298ef7ca75SBoqun Feng #include "locking-selftest-rlock.h"
11308ef7ca75SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(W1W2_R2R3_W3R1)
11318ef7ca75SBoqun Feng
11328ef7ca75SBoqun Feng #undef E1
11338ef7ca75SBoqun Feng #undef E2
11348ef7ca75SBoqun Feng #undef E3
11358ef7ca75SBoqun Feng
11368ef7ca75SBoqun Feng /*
11378ef7ca75SBoqun Feng * write-write / read-read / read-write is not deadlock when read is recursive
11388ef7ca75SBoqun Feng */
11398ef7ca75SBoqun Feng
11408ef7ca75SBoqun Feng #define E1() \
11418ef7ca75SBoqun Feng \
11428ef7ca75SBoqun Feng WL(X1); \
11438ef7ca75SBoqun Feng WL(Y1); \
11448ef7ca75SBoqun Feng WU(Y1); \
11458ef7ca75SBoqun Feng WU(X1);
11468ef7ca75SBoqun Feng
11478ef7ca75SBoqun Feng #define E2() \
11488ef7ca75SBoqun Feng \
11498ef7ca75SBoqun Feng RL(Y1); \
11508ef7ca75SBoqun Feng RL(Z1); \
11518ef7ca75SBoqun Feng RU(Z1); \
11528ef7ca75SBoqun Feng RU(Y1);
11538ef7ca75SBoqun Feng
11548ef7ca75SBoqun Feng #define E3() \
11558ef7ca75SBoqun Feng \
11568ef7ca75SBoqun Feng RL(Z1); \
11578ef7ca75SBoqun Feng WL(X1); \
11588ef7ca75SBoqun Feng WU(X1); \
11598ef7ca75SBoqun Feng RU(Z1);
11608ef7ca75SBoqun Feng
11618ef7ca75SBoqun Feng #include "locking-selftest-rlock.h"
11628ef7ca75SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(W1R2_R2R3_W3W1)
11638ef7ca75SBoqun Feng
11648ef7ca75SBoqun Feng #undef E1
11658ef7ca75SBoqun Feng #undef E2
11668ef7ca75SBoqun Feng #undef E3
11678ef7ca75SBoqun Feng
11688ef7ca75SBoqun Feng /*
11698ef7ca75SBoqun Feng * write-read / read-read / write-write is not deadlock when read is recursive
11708ef7ca75SBoqun Feng */
11718ef7ca75SBoqun Feng
11728ef7ca75SBoqun Feng #define E1() \
11738ef7ca75SBoqun Feng \
11748ef7ca75SBoqun Feng WL(X1); \
11758ef7ca75SBoqun Feng RL(Y1); \
11768ef7ca75SBoqun Feng RU(Y1); \
11778ef7ca75SBoqun Feng WU(X1);
11788ef7ca75SBoqun Feng
11798ef7ca75SBoqun Feng #define E2() \
11808ef7ca75SBoqun Feng \
11818ef7ca75SBoqun Feng RL(Y1); \
11828ef7ca75SBoqun Feng RL(Z1); \
11838ef7ca75SBoqun Feng RU(Z1); \
11848ef7ca75SBoqun Feng RU(Y1);
11858ef7ca75SBoqun Feng
11868ef7ca75SBoqun Feng #define E3() \
11878ef7ca75SBoqun Feng \
11888ef7ca75SBoqun Feng WL(Z1); \
11898ef7ca75SBoqun Feng WL(X1); \
11908ef7ca75SBoqun Feng WU(X1); \
11918ef7ca75SBoqun Feng WU(Z1);
11928ef7ca75SBoqun Feng
11938ef7ca75SBoqun Feng #include "locking-selftest-rlock.h"
11948ef7ca75SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(W1W2_R2R3_R3W1)
11958ef7ca75SBoqun Feng
11968ef7ca75SBoqun Feng #undef E1
11978ef7ca75SBoqun Feng #undef E2
11988ef7ca75SBoqun Feng #undef E3
11998ef7ca75SBoqun Feng /*
1200cae2ed9aSIngo Molnar * read-lock / write-lock recursion that is actually safe.
1201cae2ed9aSIngo Molnar */
1202cae2ed9aSIngo Molnar
1203cae2ed9aSIngo Molnar #define E1() \
1204cae2ed9aSIngo Molnar \
1205cae2ed9aSIngo Molnar IRQ_DISABLE(); \
1206cae2ed9aSIngo Molnar WL(A); \
1207cae2ed9aSIngo Molnar WU(A); \
1208cae2ed9aSIngo Molnar IRQ_ENABLE();
1209cae2ed9aSIngo Molnar
1210cae2ed9aSIngo Molnar #define E2() \
1211cae2ed9aSIngo Molnar \
1212cae2ed9aSIngo Molnar RL(A); \
1213cae2ed9aSIngo Molnar RU(A); \
1214cae2ed9aSIngo Molnar
1215cae2ed9aSIngo Molnar #define E3() \
1216cae2ed9aSIngo Molnar \
1217cae2ed9aSIngo Molnar IRQ_ENTER(); \
121831e0d747SBoqun Feng LOCK(A); \
1219cae2ed9aSIngo Molnar L(B); \
1220cae2ed9aSIngo Molnar U(B); \
122131e0d747SBoqun Feng UNLOCK(A); \
1222cae2ed9aSIngo Molnar IRQ_EXIT();
1223cae2ed9aSIngo Molnar
1224cae2ed9aSIngo Molnar /*
122531e0d747SBoqun Feng * Generate 24 testcases:
1226cae2ed9aSIngo Molnar */
1227cae2ed9aSIngo Molnar #include "locking-selftest-hardirq.h"
122831e0d747SBoqun Feng #include "locking-selftest-rlock.h"
122931e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard_rlock)
123031e0d747SBoqun Feng
123131e0d747SBoqun Feng #include "locking-selftest-wlock.h"
123231e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard_wlock)
1233cae2ed9aSIngo Molnar
1234a529f8dbSSebastian Andrzej Siewior #ifndef CONFIG_PREEMPT_RT
1235cae2ed9aSIngo Molnar #include "locking-selftest-softirq.h"
123631e0d747SBoqun Feng #include "locking-selftest-rlock.h"
123731e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft_rlock)
123831e0d747SBoqun Feng
123931e0d747SBoqun Feng #include "locking-selftest-wlock.h"
124031e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft_wlock)
1241a529f8dbSSebastian Andrzej Siewior #endif
1242cae2ed9aSIngo Molnar
1243cae2ed9aSIngo Molnar #undef E1
1244cae2ed9aSIngo Molnar #undef E2
1245cae2ed9aSIngo Molnar #undef E3
1246cae2ed9aSIngo Molnar
1247cae2ed9aSIngo Molnar /*
1248cae2ed9aSIngo Molnar * read-lock / write-lock recursion that is unsafe.
1249cae2ed9aSIngo Molnar */
1250cae2ed9aSIngo Molnar
1251cae2ed9aSIngo Molnar #define E1() \
1252cae2ed9aSIngo Molnar \
1253cae2ed9aSIngo Molnar IRQ_DISABLE(); \
1254cae2ed9aSIngo Molnar L(B); \
125531e0d747SBoqun Feng LOCK(A); \
125631e0d747SBoqun Feng UNLOCK(A); \
1257cae2ed9aSIngo Molnar U(B); \
1258cae2ed9aSIngo Molnar IRQ_ENABLE();
1259cae2ed9aSIngo Molnar
1260cae2ed9aSIngo Molnar #define E2() \
1261cae2ed9aSIngo Molnar \
1262cae2ed9aSIngo Molnar RL(A); \
1263cae2ed9aSIngo Molnar RU(A); \
1264cae2ed9aSIngo Molnar
1265cae2ed9aSIngo Molnar #define E3() \
1266cae2ed9aSIngo Molnar \
1267cae2ed9aSIngo Molnar IRQ_ENTER(); \
1268cae2ed9aSIngo Molnar L(B); \
1269cae2ed9aSIngo Molnar U(B); \
1270cae2ed9aSIngo Molnar IRQ_EXIT();
1271cae2ed9aSIngo Molnar
1272cae2ed9aSIngo Molnar /*
127331e0d747SBoqun Feng * Generate 24 testcases:
1274cae2ed9aSIngo Molnar */
1275cae2ed9aSIngo Molnar #include "locking-selftest-hardirq.h"
127631e0d747SBoqun Feng #include "locking-selftest-rlock.h"
127731e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard_rlock)
127831e0d747SBoqun Feng
127931e0d747SBoqun Feng #include "locking-selftest-wlock.h"
128031e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard_wlock)
1281cae2ed9aSIngo Molnar
1282a529f8dbSSebastian Andrzej Siewior #ifndef CONFIG_PREEMPT_RT
1283cae2ed9aSIngo Molnar #include "locking-selftest-softirq.h"
128431e0d747SBoqun Feng #include "locking-selftest-rlock.h"
128531e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft_rlock)
128631e0d747SBoqun Feng
128731e0d747SBoqun Feng #include "locking-selftest-wlock.h"
128831e0d747SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft_wlock)
1289a529f8dbSSebastian Andrzej Siewior #endif
1290cae2ed9aSIngo Molnar
129196a16f45SBoqun Feng #undef E1
129296a16f45SBoqun Feng #undef E2
129396a16f45SBoqun Feng #undef E3
129496a16f45SBoqun Feng /*
129596a16f45SBoqun Feng * read-lock / write-lock recursion that is unsafe.
129696a16f45SBoqun Feng *
129796a16f45SBoqun Feng * A is a ENABLED_*_READ lock
129896a16f45SBoqun Feng * B is a USED_IN_*_READ lock
129996a16f45SBoqun Feng *
130096a16f45SBoqun Feng * read_lock(A);
130196a16f45SBoqun Feng * write_lock(B);
130296a16f45SBoqun Feng * <interrupt>
130396a16f45SBoqun Feng * read_lock(B);
130496a16f45SBoqun Feng * write_lock(A); // if this one is read_lock(), no deadlock
130596a16f45SBoqun Feng */
130696a16f45SBoqun Feng
130796a16f45SBoqun Feng #define E1() \
130896a16f45SBoqun Feng \
130996a16f45SBoqun Feng IRQ_DISABLE(); \
131096a16f45SBoqun Feng WL(B); \
131196a16f45SBoqun Feng LOCK(A); \
131296a16f45SBoqun Feng UNLOCK(A); \
131396a16f45SBoqun Feng WU(B); \
131496a16f45SBoqun Feng IRQ_ENABLE();
131596a16f45SBoqun Feng
131696a16f45SBoqun Feng #define E2() \
131796a16f45SBoqun Feng \
131896a16f45SBoqun Feng RL(A); \
131996a16f45SBoqun Feng RU(A); \
132096a16f45SBoqun Feng
132196a16f45SBoqun Feng #define E3() \
132296a16f45SBoqun Feng \
132396a16f45SBoqun Feng IRQ_ENTER(); \
132496a16f45SBoqun Feng RL(B); \
132596a16f45SBoqun Feng RU(B); \
132696a16f45SBoqun Feng IRQ_EXIT();
132796a16f45SBoqun Feng
132896a16f45SBoqun Feng /*
132996a16f45SBoqun Feng * Generate 24 testcases:
133096a16f45SBoqun Feng */
133196a16f45SBoqun Feng #include "locking-selftest-hardirq.h"
133296a16f45SBoqun Feng #include "locking-selftest-rlock.h"
133396a16f45SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_hard_rlock)
133496a16f45SBoqun Feng
133596a16f45SBoqun Feng #include "locking-selftest-wlock.h"
133696a16f45SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_hard_wlock)
133796a16f45SBoqun Feng
1338a529f8dbSSebastian Andrzej Siewior #ifndef CONFIG_PREEMPT_RT
133996a16f45SBoqun Feng #include "locking-selftest-softirq.h"
134096a16f45SBoqun Feng #include "locking-selftest-rlock.h"
134196a16f45SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_soft_rlock)
134296a16f45SBoqun Feng
134396a16f45SBoqun Feng #include "locking-selftest-wlock.h"
134496a16f45SBoqun Feng GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_soft_wlock)
1345a529f8dbSSebastian Andrzej Siewior #endif
134696a16f45SBoqun Feng
1347cae2ed9aSIngo Molnar #ifdef CONFIG_DEBUG_LOCK_ALLOC
1348cae2ed9aSIngo Molnar # define I_SPINLOCK(x) lockdep_reset_lock(&lock_##x.dep_map)
13499271a40dSBoqun Feng # define I_RAW_SPINLOCK(x) lockdep_reset_lock(&raw_lock_##x.dep_map)
1350cae2ed9aSIngo Molnar # define I_RWLOCK(x) lockdep_reset_lock(&rwlock_##x.dep_map)
1351cae2ed9aSIngo Molnar # define I_MUTEX(x) lockdep_reset_lock(&mutex_##x.dep_map)
1352cae2ed9aSIngo Molnar # define I_RWSEM(x) lockdep_reset_lock(&rwsem_##x.dep_map)
13531de99445SMaarten Lankhorst # define I_WW(x) lockdep_reset_lock(&x.dep_map)
1354fc78dd08SSebastian Andrzej Siewior # define I_LOCAL_LOCK(x) lockdep_reset_lock(this_cpu_ptr(&local_##x.dep_map))
1355018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
1356018956d6SPeter Zijlstra # define I_RTMUTEX(x) lockdep_reset_lock(&rtmutex_##x.dep_map)
1357018956d6SPeter Zijlstra #endif
1358cae2ed9aSIngo Molnar #else
1359cae2ed9aSIngo Molnar # define I_SPINLOCK(x)
13609271a40dSBoqun Feng # define I_RAW_SPINLOCK(x)
1361cae2ed9aSIngo Molnar # define I_RWLOCK(x)
1362cae2ed9aSIngo Molnar # define I_MUTEX(x)
1363cae2ed9aSIngo Molnar # define I_RWSEM(x)
13641de99445SMaarten Lankhorst # define I_WW(x)
13657e923e6aSPeter Zijlstra # define I_LOCAL_LOCK(x)
1366cae2ed9aSIngo Molnar #endif
1367cae2ed9aSIngo Molnar
1368018956d6SPeter Zijlstra #ifndef I_RTMUTEX
1369018956d6SPeter Zijlstra # define I_RTMUTEX(x)
1370018956d6SPeter Zijlstra #endif
1371018956d6SPeter Zijlstra
1372018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
1373018956d6SPeter Zijlstra #define I2_RTMUTEX(x) rt_mutex_init(&rtmutex_##x)
1374018956d6SPeter Zijlstra #else
1375018956d6SPeter Zijlstra #define I2_RTMUTEX(x)
1376018956d6SPeter Zijlstra #endif
1377018956d6SPeter Zijlstra
1378cae2ed9aSIngo Molnar #define I1(x) \
1379cae2ed9aSIngo Molnar do { \
1380cae2ed9aSIngo Molnar I_SPINLOCK(x); \
1381cae2ed9aSIngo Molnar I_RWLOCK(x); \
1382cae2ed9aSIngo Molnar I_MUTEX(x); \
1383cae2ed9aSIngo Molnar I_RWSEM(x); \
1384018956d6SPeter Zijlstra I_RTMUTEX(x); \
1385cae2ed9aSIngo Molnar } while (0)
1386cae2ed9aSIngo Molnar
1387cae2ed9aSIngo Molnar #define I2(x) \
1388cae2ed9aSIngo Molnar do { \
1389a2e9ae58SPeter Zijlstra spin_lock_init(&lock_##x); \
1390cae2ed9aSIngo Molnar rwlock_init(&rwlock_##x); \
1391cae2ed9aSIngo Molnar mutex_init(&mutex_##x); \
1392cae2ed9aSIngo Molnar init_rwsem(&rwsem_##x); \
1393018956d6SPeter Zijlstra I2_RTMUTEX(x); \
1394cae2ed9aSIngo Molnar } while (0)
1395cae2ed9aSIngo Molnar
1396cae2ed9aSIngo Molnar static void reset_locks(void)
1397cae2ed9aSIngo Molnar {
1398cae2ed9aSIngo Molnar local_irq_disable();
13991de99445SMaarten Lankhorst lockdep_free_key_range(&ww_lockdep.acquire_key, 1);
14001de99445SMaarten Lankhorst lockdep_free_key_range(&ww_lockdep.mutex_key, 1);
14011de99445SMaarten Lankhorst
1402cae2ed9aSIngo Molnar I1(A); I1(B); I1(C); I1(D);
1403cae2ed9aSIngo Molnar I1(X1); I1(X2); I1(Y1); I1(Y2); I1(Z1); I1(Z2);
1404f3cf139eSMaarten Lankhorst I_WW(t); I_WW(t2); I_WW(o.base); I_WW(o2.base); I_WW(o3.base);
14059271a40dSBoqun Feng I_RAW_SPINLOCK(A); I_RAW_SPINLOCK(B);
14067e923e6aSPeter Zijlstra I_LOCAL_LOCK(A);
14077e923e6aSPeter Zijlstra
1408cae2ed9aSIngo Molnar lockdep_reset();
14097e923e6aSPeter Zijlstra
1410cae2ed9aSIngo Molnar I2(A); I2(B); I2(C); I2(D);
1411cae2ed9aSIngo Molnar init_shared_classes();
14129271a40dSBoqun Feng raw_spin_lock_init(&raw_lock_A);
14139271a40dSBoqun Feng raw_spin_lock_init(&raw_lock_B);
1414fc78dd08SSebastian Andrzej Siewior local_lock_init(this_cpu_ptr(&local_A));
14151de99445SMaarten Lankhorst
1416f3cf139eSMaarten Lankhorst ww_mutex_init(&o, &ww_lockdep); ww_mutex_init(&o2, &ww_lockdep); ww_mutex_init(&o3, &ww_lockdep);
14171de99445SMaarten Lankhorst memset(&t, 0, sizeof(t)); memset(&t2, 0, sizeof(t2));
14181de99445SMaarten Lankhorst memset(&ww_lockdep.acquire_key, 0, sizeof(ww_lockdep.acquire_key));
14191de99445SMaarten Lankhorst memset(&ww_lockdep.mutex_key, 0, sizeof(ww_lockdep.mutex_key));
1420cae2ed9aSIngo Molnar local_irq_enable();
1421cae2ed9aSIngo Molnar }
1422cae2ed9aSIngo Molnar
1423cae2ed9aSIngo Molnar #undef I
1424cae2ed9aSIngo Molnar
1425cae2ed9aSIngo Molnar static int testcase_total;
1426cae2ed9aSIngo Molnar static int testcase_successes;
1427cae2ed9aSIngo Molnar static int expected_testcase_failures;
1428cae2ed9aSIngo Molnar static int unexpected_testcase_failures;
1429cae2ed9aSIngo Molnar
dotest(void (* testcase_fn)(void),int expected,int lockclass_mask)1430cae2ed9aSIngo Molnar static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask)
1431cae2ed9aSIngo Molnar {
1432512bf713SSebastian Andrzej Siewior int saved_preempt_count = preempt_count();
1433512bf713SSebastian Andrzej Siewior #ifdef CONFIG_PREEMPT_RT
1434512bf713SSebastian Andrzej Siewior #ifdef CONFIG_SMP
1435512bf713SSebastian Andrzej Siewior int saved_mgd_count = current->migration_disabled;
1436512bf713SSebastian Andrzej Siewior #endif
1437512bf713SSebastian Andrzej Siewior int saved_rcu_count = current->rcu_read_lock_nesting;
1438512bf713SSebastian Andrzej Siewior #endif
1439cae2ed9aSIngo Molnar
1440cae2ed9aSIngo Molnar WARN_ON(irqs_disabled());
1441cae2ed9aSIngo Molnar
14425831c0f7SPeter Zijlstra debug_locks_silent = !(debug_locks_verbose & lockclass_mask);
14435831c0f7SPeter Zijlstra
1444cae2ed9aSIngo Molnar testcase_fn();
1445cae2ed9aSIngo Molnar /*
1446cae2ed9aSIngo Molnar * Filter out expected failures:
1447cae2ed9aSIngo Molnar */
14481de99445SMaarten Lankhorst #ifndef CONFIG_PROVE_LOCKING
1449166989e3SMaarten Lankhorst if (expected == FAILURE && debug_locks) {
1450cae2ed9aSIngo Molnar expected_testcase_failures++;
145125139409SMichael Ellerman pr_cont("failed|");
1452166989e3SMaarten Lankhorst }
1453166989e3SMaarten Lankhorst else
1454166989e3SMaarten Lankhorst #endif
1455166989e3SMaarten Lankhorst if (debug_locks != expected) {
1456cae2ed9aSIngo Molnar unexpected_testcase_failures++;
145725139409SMichael Ellerman pr_cont("FAILED|");
1458cae2ed9aSIngo Molnar } else {
1459cae2ed9aSIngo Molnar testcase_successes++;
146025139409SMichael Ellerman pr_cont(" ok |");
1461cae2ed9aSIngo Molnar }
1462cae2ed9aSIngo Molnar testcase_total++;
1463cae2ed9aSIngo Molnar
14645831c0f7SPeter Zijlstra if (debug_locks_verbose & lockclass_mask)
146525139409SMichael Ellerman pr_cont(" lockclass mask: %x, debug_locks: %d, expected: %d\n",
1466cae2ed9aSIngo Molnar lockclass_mask, debug_locks, expected);
1467cae2ed9aSIngo Molnar /*
1468cae2ed9aSIngo Molnar * Some tests (e.g. double-unlock) might corrupt the preemption
1469cae2ed9aSIngo Molnar * count, so restore it:
1470cae2ed9aSIngo Molnar */
14714a2b4b22SPeter Zijlstra preempt_count_set(saved_preempt_count);
1472512bf713SSebastian Andrzej Siewior
1473512bf713SSebastian Andrzej Siewior #ifdef CONFIG_PREEMPT_RT
1474512bf713SSebastian Andrzej Siewior #ifdef CONFIG_SMP
1475512bf713SSebastian Andrzej Siewior while (current->migration_disabled > saved_mgd_count)
1476512bf713SSebastian Andrzej Siewior migrate_enable();
1477512bf713SSebastian Andrzej Siewior #endif
1478512bf713SSebastian Andrzej Siewior
1479512bf713SSebastian Andrzej Siewior while (current->rcu_read_lock_nesting > saved_rcu_count)
1480512bf713SSebastian Andrzej Siewior rcu_read_unlock();
1481512bf713SSebastian Andrzej Siewior WARN_ON_ONCE(current->rcu_read_lock_nesting < saved_rcu_count);
1482512bf713SSebastian Andrzej Siewior #endif
1483512bf713SSebastian Andrzej Siewior
1484cae2ed9aSIngo Molnar #ifdef CONFIG_TRACE_IRQFLAGS
1485cae2ed9aSIngo Molnar if (softirq_count())
1486cae2ed9aSIngo Molnar current->softirqs_enabled = 0;
1487cae2ed9aSIngo Molnar else
1488cae2ed9aSIngo Molnar current->softirqs_enabled = 1;
1489cae2ed9aSIngo Molnar #endif
1490cae2ed9aSIngo Molnar
1491cae2ed9aSIngo Molnar reset_locks();
1492cae2ed9aSIngo Molnar }
1493cae2ed9aSIngo Molnar
1494018956d6SPeter Zijlstra #ifdef CONFIG_RT_MUTEXES
1495018956d6SPeter Zijlstra #define dotest_rt(fn, e, m) dotest((fn), (e), (m))
1496018956d6SPeter Zijlstra #else
1497018956d6SPeter Zijlstra #define dotest_rt(fn, e, m)
1498018956d6SPeter Zijlstra #endif
1499018956d6SPeter Zijlstra
print_testname(const char * testname)1500cae2ed9aSIngo Molnar static inline void print_testname(const char *testname)
1501cae2ed9aSIngo Molnar {
1502cae2ed9aSIngo Molnar printk("%33s:", testname);
1503cae2ed9aSIngo Molnar }
1504cae2ed9aSIngo Molnar
1505cae2ed9aSIngo Molnar #define DO_TESTCASE_1(desc, name, nr) \
1506cae2ed9aSIngo Molnar print_testname(desc"/"#nr); \
1507cae2ed9aSIngo Molnar dotest(name##_##nr, SUCCESS, LOCKTYPE_RWLOCK); \
150825139409SMichael Ellerman pr_cont("\n");
1509cae2ed9aSIngo Molnar
1510cae2ed9aSIngo Molnar #define DO_TESTCASE_1B(desc, name, nr) \
1511cae2ed9aSIngo Molnar print_testname(desc"/"#nr); \
1512cae2ed9aSIngo Molnar dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK); \
151325139409SMichael Ellerman pr_cont("\n");
1514cae2ed9aSIngo Molnar
15158ef7ca75SBoqun Feng #define DO_TESTCASE_1RR(desc, name, nr) \
15168ef7ca75SBoqun Feng print_testname(desc"/"#nr); \
15178ef7ca75SBoqun Feng pr_cont(" |"); \
15188ef7ca75SBoqun Feng dotest(name##_##nr, SUCCESS, LOCKTYPE_RWLOCK); \
15198ef7ca75SBoqun Feng pr_cont("\n");
15208ef7ca75SBoqun Feng
15218ef7ca75SBoqun Feng #define DO_TESTCASE_1RRB(desc, name, nr) \
15228ef7ca75SBoqun Feng print_testname(desc"/"#nr); \
15238ef7ca75SBoqun Feng pr_cont(" |"); \
15248ef7ca75SBoqun Feng dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK); \
15258ef7ca75SBoqun Feng pr_cont("\n");
15268ef7ca75SBoqun Feng
15278ef7ca75SBoqun Feng
1528cae2ed9aSIngo Molnar #define DO_TESTCASE_3(desc, name, nr) \
1529cae2ed9aSIngo Molnar print_testname(desc"/"#nr); \
1530cae2ed9aSIngo Molnar dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN); \
1531cae2ed9aSIngo Molnar dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK); \
1532cae2ed9aSIngo Molnar dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK); \
153325139409SMichael Ellerman pr_cont("\n");
1534cae2ed9aSIngo Molnar
1535cae2ed9aSIngo Molnar #define DO_TESTCASE_3RW(desc, name, nr) \
1536cae2ed9aSIngo Molnar print_testname(desc"/"#nr); \
1537cae2ed9aSIngo Molnar dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN|LOCKTYPE_RWLOCK);\
1538cae2ed9aSIngo Molnar dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK); \
1539cae2ed9aSIngo Molnar dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK); \
154025139409SMichael Ellerman pr_cont("\n");
1541cae2ed9aSIngo Molnar
154231e0d747SBoqun Feng #define DO_TESTCASE_2RW(desc, name, nr) \
154331e0d747SBoqun Feng print_testname(desc"/"#nr); \
154431e0d747SBoqun Feng pr_cont(" |"); \
154531e0d747SBoqun Feng dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK); \
154631e0d747SBoqun Feng dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK); \
154731e0d747SBoqun Feng pr_cont("\n");
154831e0d747SBoqun Feng
154931e0d747SBoqun Feng #define DO_TESTCASE_2x2RW(desc, name, nr) \
155031e0d747SBoqun Feng DO_TESTCASE_2RW("hard-"desc, name##_hard, nr) \
1551a529f8dbSSebastian Andrzej Siewior NON_RT(DO_TESTCASE_2RW("soft-"desc, name##_soft, nr)) \
155231e0d747SBoqun Feng
155331e0d747SBoqun Feng #define DO_TESTCASE_6x2x2RW(desc, name) \
155431e0d747SBoqun Feng DO_TESTCASE_2x2RW(desc, name, 123); \
155531e0d747SBoqun Feng DO_TESTCASE_2x2RW(desc, name, 132); \
155631e0d747SBoqun Feng DO_TESTCASE_2x2RW(desc, name, 213); \
155731e0d747SBoqun Feng DO_TESTCASE_2x2RW(desc, name, 231); \
155831e0d747SBoqun Feng DO_TESTCASE_2x2RW(desc, name, 312); \
155931e0d747SBoqun Feng DO_TESTCASE_2x2RW(desc, name, 321);
156031e0d747SBoqun Feng
1561cae2ed9aSIngo Molnar #define DO_TESTCASE_6(desc, name) \
1562cae2ed9aSIngo Molnar print_testname(desc); \
1563cae2ed9aSIngo Molnar dotest(name##_spin, FAILURE, LOCKTYPE_SPIN); \
1564cae2ed9aSIngo Molnar dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK); \
1565cae2ed9aSIngo Molnar dotest(name##_rlock, FAILURE, LOCKTYPE_RWLOCK); \
1566cae2ed9aSIngo Molnar dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \
1567cae2ed9aSIngo Molnar dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \
1568cae2ed9aSIngo Molnar dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \
1569018956d6SPeter Zijlstra dotest_rt(name##_rtmutex, FAILURE, LOCKTYPE_RTMUTEX); \
157025139409SMichael Ellerman pr_cont("\n");
1571cae2ed9aSIngo Molnar
1572cae2ed9aSIngo Molnar #define DO_TESTCASE_6_SUCCESS(desc, name) \
1573cae2ed9aSIngo Molnar print_testname(desc); \
1574cae2ed9aSIngo Molnar dotest(name##_spin, SUCCESS, LOCKTYPE_SPIN); \
1575cae2ed9aSIngo Molnar dotest(name##_wlock, SUCCESS, LOCKTYPE_RWLOCK); \
1576cae2ed9aSIngo Molnar dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK); \
1577cae2ed9aSIngo Molnar dotest(name##_mutex, SUCCESS, LOCKTYPE_MUTEX); \
1578cae2ed9aSIngo Molnar dotest(name##_wsem, SUCCESS, LOCKTYPE_RWSEM); \
1579cae2ed9aSIngo Molnar dotest(name##_rsem, SUCCESS, LOCKTYPE_RWSEM); \
1580018956d6SPeter Zijlstra dotest_rt(name##_rtmutex, SUCCESS, LOCKTYPE_RTMUTEX); \
158125139409SMichael Ellerman pr_cont("\n");
1582cae2ed9aSIngo Molnar
1583cae2ed9aSIngo Molnar /*
1584cae2ed9aSIngo Molnar * 'read' variant: rlocks must not trigger.
1585cae2ed9aSIngo Molnar */
1586cae2ed9aSIngo Molnar #define DO_TESTCASE_6R(desc, name) \
1587cae2ed9aSIngo Molnar print_testname(desc); \
1588cae2ed9aSIngo Molnar dotest(name##_spin, FAILURE, LOCKTYPE_SPIN); \
1589cae2ed9aSIngo Molnar dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK); \
1590cae2ed9aSIngo Molnar dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK); \
1591cae2ed9aSIngo Molnar dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \
1592cae2ed9aSIngo Molnar dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \
1593cae2ed9aSIngo Molnar dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \
1594018956d6SPeter Zijlstra dotest_rt(name##_rtmutex, FAILURE, LOCKTYPE_RTMUTEX); \
159525139409SMichael Ellerman pr_cont("\n");
1596cae2ed9aSIngo Molnar
1597cae2ed9aSIngo Molnar #define DO_TESTCASE_2I(desc, name, nr) \
1598cae2ed9aSIngo Molnar DO_TESTCASE_1("hard-"desc, name##_hard, nr); \
1599a529f8dbSSebastian Andrzej Siewior NON_RT(DO_TESTCASE_1("soft-"desc, name##_soft, nr));
1600cae2ed9aSIngo Molnar
1601cae2ed9aSIngo Molnar #define DO_TESTCASE_2IB(desc, name, nr) \
1602cae2ed9aSIngo Molnar DO_TESTCASE_1B("hard-"desc, name##_hard, nr); \
1603a529f8dbSSebastian Andrzej Siewior NON_RT(DO_TESTCASE_1B("soft-"desc, name##_soft, nr));
1604cae2ed9aSIngo Molnar
1605cae2ed9aSIngo Molnar #define DO_TESTCASE_6I(desc, name, nr) \
1606cae2ed9aSIngo Molnar DO_TESTCASE_3("hard-"desc, name##_hard, nr); \
1607a529f8dbSSebastian Andrzej Siewior NON_RT(DO_TESTCASE_3("soft-"desc, name##_soft, nr));
1608cae2ed9aSIngo Molnar
1609cae2ed9aSIngo Molnar #define DO_TESTCASE_6IRW(desc, name, nr) \
1610cae2ed9aSIngo Molnar DO_TESTCASE_3RW("hard-"desc, name##_hard, nr); \
1611a529f8dbSSebastian Andrzej Siewior NON_RT(DO_TESTCASE_3RW("soft-"desc, name##_soft, nr));
1612cae2ed9aSIngo Molnar
1613cae2ed9aSIngo Molnar #define DO_TESTCASE_2x3(desc, name) \
1614cae2ed9aSIngo Molnar DO_TESTCASE_3(desc, name, 12); \
1615cae2ed9aSIngo Molnar DO_TESTCASE_3(desc, name, 21);
1616cae2ed9aSIngo Molnar
1617cae2ed9aSIngo Molnar #define DO_TESTCASE_2x6(desc, name) \
1618cae2ed9aSIngo Molnar DO_TESTCASE_6I(desc, name, 12); \
1619cae2ed9aSIngo Molnar DO_TESTCASE_6I(desc, name, 21);
1620cae2ed9aSIngo Molnar
1621cae2ed9aSIngo Molnar #define DO_TESTCASE_6x2(desc, name) \
1622cae2ed9aSIngo Molnar DO_TESTCASE_2I(desc, name, 123); \
1623cae2ed9aSIngo Molnar DO_TESTCASE_2I(desc, name, 132); \
1624cae2ed9aSIngo Molnar DO_TESTCASE_2I(desc, name, 213); \
1625cae2ed9aSIngo Molnar DO_TESTCASE_2I(desc, name, 231); \
1626cae2ed9aSIngo Molnar DO_TESTCASE_2I(desc, name, 312); \
1627cae2ed9aSIngo Molnar DO_TESTCASE_2I(desc, name, 321);
1628cae2ed9aSIngo Molnar
1629cae2ed9aSIngo Molnar #define DO_TESTCASE_6x2B(desc, name) \
1630cae2ed9aSIngo Molnar DO_TESTCASE_2IB(desc, name, 123); \
1631cae2ed9aSIngo Molnar DO_TESTCASE_2IB(desc, name, 132); \
1632cae2ed9aSIngo Molnar DO_TESTCASE_2IB(desc, name, 213); \
1633cae2ed9aSIngo Molnar DO_TESTCASE_2IB(desc, name, 231); \
1634cae2ed9aSIngo Molnar DO_TESTCASE_2IB(desc, name, 312); \
1635cae2ed9aSIngo Molnar DO_TESTCASE_2IB(desc, name, 321);
1636cae2ed9aSIngo Molnar
16378ef7ca75SBoqun Feng #define DO_TESTCASE_6x1RR(desc, name) \
16388ef7ca75SBoqun Feng DO_TESTCASE_1RR(desc, name, 123); \
16398ef7ca75SBoqun Feng DO_TESTCASE_1RR(desc, name, 132); \
16408ef7ca75SBoqun Feng DO_TESTCASE_1RR(desc, name, 213); \
16418ef7ca75SBoqun Feng DO_TESTCASE_1RR(desc, name, 231); \
16428ef7ca75SBoqun Feng DO_TESTCASE_1RR(desc, name, 312); \
16438ef7ca75SBoqun Feng DO_TESTCASE_1RR(desc, name, 321);
16448ef7ca75SBoqun Feng
16458ef7ca75SBoqun Feng #define DO_TESTCASE_6x1RRB(desc, name) \
16468ef7ca75SBoqun Feng DO_TESTCASE_1RRB(desc, name, 123); \
16478ef7ca75SBoqun Feng DO_TESTCASE_1RRB(desc, name, 132); \
16488ef7ca75SBoqun Feng DO_TESTCASE_1RRB(desc, name, 213); \
16498ef7ca75SBoqun Feng DO_TESTCASE_1RRB(desc, name, 231); \
16508ef7ca75SBoqun Feng DO_TESTCASE_1RRB(desc, name, 312); \
16518ef7ca75SBoqun Feng DO_TESTCASE_1RRB(desc, name, 321);
16528ef7ca75SBoqun Feng
1653cae2ed9aSIngo Molnar #define DO_TESTCASE_6x6(desc, name) \
1654cae2ed9aSIngo Molnar DO_TESTCASE_6I(desc, name, 123); \
1655cae2ed9aSIngo Molnar DO_TESTCASE_6I(desc, name, 132); \
1656cae2ed9aSIngo Molnar DO_TESTCASE_6I(desc, name, 213); \
1657cae2ed9aSIngo Molnar DO_TESTCASE_6I(desc, name, 231); \
1658cae2ed9aSIngo Molnar DO_TESTCASE_6I(desc, name, 312); \
1659cae2ed9aSIngo Molnar DO_TESTCASE_6I(desc, name, 321);
1660cae2ed9aSIngo Molnar
1661cae2ed9aSIngo Molnar #define DO_TESTCASE_6x6RW(desc, name) \
1662cae2ed9aSIngo Molnar DO_TESTCASE_6IRW(desc, name, 123); \
1663cae2ed9aSIngo Molnar DO_TESTCASE_6IRW(desc, name, 132); \
1664cae2ed9aSIngo Molnar DO_TESTCASE_6IRW(desc, name, 213); \
1665cae2ed9aSIngo Molnar DO_TESTCASE_6IRW(desc, name, 231); \
1666cae2ed9aSIngo Molnar DO_TESTCASE_6IRW(desc, name, 312); \
1667cae2ed9aSIngo Molnar DO_TESTCASE_6IRW(desc, name, 321);
1668cae2ed9aSIngo Molnar
ww_test_fail_acquire(void)16691de99445SMaarten Lankhorst static void ww_test_fail_acquire(void)
16701de99445SMaarten Lankhorst {
16711de99445SMaarten Lankhorst int ret;
16721de99445SMaarten Lankhorst
16731de99445SMaarten Lankhorst WWAI(&t);
16741de99445SMaarten Lankhorst t.stamp++;
16751de99445SMaarten Lankhorst
16761de99445SMaarten Lankhorst ret = WWL(&o, &t);
16771de99445SMaarten Lankhorst
16781de99445SMaarten Lankhorst if (WARN_ON(!o.ctx) ||
16791de99445SMaarten Lankhorst WARN_ON(ret))
16801de99445SMaarten Lankhorst return;
16811de99445SMaarten Lankhorst
16821de99445SMaarten Lankhorst /* No lockdep test, pure API */
16831de99445SMaarten Lankhorst ret = WWL(&o, &t);
16841de99445SMaarten Lankhorst WARN_ON(ret != -EALREADY);
16851de99445SMaarten Lankhorst
16861de99445SMaarten Lankhorst ret = WWT(&o);
16871de99445SMaarten Lankhorst WARN_ON(ret);
16881de99445SMaarten Lankhorst
16891de99445SMaarten Lankhorst t2 = t;
16901de99445SMaarten Lankhorst t2.stamp++;
16911de99445SMaarten Lankhorst ret = WWL(&o, &t2);
16921de99445SMaarten Lankhorst WARN_ON(ret != -EDEADLK);
16931de99445SMaarten Lankhorst WWU(&o);
16941de99445SMaarten Lankhorst
16951de99445SMaarten Lankhorst if (WWT(&o))
16961de99445SMaarten Lankhorst WWU(&o);
16971de99445SMaarten Lankhorst #ifdef CONFIG_DEBUG_LOCK_ALLOC
16981de99445SMaarten Lankhorst else
16991de99445SMaarten Lankhorst DEBUG_LOCKS_WARN_ON(1);
17001de99445SMaarten Lankhorst #endif
17011de99445SMaarten Lankhorst }
17021de99445SMaarten Lankhorst
17039a75bd0cSSebastian Andrzej Siewior #ifdef CONFIG_PREEMPT_RT
17049a75bd0cSSebastian Andrzej Siewior #define ww_mutex_base_lock(b) rt_mutex_lock(b)
17059a75bd0cSSebastian Andrzej Siewior #define ww_mutex_base_trylock(b) rt_mutex_trylock(b)
17069a75bd0cSSebastian Andrzej Siewior #define ww_mutex_base_lock_nest_lock(b, b2) rt_mutex_lock_nest_lock(b, b2)
17079a75bd0cSSebastian Andrzej Siewior #define ww_mutex_base_lock_interruptible(b) rt_mutex_lock_interruptible(b)
17089a75bd0cSSebastian Andrzej Siewior #define ww_mutex_base_lock_killable(b) rt_mutex_lock_killable(b)
17099a75bd0cSSebastian Andrzej Siewior #define ww_mutex_base_unlock(b) rt_mutex_unlock(b)
17109a75bd0cSSebastian Andrzej Siewior #else
17119a75bd0cSSebastian Andrzej Siewior #define ww_mutex_base_lock(b) mutex_lock(b)
17129a75bd0cSSebastian Andrzej Siewior #define ww_mutex_base_trylock(b) mutex_trylock(b)
17139a75bd0cSSebastian Andrzej Siewior #define ww_mutex_base_lock_nest_lock(b, b2) mutex_lock_nest_lock(b, b2)
17149a75bd0cSSebastian Andrzej Siewior #define ww_mutex_base_lock_interruptible(b) mutex_lock_interruptible(b)
17159a75bd0cSSebastian Andrzej Siewior #define ww_mutex_base_lock_killable(b) mutex_lock_killable(b)
17169a75bd0cSSebastian Andrzej Siewior #define ww_mutex_base_unlock(b) mutex_unlock(b)
17179a75bd0cSSebastian Andrzej Siewior #endif
17189a75bd0cSSebastian Andrzej Siewior
ww_test_normal(void)17192fe3d4b1SMaarten Lankhorst static void ww_test_normal(void)
17202fe3d4b1SMaarten Lankhorst {
17212fe3d4b1SMaarten Lankhorst int ret;
17222fe3d4b1SMaarten Lankhorst
17232fe3d4b1SMaarten Lankhorst WWAI(&t);
17242fe3d4b1SMaarten Lankhorst
17252fe3d4b1SMaarten Lankhorst /*
17262fe3d4b1SMaarten Lankhorst * None of the ww_mutex codepaths should be taken in the 'normal'
17272fe3d4b1SMaarten Lankhorst * mutex calls. The easiest way to verify this is by using the
17282fe3d4b1SMaarten Lankhorst * normal mutex calls, and making sure o.ctx is unmodified.
17292fe3d4b1SMaarten Lankhorst */
17302fe3d4b1SMaarten Lankhorst
17312fe3d4b1SMaarten Lankhorst /* mutex_lock (and indirectly, mutex_lock_nested) */
17322fe3d4b1SMaarten Lankhorst o.ctx = (void *)~0UL;
17339a75bd0cSSebastian Andrzej Siewior ww_mutex_base_lock(&o.base);
17349a75bd0cSSebastian Andrzej Siewior ww_mutex_base_unlock(&o.base);
17352fe3d4b1SMaarten Lankhorst WARN_ON(o.ctx != (void *)~0UL);
17362fe3d4b1SMaarten Lankhorst
17372fe3d4b1SMaarten Lankhorst /* mutex_lock_interruptible (and *_nested) */
17382fe3d4b1SMaarten Lankhorst o.ctx = (void *)~0UL;
17399a75bd0cSSebastian Andrzej Siewior ret = ww_mutex_base_lock_interruptible(&o.base);
17402fe3d4b1SMaarten Lankhorst if (!ret)
17419a75bd0cSSebastian Andrzej Siewior ww_mutex_base_unlock(&o.base);
17422fe3d4b1SMaarten Lankhorst else
17432fe3d4b1SMaarten Lankhorst WARN_ON(1);
17442fe3d4b1SMaarten Lankhorst WARN_ON(o.ctx != (void *)~0UL);
17452fe3d4b1SMaarten Lankhorst
17462fe3d4b1SMaarten Lankhorst /* mutex_lock_killable (and *_nested) */
17472fe3d4b1SMaarten Lankhorst o.ctx = (void *)~0UL;
17489a75bd0cSSebastian Andrzej Siewior ret = ww_mutex_base_lock_killable(&o.base);
17492fe3d4b1SMaarten Lankhorst if (!ret)
17509a75bd0cSSebastian Andrzej Siewior ww_mutex_base_unlock(&o.base);
17512fe3d4b1SMaarten Lankhorst else
17522fe3d4b1SMaarten Lankhorst WARN_ON(1);
17532fe3d4b1SMaarten Lankhorst WARN_ON(o.ctx != (void *)~0UL);
17542fe3d4b1SMaarten Lankhorst
17552fe3d4b1SMaarten Lankhorst /* trylock, succeeding */
17562fe3d4b1SMaarten Lankhorst o.ctx = (void *)~0UL;
17579a75bd0cSSebastian Andrzej Siewior ret = ww_mutex_base_trylock(&o.base);
17582fe3d4b1SMaarten Lankhorst WARN_ON(!ret);
17592fe3d4b1SMaarten Lankhorst if (ret)
17609a75bd0cSSebastian Andrzej Siewior ww_mutex_base_unlock(&o.base);
17612fe3d4b1SMaarten Lankhorst else
17622fe3d4b1SMaarten Lankhorst WARN_ON(1);
17632fe3d4b1SMaarten Lankhorst WARN_ON(o.ctx != (void *)~0UL);
17642fe3d4b1SMaarten Lankhorst
17652fe3d4b1SMaarten Lankhorst /* trylock, failing */
17662fe3d4b1SMaarten Lankhorst o.ctx = (void *)~0UL;
17679a75bd0cSSebastian Andrzej Siewior ww_mutex_base_lock(&o.base);
17689a75bd0cSSebastian Andrzej Siewior ret = ww_mutex_base_trylock(&o.base);
17692fe3d4b1SMaarten Lankhorst WARN_ON(ret);
17709a75bd0cSSebastian Andrzej Siewior ww_mutex_base_unlock(&o.base);
17712fe3d4b1SMaarten Lankhorst WARN_ON(o.ctx != (void *)~0UL);
17722fe3d4b1SMaarten Lankhorst
17732fe3d4b1SMaarten Lankhorst /* nest_lock */
17742fe3d4b1SMaarten Lankhorst o.ctx = (void *)~0UL;
17759a75bd0cSSebastian Andrzej Siewior ww_mutex_base_lock_nest_lock(&o.base, &t);
17769a75bd0cSSebastian Andrzej Siewior ww_mutex_base_unlock(&o.base);
17772fe3d4b1SMaarten Lankhorst WARN_ON(o.ctx != (void *)~0UL);
17782fe3d4b1SMaarten Lankhorst }
17792fe3d4b1SMaarten Lankhorst
ww_test_two_contexts(void)17801de99445SMaarten Lankhorst static void ww_test_two_contexts(void)
17811de99445SMaarten Lankhorst {
17821de99445SMaarten Lankhorst WWAI(&t);
17831de99445SMaarten Lankhorst WWAI(&t2);
17841de99445SMaarten Lankhorst }
17851de99445SMaarten Lankhorst
ww_test_diff_class(void)17861de99445SMaarten Lankhorst static void ww_test_diff_class(void)
17871de99445SMaarten Lankhorst {
17881de99445SMaarten Lankhorst WWAI(&t);
17899a75bd0cSSebastian Andrzej Siewior #ifdef DEBUG_WW_MUTEXES
17901de99445SMaarten Lankhorst t.ww_class = NULL;
17911de99445SMaarten Lankhorst #endif
17921de99445SMaarten Lankhorst WWL(&o, &t);
17931de99445SMaarten Lankhorst }
17941de99445SMaarten Lankhorst
ww_test_context_done_twice(void)17951de99445SMaarten Lankhorst static void ww_test_context_done_twice(void)
17961de99445SMaarten Lankhorst {
17971de99445SMaarten Lankhorst WWAI(&t);
17981de99445SMaarten Lankhorst WWAD(&t);
17991de99445SMaarten Lankhorst WWAD(&t);
18001de99445SMaarten Lankhorst WWAF(&t);
18011de99445SMaarten Lankhorst }
18021de99445SMaarten Lankhorst
ww_test_context_unlock_twice(void)18031de99445SMaarten Lankhorst static void ww_test_context_unlock_twice(void)
18041de99445SMaarten Lankhorst {
18051de99445SMaarten Lankhorst WWAI(&t);
18061de99445SMaarten Lankhorst WWAD(&t);
18071de99445SMaarten Lankhorst WWAF(&t);
18081de99445SMaarten Lankhorst WWAF(&t);
18091de99445SMaarten Lankhorst }
18101de99445SMaarten Lankhorst
ww_test_context_fini_early(void)18111de99445SMaarten Lankhorst static void ww_test_context_fini_early(void)
18121de99445SMaarten Lankhorst {
18131de99445SMaarten Lankhorst WWAI(&t);
18141de99445SMaarten Lankhorst WWL(&o, &t);
18151de99445SMaarten Lankhorst WWAD(&t);
18161de99445SMaarten Lankhorst WWAF(&t);
18171de99445SMaarten Lankhorst }
18181de99445SMaarten Lankhorst
ww_test_context_lock_after_done(void)18191de99445SMaarten Lankhorst static void ww_test_context_lock_after_done(void)
18201de99445SMaarten Lankhorst {
18211de99445SMaarten Lankhorst WWAI(&t);
18221de99445SMaarten Lankhorst WWAD(&t);
18231de99445SMaarten Lankhorst WWL(&o, &t);
18241de99445SMaarten Lankhorst }
18251de99445SMaarten Lankhorst
ww_test_object_unlock_twice(void)18261de99445SMaarten Lankhorst static void ww_test_object_unlock_twice(void)
18271de99445SMaarten Lankhorst {
18281de99445SMaarten Lankhorst WWL1(&o);
18291de99445SMaarten Lankhorst WWU(&o);
18301de99445SMaarten Lankhorst WWU(&o);
18311de99445SMaarten Lankhorst }
18321de99445SMaarten Lankhorst
ww_test_object_lock_unbalanced(void)18331de99445SMaarten Lankhorst static void ww_test_object_lock_unbalanced(void)
18341de99445SMaarten Lankhorst {
18351de99445SMaarten Lankhorst WWAI(&t);
18361de99445SMaarten Lankhorst WWL(&o, &t);
18371de99445SMaarten Lankhorst t.acquired = 0;
18381de99445SMaarten Lankhorst WWU(&o);
18391de99445SMaarten Lankhorst WWAF(&t);
18401de99445SMaarten Lankhorst }
18411de99445SMaarten Lankhorst
ww_test_object_lock_stale_context(void)18421de99445SMaarten Lankhorst static void ww_test_object_lock_stale_context(void)
18431de99445SMaarten Lankhorst {
18441de99445SMaarten Lankhorst WWAI(&t);
18451de99445SMaarten Lankhorst o.ctx = &t2;
18461de99445SMaarten Lankhorst WWL(&o, &t);
18471de99445SMaarten Lankhorst }
18481de99445SMaarten Lankhorst
ww_test_edeadlk_normal(void)1849f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_normal(void)
1850f3cf139eSMaarten Lankhorst {
1851f3cf139eSMaarten Lankhorst int ret;
1852f3cf139eSMaarten Lankhorst
18539a75bd0cSSebastian Andrzej Siewior ww_mutex_base_lock(&o2.base);
1854f3cf139eSMaarten Lankhorst o2.ctx = &t2;
18555facae4fSQian Cai mutex_release(&o2.base.dep_map, _THIS_IP_);
1856f3cf139eSMaarten Lankhorst
1857f3cf139eSMaarten Lankhorst WWAI(&t);
1858f3cf139eSMaarten Lankhorst t2 = t;
1859f3cf139eSMaarten Lankhorst t2.stamp--;
1860f3cf139eSMaarten Lankhorst
1861f3cf139eSMaarten Lankhorst ret = WWL(&o, &t);
1862f3cf139eSMaarten Lankhorst WARN_ON(ret);
1863f3cf139eSMaarten Lankhorst
1864f3cf139eSMaarten Lankhorst ret = WWL(&o2, &t);
1865f3cf139eSMaarten Lankhorst WARN_ON(ret != -EDEADLK);
1866f3cf139eSMaarten Lankhorst
1867f3cf139eSMaarten Lankhorst o2.ctx = NULL;
1868f3cf139eSMaarten Lankhorst mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
18699a75bd0cSSebastian Andrzej Siewior ww_mutex_base_unlock(&o2.base);
1870f3cf139eSMaarten Lankhorst WWU(&o);
1871f3cf139eSMaarten Lankhorst
1872f3cf139eSMaarten Lankhorst WWL(&o2, &t);
1873f3cf139eSMaarten Lankhorst }
1874f3cf139eSMaarten Lankhorst
ww_test_edeadlk_normal_slow(void)1875f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_normal_slow(void)
1876f3cf139eSMaarten Lankhorst {
1877f3cf139eSMaarten Lankhorst int ret;
1878f3cf139eSMaarten Lankhorst
18799a75bd0cSSebastian Andrzej Siewior ww_mutex_base_lock(&o2.base);
18805facae4fSQian Cai mutex_release(&o2.base.dep_map, _THIS_IP_);
1881f3cf139eSMaarten Lankhorst o2.ctx = &t2;
1882f3cf139eSMaarten Lankhorst
1883f3cf139eSMaarten Lankhorst WWAI(&t);
1884f3cf139eSMaarten Lankhorst t2 = t;
1885f3cf139eSMaarten Lankhorst t2.stamp--;
1886f3cf139eSMaarten Lankhorst
1887f3cf139eSMaarten Lankhorst ret = WWL(&o, &t);
1888f3cf139eSMaarten Lankhorst WARN_ON(ret);
1889f3cf139eSMaarten Lankhorst
1890f3cf139eSMaarten Lankhorst ret = WWL(&o2, &t);
1891f3cf139eSMaarten Lankhorst WARN_ON(ret != -EDEADLK);
1892f3cf139eSMaarten Lankhorst
1893f3cf139eSMaarten Lankhorst o2.ctx = NULL;
1894f3cf139eSMaarten Lankhorst mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
18959a75bd0cSSebastian Andrzej Siewior ww_mutex_base_unlock(&o2.base);
1896f3cf139eSMaarten Lankhorst WWU(&o);
1897f3cf139eSMaarten Lankhorst
1898f3cf139eSMaarten Lankhorst ww_mutex_lock_slow(&o2, &t);
1899f3cf139eSMaarten Lankhorst }
1900f3cf139eSMaarten Lankhorst
ww_test_edeadlk_no_unlock(void)1901f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_no_unlock(void)
1902f3cf139eSMaarten Lankhorst {
1903f3cf139eSMaarten Lankhorst int ret;
1904f3cf139eSMaarten Lankhorst
19059a75bd0cSSebastian Andrzej Siewior ww_mutex_base_lock(&o2.base);
1906f3cf139eSMaarten Lankhorst o2.ctx = &t2;
19075facae4fSQian Cai mutex_release(&o2.base.dep_map, _THIS_IP_);
1908f3cf139eSMaarten Lankhorst
1909f3cf139eSMaarten Lankhorst WWAI(&t);
1910f3cf139eSMaarten Lankhorst t2 = t;
1911f3cf139eSMaarten Lankhorst t2.stamp--;
1912f3cf139eSMaarten Lankhorst
1913f3cf139eSMaarten Lankhorst ret = WWL(&o, &t);
1914f3cf139eSMaarten Lankhorst WARN_ON(ret);
1915f3cf139eSMaarten Lankhorst
1916f3cf139eSMaarten Lankhorst ret = WWL(&o2, &t);
1917f3cf139eSMaarten Lankhorst WARN_ON(ret != -EDEADLK);
1918f3cf139eSMaarten Lankhorst
1919f3cf139eSMaarten Lankhorst o2.ctx = NULL;
1920f3cf139eSMaarten Lankhorst mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
19219a75bd0cSSebastian Andrzej Siewior ww_mutex_base_unlock(&o2.base);
1922f3cf139eSMaarten Lankhorst
1923f3cf139eSMaarten Lankhorst WWL(&o2, &t);
1924f3cf139eSMaarten Lankhorst }
1925f3cf139eSMaarten Lankhorst
ww_test_edeadlk_no_unlock_slow(void)1926f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_no_unlock_slow(void)
1927f3cf139eSMaarten Lankhorst {
1928f3cf139eSMaarten Lankhorst int ret;
1929f3cf139eSMaarten Lankhorst
19309a75bd0cSSebastian Andrzej Siewior ww_mutex_base_lock(&o2.base);
19315facae4fSQian Cai mutex_release(&o2.base.dep_map, _THIS_IP_);
1932f3cf139eSMaarten Lankhorst o2.ctx = &t2;
1933f3cf139eSMaarten Lankhorst
1934f3cf139eSMaarten Lankhorst WWAI(&t);
1935f3cf139eSMaarten Lankhorst t2 = t;
1936f3cf139eSMaarten Lankhorst t2.stamp--;
1937f3cf139eSMaarten Lankhorst
1938f3cf139eSMaarten Lankhorst ret = WWL(&o, &t);
1939f3cf139eSMaarten Lankhorst WARN_ON(ret);
1940f3cf139eSMaarten Lankhorst
1941f3cf139eSMaarten Lankhorst ret = WWL(&o2, &t);
1942f3cf139eSMaarten Lankhorst WARN_ON(ret != -EDEADLK);
1943f3cf139eSMaarten Lankhorst
1944f3cf139eSMaarten Lankhorst o2.ctx = NULL;
1945f3cf139eSMaarten Lankhorst mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
19469a75bd0cSSebastian Andrzej Siewior ww_mutex_base_unlock(&o2.base);
1947f3cf139eSMaarten Lankhorst
1948f3cf139eSMaarten Lankhorst ww_mutex_lock_slow(&o2, &t);
1949f3cf139eSMaarten Lankhorst }
1950f3cf139eSMaarten Lankhorst
ww_test_edeadlk_acquire_more(void)1951f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_more(void)
1952f3cf139eSMaarten Lankhorst {
1953f3cf139eSMaarten Lankhorst int ret;
1954f3cf139eSMaarten Lankhorst
19559a75bd0cSSebastian Andrzej Siewior ww_mutex_base_lock(&o2.base);
19565facae4fSQian Cai mutex_release(&o2.base.dep_map, _THIS_IP_);
1957f3cf139eSMaarten Lankhorst o2.ctx = &t2;
1958f3cf139eSMaarten Lankhorst
1959f3cf139eSMaarten Lankhorst WWAI(&t);
1960f3cf139eSMaarten Lankhorst t2 = t;
1961f3cf139eSMaarten Lankhorst t2.stamp--;
1962f3cf139eSMaarten Lankhorst
1963f3cf139eSMaarten Lankhorst ret = WWL(&o, &t);
1964f3cf139eSMaarten Lankhorst WARN_ON(ret);
1965f3cf139eSMaarten Lankhorst
1966f3cf139eSMaarten Lankhorst ret = WWL(&o2, &t);
1967f3cf139eSMaarten Lankhorst WARN_ON(ret != -EDEADLK);
1968f3cf139eSMaarten Lankhorst
1969f3cf139eSMaarten Lankhorst ret = WWL(&o3, &t);
1970f3cf139eSMaarten Lankhorst }
1971f3cf139eSMaarten Lankhorst
ww_test_edeadlk_acquire_more_slow(void)1972f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_more_slow(void)
1973f3cf139eSMaarten Lankhorst {
1974f3cf139eSMaarten Lankhorst int ret;
1975f3cf139eSMaarten Lankhorst
19769a75bd0cSSebastian Andrzej Siewior ww_mutex_base_lock(&o2.base);
19775facae4fSQian Cai mutex_release(&o2.base.dep_map, _THIS_IP_);
1978f3cf139eSMaarten Lankhorst o2.ctx = &t2;
1979f3cf139eSMaarten Lankhorst
1980f3cf139eSMaarten Lankhorst WWAI(&t);
1981f3cf139eSMaarten Lankhorst t2 = t;
1982f3cf139eSMaarten Lankhorst t2.stamp--;
1983f3cf139eSMaarten Lankhorst
1984f3cf139eSMaarten Lankhorst ret = WWL(&o, &t);
1985f3cf139eSMaarten Lankhorst WARN_ON(ret);
1986f3cf139eSMaarten Lankhorst
1987f3cf139eSMaarten Lankhorst ret = WWL(&o2, &t);
1988f3cf139eSMaarten Lankhorst WARN_ON(ret != -EDEADLK);
1989f3cf139eSMaarten Lankhorst
1990f3cf139eSMaarten Lankhorst ww_mutex_lock_slow(&o3, &t);
1991f3cf139eSMaarten Lankhorst }
1992f3cf139eSMaarten Lankhorst
ww_test_edeadlk_acquire_more_edeadlk(void)1993f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_more_edeadlk(void)
1994f3cf139eSMaarten Lankhorst {
1995f3cf139eSMaarten Lankhorst int ret;
1996f3cf139eSMaarten Lankhorst
19979a75bd0cSSebastian Andrzej Siewior ww_mutex_base_lock(&o2.base);
19985facae4fSQian Cai mutex_release(&o2.base.dep_map, _THIS_IP_);
1999f3cf139eSMaarten Lankhorst o2.ctx = &t2;
2000f3cf139eSMaarten Lankhorst
20019a75bd0cSSebastian Andrzej Siewior ww_mutex_base_lock(&o3.base);
20025facae4fSQian Cai mutex_release(&o3.base.dep_map, _THIS_IP_);
2003f3cf139eSMaarten Lankhorst o3.ctx = &t2;
2004f3cf139eSMaarten Lankhorst
2005f3cf139eSMaarten Lankhorst WWAI(&t);
2006f3cf139eSMaarten Lankhorst t2 = t;
2007f3cf139eSMaarten Lankhorst t2.stamp--;
2008f3cf139eSMaarten Lankhorst
2009f3cf139eSMaarten Lankhorst ret = WWL(&o, &t);
2010f3cf139eSMaarten Lankhorst WARN_ON(ret);
2011f3cf139eSMaarten Lankhorst
2012f3cf139eSMaarten Lankhorst ret = WWL(&o2, &t);
2013f3cf139eSMaarten Lankhorst WARN_ON(ret != -EDEADLK);
2014f3cf139eSMaarten Lankhorst
2015f3cf139eSMaarten Lankhorst ret = WWL(&o3, &t);
2016f3cf139eSMaarten Lankhorst WARN_ON(ret != -EDEADLK);
2017f3cf139eSMaarten Lankhorst }
2018f3cf139eSMaarten Lankhorst
ww_test_edeadlk_acquire_more_edeadlk_slow(void)2019f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_more_edeadlk_slow(void)
2020f3cf139eSMaarten Lankhorst {
2021f3cf139eSMaarten Lankhorst int ret;
2022f3cf139eSMaarten Lankhorst
20239a75bd0cSSebastian Andrzej Siewior ww_mutex_base_lock(&o2.base);
20245facae4fSQian Cai mutex_release(&o2.base.dep_map, _THIS_IP_);
2025f3cf139eSMaarten Lankhorst o2.ctx = &t2;
2026f3cf139eSMaarten Lankhorst
20279a75bd0cSSebastian Andrzej Siewior ww_mutex_base_lock(&o3.base);
20285facae4fSQian Cai mutex_release(&o3.base.dep_map, _THIS_IP_);
2029f3cf139eSMaarten Lankhorst o3.ctx = &t2;
2030f3cf139eSMaarten Lankhorst
2031f3cf139eSMaarten Lankhorst WWAI(&t);
2032f3cf139eSMaarten Lankhorst t2 = t;
2033f3cf139eSMaarten Lankhorst t2.stamp--;
2034f3cf139eSMaarten Lankhorst
2035f3cf139eSMaarten Lankhorst ret = WWL(&o, &t);
2036f3cf139eSMaarten Lankhorst WARN_ON(ret);
2037f3cf139eSMaarten Lankhorst
2038f3cf139eSMaarten Lankhorst ret = WWL(&o2, &t);
2039f3cf139eSMaarten Lankhorst WARN_ON(ret != -EDEADLK);
2040f3cf139eSMaarten Lankhorst
2041f3cf139eSMaarten Lankhorst ww_mutex_lock_slow(&o3, &t);
2042f3cf139eSMaarten Lankhorst }
2043f3cf139eSMaarten Lankhorst
ww_test_edeadlk_acquire_wrong(void)2044f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_wrong(void)
2045f3cf139eSMaarten Lankhorst {
2046f3cf139eSMaarten Lankhorst int ret;
2047f3cf139eSMaarten Lankhorst
20489a75bd0cSSebastian Andrzej Siewior ww_mutex_base_lock(&o2.base);
20495facae4fSQian Cai mutex_release(&o2.base.dep_map, _THIS_IP_);
2050f3cf139eSMaarten Lankhorst o2.ctx = &t2;
2051f3cf139eSMaarten Lankhorst
2052f3cf139eSMaarten Lankhorst WWAI(&t);
2053f3cf139eSMaarten Lankhorst t2 = t;
2054f3cf139eSMaarten Lankhorst t2.stamp--;
2055f3cf139eSMaarten Lankhorst
2056f3cf139eSMaarten Lankhorst ret = WWL(&o, &t);
2057f3cf139eSMaarten Lankhorst WARN_ON(ret);
2058f3cf139eSMaarten Lankhorst
2059f3cf139eSMaarten Lankhorst ret = WWL(&o2, &t);
2060f3cf139eSMaarten Lankhorst WARN_ON(ret != -EDEADLK);
2061f3cf139eSMaarten Lankhorst if (!ret)
2062f3cf139eSMaarten Lankhorst WWU(&o2);
2063f3cf139eSMaarten Lankhorst
2064f3cf139eSMaarten Lankhorst WWU(&o);
2065f3cf139eSMaarten Lankhorst
2066f3cf139eSMaarten Lankhorst ret = WWL(&o3, &t);
2067f3cf139eSMaarten Lankhorst }
2068f3cf139eSMaarten Lankhorst
ww_test_edeadlk_acquire_wrong_slow(void)2069f3cf139eSMaarten Lankhorst static void ww_test_edeadlk_acquire_wrong_slow(void)
2070f3cf139eSMaarten Lankhorst {
2071f3cf139eSMaarten Lankhorst int ret;
2072f3cf139eSMaarten Lankhorst
20739a75bd0cSSebastian Andrzej Siewior ww_mutex_base_lock(&o2.base);
20745facae4fSQian Cai mutex_release(&o2.base.dep_map, _THIS_IP_);
2075f3cf139eSMaarten Lankhorst o2.ctx = &t2;
2076f3cf139eSMaarten Lankhorst
2077f3cf139eSMaarten Lankhorst WWAI(&t);
2078f3cf139eSMaarten Lankhorst t2 = t;
2079f3cf139eSMaarten Lankhorst t2.stamp--;
2080f3cf139eSMaarten Lankhorst
2081f3cf139eSMaarten Lankhorst ret = WWL(&o, &t);
2082f3cf139eSMaarten Lankhorst WARN_ON(ret);
2083f3cf139eSMaarten Lankhorst
2084f3cf139eSMaarten Lankhorst ret = WWL(&o2, &t);
2085f3cf139eSMaarten Lankhorst WARN_ON(ret != -EDEADLK);
2086f3cf139eSMaarten Lankhorst if (!ret)
2087f3cf139eSMaarten Lankhorst WWU(&o2);
2088f3cf139eSMaarten Lankhorst
2089f3cf139eSMaarten Lankhorst WWU(&o);
2090f3cf139eSMaarten Lankhorst
2091f3cf139eSMaarten Lankhorst ww_mutex_lock_slow(&o3, &t);
2092f3cf139eSMaarten Lankhorst }
2093f3cf139eSMaarten Lankhorst
ww_test_spin_nest_unlocked(void)20941de99445SMaarten Lankhorst static void ww_test_spin_nest_unlocked(void)
20951de99445SMaarten Lankhorst {
2096a2e9ae58SPeter Zijlstra spin_lock_nest_lock(&lock_A, &o.base);
20971de99445SMaarten Lankhorst U(A);
20981de99445SMaarten Lankhorst }
20991de99445SMaarten Lankhorst
2100e04ce676SBoqun Feng /* This is not a deadlock, because we have X1 to serialize Y1 and Y2 */
ww_test_spin_nest_lock(void)2101e04ce676SBoqun Feng static void ww_test_spin_nest_lock(void)
2102e04ce676SBoqun Feng {
2103e04ce676SBoqun Feng spin_lock(&lock_X1);
2104e04ce676SBoqun Feng spin_lock_nest_lock(&lock_Y1, &lock_X1);
2105e04ce676SBoqun Feng spin_lock(&lock_A);
2106e04ce676SBoqun Feng spin_lock_nest_lock(&lock_Y2, &lock_X1);
2107e04ce676SBoqun Feng spin_unlock(&lock_A);
2108e04ce676SBoqun Feng spin_unlock(&lock_Y2);
2109e04ce676SBoqun Feng spin_unlock(&lock_Y1);
2110e04ce676SBoqun Feng spin_unlock(&lock_X1);
2111e04ce676SBoqun Feng }
2112e04ce676SBoqun Feng
ww_test_unneeded_slow(void)21131de99445SMaarten Lankhorst static void ww_test_unneeded_slow(void)
21141de99445SMaarten Lankhorst {
21151de99445SMaarten Lankhorst WWAI(&t);
21161de99445SMaarten Lankhorst
21171de99445SMaarten Lankhorst ww_mutex_lock_slow(&o, &t);
21181de99445SMaarten Lankhorst }
21191de99445SMaarten Lankhorst
ww_test_context_block(void)21201de99445SMaarten Lankhorst static void ww_test_context_block(void)
21211de99445SMaarten Lankhorst {
21221de99445SMaarten Lankhorst int ret;
21231de99445SMaarten Lankhorst
21241de99445SMaarten Lankhorst WWAI(&t);
21251de99445SMaarten Lankhorst
21261de99445SMaarten Lankhorst ret = WWL(&o, &t);
21271de99445SMaarten Lankhorst WARN_ON(ret);
21281de99445SMaarten Lankhorst WWL1(&o2);
21291de99445SMaarten Lankhorst }
21301de99445SMaarten Lankhorst
ww_test_context_try(void)21311de99445SMaarten Lankhorst static void ww_test_context_try(void)
21321de99445SMaarten Lankhorst {
21331de99445SMaarten Lankhorst int ret;
21341de99445SMaarten Lankhorst
21351de99445SMaarten Lankhorst WWAI(&t);
21361de99445SMaarten Lankhorst
21371de99445SMaarten Lankhorst ret = WWL(&o, &t);
21381de99445SMaarten Lankhorst WARN_ON(ret);
21391de99445SMaarten Lankhorst
21401de99445SMaarten Lankhorst ret = WWT(&o2);
21411de99445SMaarten Lankhorst WARN_ON(!ret);
21421de99445SMaarten Lankhorst WWU(&o2);
21431de99445SMaarten Lankhorst WWU(&o);
21441de99445SMaarten Lankhorst }
21451de99445SMaarten Lankhorst
ww_test_context_context(void)21461de99445SMaarten Lankhorst static void ww_test_context_context(void)
21471de99445SMaarten Lankhorst {
21481de99445SMaarten Lankhorst int ret;
21491de99445SMaarten Lankhorst
21501de99445SMaarten Lankhorst WWAI(&t);
21511de99445SMaarten Lankhorst
21521de99445SMaarten Lankhorst ret = WWL(&o, &t);
21531de99445SMaarten Lankhorst WARN_ON(ret);
21541de99445SMaarten Lankhorst
21551de99445SMaarten Lankhorst ret = WWL(&o2, &t);
21561de99445SMaarten Lankhorst WARN_ON(ret);
21571de99445SMaarten Lankhorst
21581de99445SMaarten Lankhorst WWU(&o2);
21591de99445SMaarten Lankhorst WWU(&o);
21601de99445SMaarten Lankhorst }
21611de99445SMaarten Lankhorst
ww_test_try_block(void)21621de99445SMaarten Lankhorst static void ww_test_try_block(void)
21631de99445SMaarten Lankhorst {
21641de99445SMaarten Lankhorst bool ret;
21651de99445SMaarten Lankhorst
21661de99445SMaarten Lankhorst ret = WWT(&o);
21671de99445SMaarten Lankhorst WARN_ON(!ret);
21681de99445SMaarten Lankhorst
21691de99445SMaarten Lankhorst WWL1(&o2);
21701de99445SMaarten Lankhorst WWU(&o2);
21711de99445SMaarten Lankhorst WWU(&o);
21721de99445SMaarten Lankhorst }
21731de99445SMaarten Lankhorst
ww_test_try_try(void)21741de99445SMaarten Lankhorst static void ww_test_try_try(void)
21751de99445SMaarten Lankhorst {
21761de99445SMaarten Lankhorst bool ret;
21771de99445SMaarten Lankhorst
21781de99445SMaarten Lankhorst ret = WWT(&o);
21791de99445SMaarten Lankhorst WARN_ON(!ret);
21801de99445SMaarten Lankhorst ret = WWT(&o2);
21811de99445SMaarten Lankhorst WARN_ON(!ret);
21821de99445SMaarten Lankhorst WWU(&o2);
21831de99445SMaarten Lankhorst WWU(&o);
21841de99445SMaarten Lankhorst }
21851de99445SMaarten Lankhorst
ww_test_try_context(void)21861de99445SMaarten Lankhorst static void ww_test_try_context(void)
21871de99445SMaarten Lankhorst {
21881de99445SMaarten Lankhorst int ret;
21891de99445SMaarten Lankhorst
21901de99445SMaarten Lankhorst ret = WWT(&o);
21911de99445SMaarten Lankhorst WARN_ON(!ret);
21921de99445SMaarten Lankhorst
21931de99445SMaarten Lankhorst WWAI(&t);
21941de99445SMaarten Lankhorst
21951de99445SMaarten Lankhorst ret = WWL(&o2, &t);
21961de99445SMaarten Lankhorst WARN_ON(ret);
21971de99445SMaarten Lankhorst }
21981de99445SMaarten Lankhorst
ww_test_block_block(void)21991de99445SMaarten Lankhorst static void ww_test_block_block(void)
22001de99445SMaarten Lankhorst {
22011de99445SMaarten Lankhorst WWL1(&o);
22021de99445SMaarten Lankhorst WWL1(&o2);
22031de99445SMaarten Lankhorst }
22041de99445SMaarten Lankhorst
ww_test_block_try(void)22051de99445SMaarten Lankhorst static void ww_test_block_try(void)
22061de99445SMaarten Lankhorst {
22071de99445SMaarten Lankhorst bool ret;
22081de99445SMaarten Lankhorst
22091de99445SMaarten Lankhorst WWL1(&o);
22101de99445SMaarten Lankhorst ret = WWT(&o2);
22111de99445SMaarten Lankhorst WARN_ON(!ret);
22121de99445SMaarten Lankhorst }
22131de99445SMaarten Lankhorst
ww_test_block_context(void)22141de99445SMaarten Lankhorst static void ww_test_block_context(void)
22151de99445SMaarten Lankhorst {
22161de99445SMaarten Lankhorst int ret;
22171de99445SMaarten Lankhorst
22181de99445SMaarten Lankhorst WWL1(&o);
22191de99445SMaarten Lankhorst WWAI(&t);
22201de99445SMaarten Lankhorst
22211de99445SMaarten Lankhorst ret = WWL(&o2, &t);
22221de99445SMaarten Lankhorst WARN_ON(ret);
22231de99445SMaarten Lankhorst }
22241de99445SMaarten Lankhorst
ww_test_spin_block(void)22251de99445SMaarten Lankhorst static void ww_test_spin_block(void)
22261de99445SMaarten Lankhorst {
22271de99445SMaarten Lankhorst L(A);
22281de99445SMaarten Lankhorst U(A);
22291de99445SMaarten Lankhorst
22301de99445SMaarten Lankhorst WWL1(&o);
22311de99445SMaarten Lankhorst L(A);
22321de99445SMaarten Lankhorst U(A);
22331de99445SMaarten Lankhorst WWU(&o);
22341de99445SMaarten Lankhorst
22351de99445SMaarten Lankhorst L(A);
22361de99445SMaarten Lankhorst WWL1(&o);
22371de99445SMaarten Lankhorst WWU(&o);
22381de99445SMaarten Lankhorst U(A);
22391de99445SMaarten Lankhorst }
22401de99445SMaarten Lankhorst
ww_test_spin_try(void)22411de99445SMaarten Lankhorst static void ww_test_spin_try(void)
22421de99445SMaarten Lankhorst {
22431de99445SMaarten Lankhorst bool ret;
22441de99445SMaarten Lankhorst
22451de99445SMaarten Lankhorst L(A);
22461de99445SMaarten Lankhorst U(A);
22471de99445SMaarten Lankhorst
22481de99445SMaarten Lankhorst ret = WWT(&o);
22491de99445SMaarten Lankhorst WARN_ON(!ret);
22501de99445SMaarten Lankhorst L(A);
22511de99445SMaarten Lankhorst U(A);
22521de99445SMaarten Lankhorst WWU(&o);
22531de99445SMaarten Lankhorst
22541de99445SMaarten Lankhorst L(A);
22551de99445SMaarten Lankhorst ret = WWT(&o);
22561de99445SMaarten Lankhorst WARN_ON(!ret);
22571de99445SMaarten Lankhorst WWU(&o);
22581de99445SMaarten Lankhorst U(A);
22591de99445SMaarten Lankhorst }
22601de99445SMaarten Lankhorst
ww_test_spin_context(void)22611de99445SMaarten Lankhorst static void ww_test_spin_context(void)
22621de99445SMaarten Lankhorst {
22631de99445SMaarten Lankhorst int ret;
22641de99445SMaarten Lankhorst
22651de99445SMaarten Lankhorst L(A);
22661de99445SMaarten Lankhorst U(A);
22671de99445SMaarten Lankhorst
22681de99445SMaarten Lankhorst WWAI(&t);
22691de99445SMaarten Lankhorst
22701de99445SMaarten Lankhorst ret = WWL(&o, &t);
22711de99445SMaarten Lankhorst WARN_ON(ret);
22721de99445SMaarten Lankhorst L(A);
22731de99445SMaarten Lankhorst U(A);
22741de99445SMaarten Lankhorst WWU(&o);
22751de99445SMaarten Lankhorst
22761de99445SMaarten Lankhorst L(A);
22771de99445SMaarten Lankhorst ret = WWL(&o, &t);
22781de99445SMaarten Lankhorst WARN_ON(ret);
22791de99445SMaarten Lankhorst WWU(&o);
22801de99445SMaarten Lankhorst U(A);
22811de99445SMaarten Lankhorst }
22821de99445SMaarten Lankhorst
ww_tests(void)22831de99445SMaarten Lankhorst static void ww_tests(void)
22841de99445SMaarten Lankhorst {
22851de99445SMaarten Lankhorst printk(" --------------------------------------------------------------------------\n");
22861de99445SMaarten Lankhorst printk(" | Wound/wait tests |\n");
22871de99445SMaarten Lankhorst printk(" ---------------------\n");
22881de99445SMaarten Lankhorst
22891de99445SMaarten Lankhorst print_testname("ww api failures");
22901de99445SMaarten Lankhorst dotest(ww_test_fail_acquire, SUCCESS, LOCKTYPE_WW);
22912fe3d4b1SMaarten Lankhorst dotest(ww_test_normal, SUCCESS, LOCKTYPE_WW);
22921de99445SMaarten Lankhorst dotest(ww_test_unneeded_slow, FAILURE, LOCKTYPE_WW);
229325139409SMichael Ellerman pr_cont("\n");
22941de99445SMaarten Lankhorst
22951de99445SMaarten Lankhorst print_testname("ww contexts mixing");
22961de99445SMaarten Lankhorst dotest(ww_test_two_contexts, FAILURE, LOCKTYPE_WW);
22971de99445SMaarten Lankhorst dotest(ww_test_diff_class, FAILURE, LOCKTYPE_WW);
229825139409SMichael Ellerman pr_cont("\n");
22991de99445SMaarten Lankhorst
23001de99445SMaarten Lankhorst print_testname("finishing ww context");
23011de99445SMaarten Lankhorst dotest(ww_test_context_done_twice, FAILURE, LOCKTYPE_WW);
23021de99445SMaarten Lankhorst dotest(ww_test_context_unlock_twice, FAILURE, LOCKTYPE_WW);
23031de99445SMaarten Lankhorst dotest(ww_test_context_fini_early, FAILURE, LOCKTYPE_WW);
23041de99445SMaarten Lankhorst dotest(ww_test_context_lock_after_done, FAILURE, LOCKTYPE_WW);
230525139409SMichael Ellerman pr_cont("\n");
23061de99445SMaarten Lankhorst
23071de99445SMaarten Lankhorst print_testname("locking mismatches");
23081de99445SMaarten Lankhorst dotest(ww_test_object_unlock_twice, FAILURE, LOCKTYPE_WW);
23091de99445SMaarten Lankhorst dotest(ww_test_object_lock_unbalanced, FAILURE, LOCKTYPE_WW);
23101de99445SMaarten Lankhorst dotest(ww_test_object_lock_stale_context, FAILURE, LOCKTYPE_WW);
231125139409SMichael Ellerman pr_cont("\n");
23121de99445SMaarten Lankhorst
2313f3cf139eSMaarten Lankhorst print_testname("EDEADLK handling");
2314f3cf139eSMaarten Lankhorst dotest(ww_test_edeadlk_normal, SUCCESS, LOCKTYPE_WW);
2315f3cf139eSMaarten Lankhorst dotest(ww_test_edeadlk_normal_slow, SUCCESS, LOCKTYPE_WW);
2316f3cf139eSMaarten Lankhorst dotest(ww_test_edeadlk_no_unlock, FAILURE, LOCKTYPE_WW);
2317f3cf139eSMaarten Lankhorst dotest(ww_test_edeadlk_no_unlock_slow, FAILURE, LOCKTYPE_WW);
2318f3cf139eSMaarten Lankhorst dotest(ww_test_edeadlk_acquire_more, FAILURE, LOCKTYPE_WW);
2319f3cf139eSMaarten Lankhorst dotest(ww_test_edeadlk_acquire_more_slow, FAILURE, LOCKTYPE_WW);
2320f3cf139eSMaarten Lankhorst dotest(ww_test_edeadlk_acquire_more_edeadlk, FAILURE, LOCKTYPE_WW);
2321f3cf139eSMaarten Lankhorst dotest(ww_test_edeadlk_acquire_more_edeadlk_slow, FAILURE, LOCKTYPE_WW);
2322f3cf139eSMaarten Lankhorst dotest(ww_test_edeadlk_acquire_wrong, FAILURE, LOCKTYPE_WW);
2323f3cf139eSMaarten Lankhorst dotest(ww_test_edeadlk_acquire_wrong_slow, FAILURE, LOCKTYPE_WW);
232425139409SMichael Ellerman pr_cont("\n");
2325f3cf139eSMaarten Lankhorst
23261de99445SMaarten Lankhorst print_testname("spinlock nest unlocked");
23271de99445SMaarten Lankhorst dotest(ww_test_spin_nest_unlocked, FAILURE, LOCKTYPE_WW);
232825139409SMichael Ellerman pr_cont("\n");
23291de99445SMaarten Lankhorst
2330e04ce676SBoqun Feng print_testname("spinlock nest test");
2331e04ce676SBoqun Feng dotest(ww_test_spin_nest_lock, SUCCESS, LOCKTYPE_WW);
2332e04ce676SBoqun Feng pr_cont("\n");
2333e04ce676SBoqun Feng
23341de99445SMaarten Lankhorst printk(" -----------------------------------------------------\n");
23351de99445SMaarten Lankhorst printk(" |block | try |context|\n");
23361de99445SMaarten Lankhorst printk(" -----------------------------------------------------\n");
23371de99445SMaarten Lankhorst
23381de99445SMaarten Lankhorst print_testname("context");
23391de99445SMaarten Lankhorst dotest(ww_test_context_block, FAILURE, LOCKTYPE_WW);
23401de99445SMaarten Lankhorst dotest(ww_test_context_try, SUCCESS, LOCKTYPE_WW);
23411de99445SMaarten Lankhorst dotest(ww_test_context_context, SUCCESS, LOCKTYPE_WW);
234225139409SMichael Ellerman pr_cont("\n");
23431de99445SMaarten Lankhorst
23441de99445SMaarten Lankhorst print_testname("try");
23451de99445SMaarten Lankhorst dotest(ww_test_try_block, FAILURE, LOCKTYPE_WW);
23461de99445SMaarten Lankhorst dotest(ww_test_try_try, SUCCESS, LOCKTYPE_WW);
23471de99445SMaarten Lankhorst dotest(ww_test_try_context, FAILURE, LOCKTYPE_WW);
234825139409SMichael Ellerman pr_cont("\n");
23491de99445SMaarten Lankhorst
23501de99445SMaarten Lankhorst print_testname("block");
23511de99445SMaarten Lankhorst dotest(ww_test_block_block, FAILURE, LOCKTYPE_WW);
23521de99445SMaarten Lankhorst dotest(ww_test_block_try, SUCCESS, LOCKTYPE_WW);
23531de99445SMaarten Lankhorst dotest(ww_test_block_context, FAILURE, LOCKTYPE_WW);
235425139409SMichael Ellerman pr_cont("\n");
23551de99445SMaarten Lankhorst
23561de99445SMaarten Lankhorst print_testname("spinlock");
23571de99445SMaarten Lankhorst dotest(ww_test_spin_block, FAILURE, LOCKTYPE_WW);
23581de99445SMaarten Lankhorst dotest(ww_test_spin_try, SUCCESS, LOCKTYPE_WW);
23591de99445SMaarten Lankhorst dotest(ww_test_spin_context, FAILURE, LOCKTYPE_WW);
236025139409SMichael Ellerman pr_cont("\n");
23611de99445SMaarten Lankhorst }
2362cae2ed9aSIngo Molnar
2363ad56450dSBoqun Feng
2364ad56450dSBoqun Feng /*
2365ad56450dSBoqun Feng * <in hardirq handler>
2366ad56450dSBoqun Feng * read_lock(&A);
2367ad56450dSBoqun Feng * <hardirq disable>
2368ad56450dSBoqun Feng * spin_lock(&B);
2369ad56450dSBoqun Feng * spin_lock(&B);
2370ad56450dSBoqun Feng * read_lock(&A);
2371ad56450dSBoqun Feng *
2372ad56450dSBoqun Feng * is a deadlock.
2373ad56450dSBoqun Feng */
queued_read_lock_hardirq_RE_Er(void)2374ad56450dSBoqun Feng static void queued_read_lock_hardirq_RE_Er(void)
2375ad56450dSBoqun Feng {
2376ad56450dSBoqun Feng HARDIRQ_ENTER();
2377ad56450dSBoqun Feng read_lock(&rwlock_A);
2378ad56450dSBoqun Feng LOCK(B);
2379ad56450dSBoqun Feng UNLOCK(B);
2380ad56450dSBoqun Feng read_unlock(&rwlock_A);
2381ad56450dSBoqun Feng HARDIRQ_EXIT();
2382ad56450dSBoqun Feng
2383ad56450dSBoqun Feng HARDIRQ_DISABLE();
2384ad56450dSBoqun Feng LOCK(B);
2385ad56450dSBoqun Feng read_lock(&rwlock_A);
2386ad56450dSBoqun Feng read_unlock(&rwlock_A);
2387ad56450dSBoqun Feng UNLOCK(B);
2388ad56450dSBoqun Feng HARDIRQ_ENABLE();
2389ad56450dSBoqun Feng }
2390ad56450dSBoqun Feng
2391ad56450dSBoqun Feng /*
2392ad56450dSBoqun Feng * <in hardirq handler>
2393ad56450dSBoqun Feng * spin_lock(&B);
2394ad56450dSBoqun Feng * <hardirq disable>
2395ad56450dSBoqun Feng * read_lock(&A);
2396ad56450dSBoqun Feng * read_lock(&A);
2397ad56450dSBoqun Feng * spin_lock(&B);
2398ad56450dSBoqun Feng *
2399ad56450dSBoqun Feng * is not a deadlock.
2400ad56450dSBoqun Feng */
queued_read_lock_hardirq_ER_rE(void)2401ad56450dSBoqun Feng static void queued_read_lock_hardirq_ER_rE(void)
2402ad56450dSBoqun Feng {
2403ad56450dSBoqun Feng HARDIRQ_ENTER();
2404ad56450dSBoqun Feng LOCK(B);
2405ad56450dSBoqun Feng read_lock(&rwlock_A);
2406ad56450dSBoqun Feng read_unlock(&rwlock_A);
2407ad56450dSBoqun Feng UNLOCK(B);
2408ad56450dSBoqun Feng HARDIRQ_EXIT();
2409ad56450dSBoqun Feng
2410ad56450dSBoqun Feng HARDIRQ_DISABLE();
2411ad56450dSBoqun Feng read_lock(&rwlock_A);
2412ad56450dSBoqun Feng LOCK(B);
2413ad56450dSBoqun Feng UNLOCK(B);
2414ad56450dSBoqun Feng read_unlock(&rwlock_A);
2415ad56450dSBoqun Feng HARDIRQ_ENABLE();
2416ad56450dSBoqun Feng }
2417ad56450dSBoqun Feng
2418ad56450dSBoqun Feng /*
2419ad56450dSBoqun Feng * <hardirq disable>
2420ad56450dSBoqun Feng * spin_lock(&B);
2421ad56450dSBoqun Feng * read_lock(&A);
2422ad56450dSBoqun Feng * <in hardirq handler>
2423ad56450dSBoqun Feng * spin_lock(&B);
2424ad56450dSBoqun Feng * read_lock(&A);
2425ad56450dSBoqun Feng *
2426ad56450dSBoqun Feng * is a deadlock. Because the two read_lock()s are both non-recursive readers.
2427ad56450dSBoqun Feng */
queued_read_lock_hardirq_inversion(void)2428ad56450dSBoqun Feng static void queued_read_lock_hardirq_inversion(void)
2429ad56450dSBoqun Feng {
2430ad56450dSBoqun Feng
2431ad56450dSBoqun Feng HARDIRQ_ENTER();
2432ad56450dSBoqun Feng LOCK(B);
2433ad56450dSBoqun Feng UNLOCK(B);
2434ad56450dSBoqun Feng HARDIRQ_EXIT();
2435ad56450dSBoqun Feng
2436ad56450dSBoqun Feng HARDIRQ_DISABLE();
2437ad56450dSBoqun Feng LOCK(B);
2438ad56450dSBoqun Feng read_lock(&rwlock_A);
2439ad56450dSBoqun Feng read_unlock(&rwlock_A);
2440ad56450dSBoqun Feng UNLOCK(B);
2441ad56450dSBoqun Feng HARDIRQ_ENABLE();
2442ad56450dSBoqun Feng
2443ad56450dSBoqun Feng read_lock(&rwlock_A);
2444ad56450dSBoqun Feng read_unlock(&rwlock_A);
2445ad56450dSBoqun Feng }
2446ad56450dSBoqun Feng
queued_read_lock_tests(void)2447ad56450dSBoqun Feng static void queued_read_lock_tests(void)
2448ad56450dSBoqun Feng {
2449ad56450dSBoqun Feng printk(" --------------------------------------------------------------------------\n");
2450ad56450dSBoqun Feng printk(" | queued read lock tests |\n");
2451ad56450dSBoqun Feng printk(" ---------------------------\n");
2452ad56450dSBoqun Feng print_testname("hardirq read-lock/lock-read");
2453ad56450dSBoqun Feng dotest(queued_read_lock_hardirq_RE_Er, FAILURE, LOCKTYPE_RWLOCK);
2454ad56450dSBoqun Feng pr_cont("\n");
2455ad56450dSBoqun Feng
2456ad56450dSBoqun Feng print_testname("hardirq lock-read/read-lock");
2457ad56450dSBoqun Feng dotest(queued_read_lock_hardirq_ER_rE, SUCCESS, LOCKTYPE_RWLOCK);
2458ad56450dSBoqun Feng pr_cont("\n");
2459ad56450dSBoqun Feng
2460ad56450dSBoqun Feng print_testname("hardirq inversion");
2461ad56450dSBoqun Feng dotest(queued_read_lock_hardirq_inversion, FAILURE, LOCKTYPE_RWLOCK);
2462ad56450dSBoqun Feng pr_cont("\n");
2463ad56450dSBoqun Feng }
2464ad56450dSBoqun Feng
fs_reclaim_correct_nesting(void)2465d5037d1dSDaniel Vetter static void fs_reclaim_correct_nesting(void)
2466d5037d1dSDaniel Vetter {
2467d5037d1dSDaniel Vetter fs_reclaim_acquire(GFP_KERNEL);
2468d5037d1dSDaniel Vetter might_alloc(GFP_NOFS);
2469d5037d1dSDaniel Vetter fs_reclaim_release(GFP_KERNEL);
2470d5037d1dSDaniel Vetter }
2471d5037d1dSDaniel Vetter
fs_reclaim_wrong_nesting(void)2472d5037d1dSDaniel Vetter static void fs_reclaim_wrong_nesting(void)
2473d5037d1dSDaniel Vetter {
2474d5037d1dSDaniel Vetter fs_reclaim_acquire(GFP_KERNEL);
2475d5037d1dSDaniel Vetter might_alloc(GFP_KERNEL);
2476d5037d1dSDaniel Vetter fs_reclaim_release(GFP_KERNEL);
2477d5037d1dSDaniel Vetter }
2478d5037d1dSDaniel Vetter
fs_reclaim_protected_nesting(void)2479d5037d1dSDaniel Vetter static void fs_reclaim_protected_nesting(void)
2480d5037d1dSDaniel Vetter {
2481d5037d1dSDaniel Vetter unsigned int flags;
2482d5037d1dSDaniel Vetter
2483d5037d1dSDaniel Vetter fs_reclaim_acquire(GFP_KERNEL);
2484d5037d1dSDaniel Vetter flags = memalloc_nofs_save();
2485d5037d1dSDaniel Vetter might_alloc(GFP_KERNEL);
2486d5037d1dSDaniel Vetter memalloc_nofs_restore(flags);
2487d5037d1dSDaniel Vetter fs_reclaim_release(GFP_KERNEL);
2488d5037d1dSDaniel Vetter }
2489d5037d1dSDaniel Vetter
fs_reclaim_tests(void)2490d5037d1dSDaniel Vetter static void fs_reclaim_tests(void)
2491d5037d1dSDaniel Vetter {
2492d5037d1dSDaniel Vetter printk(" --------------------\n");
2493d5037d1dSDaniel Vetter printk(" | fs_reclaim tests |\n");
2494d5037d1dSDaniel Vetter printk(" --------------------\n");
2495d5037d1dSDaniel Vetter
2496d5037d1dSDaniel Vetter print_testname("correct nesting");
2497d5037d1dSDaniel Vetter dotest(fs_reclaim_correct_nesting, SUCCESS, 0);
2498d5037d1dSDaniel Vetter pr_cont("\n");
2499d5037d1dSDaniel Vetter
2500d5037d1dSDaniel Vetter print_testname("wrong nesting");
2501d5037d1dSDaniel Vetter dotest(fs_reclaim_wrong_nesting, FAILURE, 0);
2502d5037d1dSDaniel Vetter pr_cont("\n");
2503d5037d1dSDaniel Vetter
2504d5037d1dSDaniel Vetter print_testname("protected nesting");
2505d5037d1dSDaniel Vetter dotest(fs_reclaim_protected_nesting, SUCCESS, 0);
2506d5037d1dSDaniel Vetter pr_cont("\n");
2507d5037d1dSDaniel Vetter }
2508d5037d1dSDaniel Vetter
2509*f66c5380SBoqun Feng /* Defines guard classes to create contexts */
DEFINE_LOCK_GUARD_0(HARDIRQ,HARDIRQ_ENTER (),HARDIRQ_EXIT ())2510*f66c5380SBoqun Feng DEFINE_LOCK_GUARD_0(HARDIRQ, HARDIRQ_ENTER(), HARDIRQ_EXIT())
2511*f66c5380SBoqun Feng DEFINE_LOCK_GUARD_0(NOTTHREADED_HARDIRQ,
2512*f66c5380SBoqun Feng do {
2513*f66c5380SBoqun Feng local_irq_disable();
2514*f66c5380SBoqun Feng __irq_enter();
25159271a40dSBoqun Feng WARN_ON(!in_irq());
2516*f66c5380SBoqun Feng } while(0), HARDIRQ_EXIT())
2517*f66c5380SBoqun Feng DEFINE_LOCK_GUARD_0(SOFTIRQ, SOFTIRQ_ENTER(), SOFTIRQ_EXIT())
25189271a40dSBoqun Feng
2519*f66c5380SBoqun Feng /* Define RCU guards, should go away when RCU has its own guard definitions */
2520*f66c5380SBoqun Feng DEFINE_LOCK_GUARD_0(RCU, rcu_read_lock(), rcu_read_unlock())
2521*f66c5380SBoqun Feng DEFINE_LOCK_GUARD_0(RCU_BH, rcu_read_lock_bh(), rcu_read_unlock_bh())
2522*f66c5380SBoqun Feng DEFINE_LOCK_GUARD_0(RCU_SCHED, rcu_read_lock_sched(), rcu_read_unlock_sched())
25239271a40dSBoqun Feng
25249271a40dSBoqun Feng
25259271a40dSBoqun Feng #define GENERATE_2_CONTEXT_TESTCASE(outer, outer_lock, inner, inner_lock) \
25269271a40dSBoqun Feng \
25279271a40dSBoqun Feng static void __maybe_unused inner##_in_##outer(void) \
25289271a40dSBoqun Feng { \
2529*f66c5380SBoqun Feng /* Relies the reversed clean-up ordering: inner first */ \
2530*f66c5380SBoqun Feng guard(outer)(outer_lock); \
2531*f66c5380SBoqun Feng guard(inner)(inner_lock); \
25329271a40dSBoqun Feng }
25339271a40dSBoqun Feng
25349271a40dSBoqun Feng /*
25359271a40dSBoqun Feng * wait contexts (considering PREEMPT_RT)
25369271a40dSBoqun Feng *
25379271a40dSBoqun Feng * o: inner is allowed in outer
25389271a40dSBoqun Feng * x: inner is disallowed in outer
25399271a40dSBoqun Feng *
25409271a40dSBoqun Feng * \ inner | RCU | RAW_SPIN | SPIN | MUTEX
25419271a40dSBoqun Feng * outer \ | | | |
25429271a40dSBoqun Feng * ---------------+-------+----------+------+-------
25439271a40dSBoqun Feng * HARDIRQ | o | o | o | x
25449271a40dSBoqun Feng * ---------------+-------+----------+------+-------
25459271a40dSBoqun Feng * NOTTHREADED_IRQ| o | o | x | x
25469271a40dSBoqun Feng * ---------------+-------+----------+------+-------
25479271a40dSBoqun Feng * SOFTIRQ | o | o | o | x
25489271a40dSBoqun Feng * ---------------+-------+----------+------+-------
25499271a40dSBoqun Feng * RCU | o | o | o | x
25509271a40dSBoqun Feng * ---------------+-------+----------+------+-------
25519271a40dSBoqun Feng * RCU_BH | o | o | o | x
25529271a40dSBoqun Feng * ---------------+-------+----------+------+-------
25539271a40dSBoqun Feng * RCU_SCHED | o | o | x | x
25549271a40dSBoqun Feng * ---------------+-------+----------+------+-------
25559271a40dSBoqun Feng * RAW_SPIN | o | o | x | x
25569271a40dSBoqun Feng * ---------------+-------+----------+------+-------
25579271a40dSBoqun Feng * SPIN | o | o | o | x
25589271a40dSBoqun Feng * ---------------+-------+----------+------+-------
25599271a40dSBoqun Feng * MUTEX | o | o | o | o
25609271a40dSBoqun Feng * ---------------+-------+----------+------+-------
25619271a40dSBoqun Feng */
25629271a40dSBoqun Feng
25639271a40dSBoqun Feng #define GENERATE_2_CONTEXT_TESTCASE_FOR_ALL_OUTER(inner, inner_lock) \
25649271a40dSBoqun Feng GENERATE_2_CONTEXT_TESTCASE(HARDIRQ, , inner, inner_lock) \
25659271a40dSBoqun Feng GENERATE_2_CONTEXT_TESTCASE(NOTTHREADED_HARDIRQ, , inner, inner_lock) \
25669271a40dSBoqun Feng GENERATE_2_CONTEXT_TESTCASE(SOFTIRQ, , inner, inner_lock) \
25679271a40dSBoqun Feng GENERATE_2_CONTEXT_TESTCASE(RCU, , inner, inner_lock) \
25689271a40dSBoqun Feng GENERATE_2_CONTEXT_TESTCASE(RCU_BH, , inner, inner_lock) \
25699271a40dSBoqun Feng GENERATE_2_CONTEXT_TESTCASE(RCU_SCHED, , inner, inner_lock) \
2570*f66c5380SBoqun Feng GENERATE_2_CONTEXT_TESTCASE(raw_spinlock, &raw_lock_A, inner, inner_lock) \
2571*f66c5380SBoqun Feng GENERATE_2_CONTEXT_TESTCASE(spinlock, &lock_A, inner, inner_lock) \
2572*f66c5380SBoqun Feng GENERATE_2_CONTEXT_TESTCASE(mutex, &mutex_A, inner, inner_lock)
25739271a40dSBoqun Feng
25749271a40dSBoqun Feng GENERATE_2_CONTEXT_TESTCASE_FOR_ALL_OUTER(RCU, )
2575*f66c5380SBoqun Feng GENERATE_2_CONTEXT_TESTCASE_FOR_ALL_OUTER(raw_spinlock, &raw_lock_B)
2576*f66c5380SBoqun Feng GENERATE_2_CONTEXT_TESTCASE_FOR_ALL_OUTER(spinlock, &lock_B)
2577*f66c5380SBoqun Feng GENERATE_2_CONTEXT_TESTCASE_FOR_ALL_OUTER(mutex, &mutex_B)
25789271a40dSBoqun Feng
25799271a40dSBoqun Feng /* the outer context allows all kinds of preemption */
25809271a40dSBoqun Feng #define DO_CONTEXT_TESTCASE_OUTER_PREEMPTIBLE(outer) \
25819271a40dSBoqun Feng dotest(RCU_in_##outer, SUCCESS, LOCKTYPE_RWLOCK); \
2582*f66c5380SBoqun Feng dotest(raw_spinlock_in_##outer, SUCCESS, LOCKTYPE_SPIN); \
2583*f66c5380SBoqun Feng dotest(spinlock_in_##outer, SUCCESS, LOCKTYPE_SPIN); \
2584*f66c5380SBoqun Feng dotest(mutex_in_##outer, SUCCESS, LOCKTYPE_MUTEX); \
25859271a40dSBoqun Feng
25869271a40dSBoqun Feng /*
25879271a40dSBoqun Feng * the outer context only allows the preemption introduced by spinlock_t (which
25889271a40dSBoqun Feng * is a sleepable lock for PREEMPT_RT)
25899271a40dSBoqun Feng */
25909271a40dSBoqun Feng #define DO_CONTEXT_TESTCASE_OUTER_LIMITED_PREEMPTIBLE(outer) \
25919271a40dSBoqun Feng dotest(RCU_in_##outer, SUCCESS, LOCKTYPE_RWLOCK); \
2592*f66c5380SBoqun Feng dotest(raw_spinlock_in_##outer, SUCCESS, LOCKTYPE_SPIN); \
2593*f66c5380SBoqun Feng dotest(spinlock_in_##outer, SUCCESS, LOCKTYPE_SPIN); \
2594*f66c5380SBoqun Feng dotest(mutex_in_##outer, FAILURE, LOCKTYPE_MUTEX); \
25959271a40dSBoqun Feng
25969271a40dSBoqun Feng /* the outer doesn't allows any kind of preemption */
25979271a40dSBoqun Feng #define DO_CONTEXT_TESTCASE_OUTER_NOT_PREEMPTIBLE(outer) \
25989271a40dSBoqun Feng dotest(RCU_in_##outer, SUCCESS, LOCKTYPE_RWLOCK); \
2599*f66c5380SBoqun Feng dotest(raw_spinlock_in_##outer, SUCCESS, LOCKTYPE_SPIN); \
2600*f66c5380SBoqun Feng dotest(spinlock_in_##outer, FAILURE, LOCKTYPE_SPIN); \
2601*f66c5380SBoqun Feng dotest(mutex_in_##outer, FAILURE, LOCKTYPE_MUTEX); \
26029271a40dSBoqun Feng
26039271a40dSBoqun Feng static void wait_context_tests(void)
26049271a40dSBoqun Feng {
26059271a40dSBoqun Feng printk(" --------------------------------------------------------------------------\n");
26069271a40dSBoqun Feng printk(" | wait context tests |\n");
26079271a40dSBoqun Feng printk(" --------------------------------------------------------------------------\n");
26089271a40dSBoqun Feng printk(" | rcu | raw | spin |mutex |\n");
26099271a40dSBoqun Feng printk(" --------------------------------------------------------------------------\n");
26109271a40dSBoqun Feng print_testname("in hardirq context");
26119271a40dSBoqun Feng DO_CONTEXT_TESTCASE_OUTER_LIMITED_PREEMPTIBLE(HARDIRQ);
26129271a40dSBoqun Feng pr_cont("\n");
26139271a40dSBoqun Feng
26149271a40dSBoqun Feng print_testname("in hardirq context (not threaded)");
26159271a40dSBoqun Feng DO_CONTEXT_TESTCASE_OUTER_NOT_PREEMPTIBLE(NOTTHREADED_HARDIRQ);
26169271a40dSBoqun Feng pr_cont("\n");
26179271a40dSBoqun Feng
26189271a40dSBoqun Feng print_testname("in softirq context");
26199271a40dSBoqun Feng DO_CONTEXT_TESTCASE_OUTER_LIMITED_PREEMPTIBLE(SOFTIRQ);
26209271a40dSBoqun Feng pr_cont("\n");
26219271a40dSBoqun Feng
26229271a40dSBoqun Feng print_testname("in RCU context");
26239271a40dSBoqun Feng DO_CONTEXT_TESTCASE_OUTER_LIMITED_PREEMPTIBLE(RCU);
26249271a40dSBoqun Feng pr_cont("\n");
26259271a40dSBoqun Feng
26269271a40dSBoqun Feng print_testname("in RCU-bh context");
26279271a40dSBoqun Feng DO_CONTEXT_TESTCASE_OUTER_LIMITED_PREEMPTIBLE(RCU_BH);
26289271a40dSBoqun Feng pr_cont("\n");
26299271a40dSBoqun Feng
26309271a40dSBoqun Feng print_testname("in RCU-sched context");
26319271a40dSBoqun Feng DO_CONTEXT_TESTCASE_OUTER_NOT_PREEMPTIBLE(RCU_SCHED);
26329271a40dSBoqun Feng pr_cont("\n");
26339271a40dSBoqun Feng
26349271a40dSBoqun Feng print_testname("in RAW_SPINLOCK context");
2635*f66c5380SBoqun Feng DO_CONTEXT_TESTCASE_OUTER_NOT_PREEMPTIBLE(raw_spinlock);
26369271a40dSBoqun Feng pr_cont("\n");
26379271a40dSBoqun Feng
26389271a40dSBoqun Feng print_testname("in SPINLOCK context");
2639*f66c5380SBoqun Feng DO_CONTEXT_TESTCASE_OUTER_LIMITED_PREEMPTIBLE(spinlock);
26409271a40dSBoqun Feng pr_cont("\n");
26419271a40dSBoqun Feng
26429271a40dSBoqun Feng print_testname("in MUTEX context");
2643*f66c5380SBoqun Feng DO_CONTEXT_TESTCASE_OUTER_PREEMPTIBLE(mutex);
26449271a40dSBoqun Feng pr_cont("\n");
26459271a40dSBoqun Feng }
26469271a40dSBoqun Feng
local_lock_2(void)26477e923e6aSPeter Zijlstra static void local_lock_2(void)
26487e923e6aSPeter Zijlstra {
2649fc78dd08SSebastian Andrzej Siewior local_lock(&local_A); /* IRQ-ON */
2650fc78dd08SSebastian Andrzej Siewior local_unlock(&local_A);
26517e923e6aSPeter Zijlstra
26527e923e6aSPeter Zijlstra HARDIRQ_ENTER();
26537e923e6aSPeter Zijlstra spin_lock(&lock_A); /* IN-IRQ */
26547e923e6aSPeter Zijlstra spin_unlock(&lock_A);
26557e923e6aSPeter Zijlstra HARDIRQ_EXIT()
26567e923e6aSPeter Zijlstra
26577e923e6aSPeter Zijlstra HARDIRQ_DISABLE();
26587e923e6aSPeter Zijlstra spin_lock(&lock_A);
2659fc78dd08SSebastian Andrzej Siewior local_lock(&local_A); /* IN-IRQ <-> IRQ-ON cycle, false */
2660fc78dd08SSebastian Andrzej Siewior local_unlock(&local_A);
26617e923e6aSPeter Zijlstra spin_unlock(&lock_A);
26627e923e6aSPeter Zijlstra HARDIRQ_ENABLE();
26637e923e6aSPeter Zijlstra }
26647e923e6aSPeter Zijlstra
local_lock_3A(void)26657e923e6aSPeter Zijlstra static void local_lock_3A(void)
26667e923e6aSPeter Zijlstra {
2667fc78dd08SSebastian Andrzej Siewior local_lock(&local_A); /* IRQ-ON */
26687e923e6aSPeter Zijlstra spin_lock(&lock_B); /* IRQ-ON */
26697e923e6aSPeter Zijlstra spin_unlock(&lock_B);
2670fc78dd08SSebastian Andrzej Siewior local_unlock(&local_A);
26717e923e6aSPeter Zijlstra
26727e923e6aSPeter Zijlstra HARDIRQ_ENTER();
26737e923e6aSPeter Zijlstra spin_lock(&lock_A); /* IN-IRQ */
26747e923e6aSPeter Zijlstra spin_unlock(&lock_A);
26757e923e6aSPeter Zijlstra HARDIRQ_EXIT()
26767e923e6aSPeter Zijlstra
26777e923e6aSPeter Zijlstra HARDIRQ_DISABLE();
26787e923e6aSPeter Zijlstra spin_lock(&lock_A);
2679fc78dd08SSebastian Andrzej Siewior local_lock(&local_A); /* IN-IRQ <-> IRQ-ON cycle only if we count local_lock(), false */
2680fc78dd08SSebastian Andrzej Siewior local_unlock(&local_A);
26817e923e6aSPeter Zijlstra spin_unlock(&lock_A);
26827e923e6aSPeter Zijlstra HARDIRQ_ENABLE();
26837e923e6aSPeter Zijlstra }
26847e923e6aSPeter Zijlstra
local_lock_3B(void)26857e923e6aSPeter Zijlstra static void local_lock_3B(void)
26867e923e6aSPeter Zijlstra {
2687fc78dd08SSebastian Andrzej Siewior local_lock(&local_A); /* IRQ-ON */
26887e923e6aSPeter Zijlstra spin_lock(&lock_B); /* IRQ-ON */
26897e923e6aSPeter Zijlstra spin_unlock(&lock_B);
2690fc78dd08SSebastian Andrzej Siewior local_unlock(&local_A);
26917e923e6aSPeter Zijlstra
26927e923e6aSPeter Zijlstra HARDIRQ_ENTER();
26937e923e6aSPeter Zijlstra spin_lock(&lock_A); /* IN-IRQ */
26947e923e6aSPeter Zijlstra spin_unlock(&lock_A);
26957e923e6aSPeter Zijlstra HARDIRQ_EXIT()
26967e923e6aSPeter Zijlstra
26977e923e6aSPeter Zijlstra HARDIRQ_DISABLE();
26987e923e6aSPeter Zijlstra spin_lock(&lock_A);
2699fc78dd08SSebastian Andrzej Siewior local_lock(&local_A); /* IN-IRQ <-> IRQ-ON cycle only if we count local_lock(), false */
2700fc78dd08SSebastian Andrzej Siewior local_unlock(&local_A);
27017e923e6aSPeter Zijlstra spin_unlock(&lock_A);
27027e923e6aSPeter Zijlstra HARDIRQ_ENABLE();
27037e923e6aSPeter Zijlstra
27047e923e6aSPeter Zijlstra HARDIRQ_DISABLE();
27057e923e6aSPeter Zijlstra spin_lock(&lock_A);
27067e923e6aSPeter Zijlstra spin_lock(&lock_B); /* IN-IRQ <-> IRQ-ON cycle, true */
27077e923e6aSPeter Zijlstra spin_unlock(&lock_B);
27087e923e6aSPeter Zijlstra spin_unlock(&lock_A);
27097e923e6aSPeter Zijlstra HARDIRQ_DISABLE();
27107e923e6aSPeter Zijlstra
27117e923e6aSPeter Zijlstra }
27127e923e6aSPeter Zijlstra
local_lock_tests(void)27137e923e6aSPeter Zijlstra static void local_lock_tests(void)
27147e923e6aSPeter Zijlstra {
27157e923e6aSPeter Zijlstra printk(" --------------------------------------------------------------------------\n");
27167e923e6aSPeter Zijlstra printk(" | local_lock tests |\n");
27177e923e6aSPeter Zijlstra printk(" ---------------------\n");
27187e923e6aSPeter Zijlstra
27197e923e6aSPeter Zijlstra print_testname("local_lock inversion 2");
27207e923e6aSPeter Zijlstra dotest(local_lock_2, SUCCESS, LOCKTYPE_LL);
27217e923e6aSPeter Zijlstra pr_cont("\n");
27227e923e6aSPeter Zijlstra
27237e923e6aSPeter Zijlstra print_testname("local_lock inversion 3A");
27247e923e6aSPeter Zijlstra dotest(local_lock_3A, SUCCESS, LOCKTYPE_LL);
27257e923e6aSPeter Zijlstra pr_cont("\n");
27267e923e6aSPeter Zijlstra
27277e923e6aSPeter Zijlstra print_testname("local_lock inversion 3B");
27287e923e6aSPeter Zijlstra dotest(local_lock_3B, FAILURE, LOCKTYPE_LL);
27297e923e6aSPeter Zijlstra pr_cont("\n");
27307e923e6aSPeter Zijlstra }
27317e923e6aSPeter Zijlstra
hardirq_deadlock_softirq_not_deadlock(void)27328946ccc2SBoqun Feng static void hardirq_deadlock_softirq_not_deadlock(void)
27338946ccc2SBoqun Feng {
27348946ccc2SBoqun Feng /* mutex_A is hardirq-unsafe and softirq-unsafe */
27358946ccc2SBoqun Feng /* mutex_A -> lock_C */
27368946ccc2SBoqun Feng mutex_lock(&mutex_A);
27378946ccc2SBoqun Feng HARDIRQ_DISABLE();
27388946ccc2SBoqun Feng spin_lock(&lock_C);
27398946ccc2SBoqun Feng spin_unlock(&lock_C);
27408946ccc2SBoqun Feng HARDIRQ_ENABLE();
27418946ccc2SBoqun Feng mutex_unlock(&mutex_A);
27428946ccc2SBoqun Feng
27438946ccc2SBoqun Feng /* lock_A is hardirq-safe */
27448946ccc2SBoqun Feng HARDIRQ_ENTER();
27458946ccc2SBoqun Feng spin_lock(&lock_A);
27468946ccc2SBoqun Feng spin_unlock(&lock_A);
27478946ccc2SBoqun Feng HARDIRQ_EXIT();
27488946ccc2SBoqun Feng
27498946ccc2SBoqun Feng /* lock_A -> lock_B */
27508946ccc2SBoqun Feng HARDIRQ_DISABLE();
27518946ccc2SBoqun Feng spin_lock(&lock_A);
27528946ccc2SBoqun Feng spin_lock(&lock_B);
27538946ccc2SBoqun Feng spin_unlock(&lock_B);
27548946ccc2SBoqun Feng spin_unlock(&lock_A);
27558946ccc2SBoqun Feng HARDIRQ_ENABLE();
27568946ccc2SBoqun Feng
27578946ccc2SBoqun Feng /* lock_B -> lock_C */
27588946ccc2SBoqun Feng HARDIRQ_DISABLE();
27598946ccc2SBoqun Feng spin_lock(&lock_B);
27608946ccc2SBoqun Feng spin_lock(&lock_C);
27618946ccc2SBoqun Feng spin_unlock(&lock_C);
27628946ccc2SBoqun Feng spin_unlock(&lock_B);
27638946ccc2SBoqun Feng HARDIRQ_ENABLE();
27648946ccc2SBoqun Feng
27658946ccc2SBoqun Feng /* lock_D is softirq-safe */
27668946ccc2SBoqun Feng SOFTIRQ_ENTER();
27678946ccc2SBoqun Feng spin_lock(&lock_D);
27688946ccc2SBoqun Feng spin_unlock(&lock_D);
27698946ccc2SBoqun Feng SOFTIRQ_EXIT();
27708946ccc2SBoqun Feng
27718946ccc2SBoqun Feng /* And lock_D is hardirq-unsafe */
27728946ccc2SBoqun Feng SOFTIRQ_DISABLE();
27738946ccc2SBoqun Feng spin_lock(&lock_D);
27748946ccc2SBoqun Feng spin_unlock(&lock_D);
27758946ccc2SBoqun Feng SOFTIRQ_ENABLE();
27768946ccc2SBoqun Feng
27778946ccc2SBoqun Feng /*
27788946ccc2SBoqun Feng * mutex_A -> lock_C -> lock_D is softirq-unsafe -> softirq-safe, not
27798946ccc2SBoqun Feng * deadlock.
27808946ccc2SBoqun Feng *
27818946ccc2SBoqun Feng * lock_A -> lock_B -> lock_C -> lock_D is hardirq-safe ->
27828946ccc2SBoqun Feng * hardirq-unsafe, deadlock.
27838946ccc2SBoqun Feng */
27848946ccc2SBoqun Feng HARDIRQ_DISABLE();
27858946ccc2SBoqun Feng spin_lock(&lock_C);
27868946ccc2SBoqun Feng spin_lock(&lock_D);
27878946ccc2SBoqun Feng spin_unlock(&lock_D);
27888946ccc2SBoqun Feng spin_unlock(&lock_C);
27898946ccc2SBoqun Feng HARDIRQ_ENABLE();
27908946ccc2SBoqun Feng }
27918946ccc2SBoqun Feng
locking_selftest(void)2792cae2ed9aSIngo Molnar void locking_selftest(void)
2793cae2ed9aSIngo Molnar {
2794cae2ed9aSIngo Molnar /*
2795cae2ed9aSIngo Molnar * Got a locking failure before the selftest ran?
2796cae2ed9aSIngo Molnar */
2797cae2ed9aSIngo Molnar if (!debug_locks) {
2798cae2ed9aSIngo Molnar printk("----------------------------------\n");
2799cae2ed9aSIngo Molnar printk("| Locking API testsuite disabled |\n");
2800cae2ed9aSIngo Molnar printk("----------------------------------\n");
2801cae2ed9aSIngo Molnar return;
2802cae2ed9aSIngo Molnar }
2803cae2ed9aSIngo Molnar
2804cae2ed9aSIngo Molnar /*
2805e9181886SBoqun Feng * treats read_lock() as recursive read locks for testing purpose
2806e9181886SBoqun Feng */
2807e9181886SBoqun Feng force_read_lock_recursive = 1;
2808e9181886SBoqun Feng
2809e9181886SBoqun Feng /*
2810cae2ed9aSIngo Molnar * Run the testsuite:
2811cae2ed9aSIngo Molnar */
2812cae2ed9aSIngo Molnar printk("------------------------\n");
2813cae2ed9aSIngo Molnar printk("| Locking API testsuite:\n");
2814cae2ed9aSIngo Molnar printk("----------------------------------------------------------------------------\n");
2815fc78dd08SSebastian Andrzej Siewior printk(" | spin |wlock |rlock |mutex | wsem | rsem |rtmutex\n");
2816cae2ed9aSIngo Molnar printk(" --------------------------------------------------------------------------\n");
2817cae2ed9aSIngo Molnar
2818cae2ed9aSIngo Molnar init_shared_classes();
2819cdc84d79SBart Van Assche lockdep_set_selftest_task(current);
2820cae2ed9aSIngo Molnar
28216c9076ecSIngo Molnar DO_TESTCASE_6R("A-A deadlock", AA);
2822cae2ed9aSIngo Molnar DO_TESTCASE_6R("A-B-B-A deadlock", ABBA);
2823cae2ed9aSIngo Molnar DO_TESTCASE_6R("A-B-B-C-C-A deadlock", ABBCCA);
2824cae2ed9aSIngo Molnar DO_TESTCASE_6R("A-B-C-A-B-C deadlock", ABCABC);
2825cae2ed9aSIngo Molnar DO_TESTCASE_6R("A-B-B-C-C-D-D-A deadlock", ABBCCDDA);
2826cae2ed9aSIngo Molnar DO_TESTCASE_6R("A-B-C-D-B-D-D-A deadlock", ABCDBDDA);
2827cae2ed9aSIngo Molnar DO_TESTCASE_6R("A-B-C-D-B-C-D-A deadlock", ABCDBCDA);
2828cae2ed9aSIngo Molnar DO_TESTCASE_6("double unlock", double_unlock);
2829cae2ed9aSIngo Molnar DO_TESTCASE_6("initialize held", init_held);
2830cae2ed9aSIngo Molnar
2831cae2ed9aSIngo Molnar printk(" --------------------------------------------------------------------------\n");
2832cae2ed9aSIngo Molnar print_testname("recursive read-lock");
283325139409SMichael Ellerman pr_cont(" |");
2834cae2ed9aSIngo Molnar dotest(rlock_AA1, SUCCESS, LOCKTYPE_RWLOCK);
283525139409SMichael Ellerman pr_cont(" |");
2836cae2ed9aSIngo Molnar dotest(rsem_AA1, FAILURE, LOCKTYPE_RWSEM);
283725139409SMichael Ellerman pr_cont("\n");
2838cae2ed9aSIngo Molnar
2839cae2ed9aSIngo Molnar print_testname("recursive read-lock #2");
284025139409SMichael Ellerman pr_cont(" |");
28416c9076ecSIngo Molnar dotest(rlock_AA1B, SUCCESS, LOCKTYPE_RWLOCK);
284225139409SMichael Ellerman pr_cont(" |");
2843cae2ed9aSIngo Molnar dotest(rsem_AA1B, FAILURE, LOCKTYPE_RWSEM);
284425139409SMichael Ellerman pr_cont("\n");
2845cae2ed9aSIngo Molnar
2846cae2ed9aSIngo Molnar print_testname("mixed read-write-lock");
284725139409SMichael Ellerman pr_cont(" |");
2848cae2ed9aSIngo Molnar dotest(rlock_AA2, FAILURE, LOCKTYPE_RWLOCK);
284925139409SMichael Ellerman pr_cont(" |");
2850cae2ed9aSIngo Molnar dotest(rsem_AA2, FAILURE, LOCKTYPE_RWSEM);
285125139409SMichael Ellerman pr_cont("\n");
2852cae2ed9aSIngo Molnar
2853cae2ed9aSIngo Molnar print_testname("mixed write-read-lock");
285425139409SMichael Ellerman pr_cont(" |");
2855cae2ed9aSIngo Molnar dotest(rlock_AA3, FAILURE, LOCKTYPE_RWLOCK);
285625139409SMichael Ellerman pr_cont(" |");
2857cae2ed9aSIngo Molnar dotest(rsem_AA3, FAILURE, LOCKTYPE_RWSEM);
285825139409SMichael Ellerman pr_cont("\n");
2859cae2ed9aSIngo Molnar
2860e9149858SPeter Zijlstra print_testname("mixed read-lock/lock-write ABBA");
2861e9149858SPeter Zijlstra pr_cont(" |");
2862e9149858SPeter Zijlstra dotest(rlock_ABBA1, FAILURE, LOCKTYPE_RWLOCK);
2863e9149858SPeter Zijlstra pr_cont(" |");
2864e9149858SPeter Zijlstra dotest(rwsem_ABBA1, FAILURE, LOCKTYPE_RWSEM);
2865e9149858SPeter Zijlstra
2866e9149858SPeter Zijlstra print_testname("mixed read-lock/lock-read ABBA");
2867e9149858SPeter Zijlstra pr_cont(" |");
2868e9149858SPeter Zijlstra dotest(rlock_ABBA2, SUCCESS, LOCKTYPE_RWLOCK);
2869e9149858SPeter Zijlstra pr_cont(" |");
2870e9149858SPeter Zijlstra dotest(rwsem_ABBA2, FAILURE, LOCKTYPE_RWSEM);
2871e9149858SPeter Zijlstra
2872e9149858SPeter Zijlstra print_testname("mixed write-lock/lock-write ABBA");
2873e9149858SPeter Zijlstra pr_cont(" |");
2874e9149858SPeter Zijlstra dotest(rlock_ABBA3, FAILURE, LOCKTYPE_RWLOCK);
2875e9149858SPeter Zijlstra pr_cont(" |");
2876e9149858SPeter Zijlstra dotest(rwsem_ABBA3, FAILURE, LOCKTYPE_RWSEM);
2877e9149858SPeter Zijlstra
2878d4f200e5SBoqun Feng print_testname("chain cached mixed R-L/L-W ABBA");
2879d4f200e5SBoqun Feng pr_cont(" |");
2880d4f200e5SBoqun Feng dotest(rlock_chaincache_ABBA1, FAILURE, LOCKTYPE_RWLOCK);
2881d4f200e5SBoqun Feng
28828ef7ca75SBoqun Feng DO_TESTCASE_6x1RRB("rlock W1R2/W2R3/W3R1", W1R2_W2R3_W3R1);
28838ef7ca75SBoqun Feng DO_TESTCASE_6x1RRB("rlock W1W2/R2R3/W3R1", W1W2_R2R3_W3R1);
28848ef7ca75SBoqun Feng DO_TESTCASE_6x1RR("rlock W1W2/R2R3/R3W1", W1W2_R2R3_R3W1);
28858ef7ca75SBoqun Feng DO_TESTCASE_6x1RR("rlock W1R2/R2R3/W3W1", W1R2_R2R3_W3W1);
28868ef7ca75SBoqun Feng
2887cae2ed9aSIngo Molnar printk(" --------------------------------------------------------------------------\n");
2888cae2ed9aSIngo Molnar /*
2889cae2ed9aSIngo Molnar * irq-context testcases:
2890cae2ed9aSIngo Molnar */
2891cae2ed9aSIngo Molnar DO_TESTCASE_2x6("irqs-on + irq-safe-A", irqsafe1);
2892a529f8dbSSebastian Andrzej Siewior NON_RT(DO_TESTCASE_2x3("sirq-safe-A => hirqs-on", irqsafe2A));
2893cae2ed9aSIngo Molnar DO_TESTCASE_2x6("safe-A + irqs-on", irqsafe2B);
2894cae2ed9aSIngo Molnar DO_TESTCASE_6x6("safe-A + unsafe-B #1", irqsafe3);
2895cae2ed9aSIngo Molnar DO_TESTCASE_6x6("safe-A + unsafe-B #2", irqsafe4);
2896cae2ed9aSIngo Molnar DO_TESTCASE_6x6RW("irq lock-inversion", irq_inversion);
2897cae2ed9aSIngo Molnar
289831e0d747SBoqun Feng DO_TESTCASE_6x2x2RW("irq read-recursion", irq_read_recursion);
289931e0d747SBoqun Feng DO_TESTCASE_6x2x2RW("irq read-recursion #2", irq_read_recursion2);
290096a16f45SBoqun Feng DO_TESTCASE_6x2x2RW("irq read-recursion #3", irq_read_recursion3);
2901cae2ed9aSIngo Molnar
29021de99445SMaarten Lankhorst ww_tests();
29031de99445SMaarten Lankhorst
2904e9181886SBoqun Feng force_read_lock_recursive = 0;
2905e9181886SBoqun Feng /*
2906e9181886SBoqun Feng * queued_read_lock() specific test cases can be put here
2907e9181886SBoqun Feng */
2908ad56450dSBoqun Feng if (IS_ENABLED(CONFIG_QUEUED_RWLOCKS))
2909ad56450dSBoqun Feng queued_read_lock_tests();
2910e9181886SBoqun Feng
2911d5037d1dSDaniel Vetter fs_reclaim_tests();
2912d5037d1dSDaniel Vetter
29139271a40dSBoqun Feng /* Wait context test cases that are specific for RAW_LOCK_NESTING */
29149271a40dSBoqun Feng if (IS_ENABLED(CONFIG_PROVE_RAW_LOCK_NESTING))
29159271a40dSBoqun Feng wait_context_tests();
29169271a40dSBoqun Feng
29177e923e6aSPeter Zijlstra local_lock_tests();
29187e923e6aSPeter Zijlstra
29198946ccc2SBoqun Feng print_testname("hardirq_unsafe_softirq_safe");
29208946ccc2SBoqun Feng dotest(hardirq_deadlock_softirq_not_deadlock, FAILURE, LOCKTYPE_SPECIAL);
29218946ccc2SBoqun Feng pr_cont("\n");
29228946ccc2SBoqun Feng
2923cae2ed9aSIngo Molnar if (unexpected_testcase_failures) {
2924cae2ed9aSIngo Molnar printk("-----------------------------------------------------------------\n");
2925cae2ed9aSIngo Molnar debug_locks = 0;
2926cae2ed9aSIngo Molnar printk("BUG: %3d unexpected failures (out of %3d) - debugging disabled! |\n",
2927cae2ed9aSIngo Molnar unexpected_testcase_failures, testcase_total);
2928cae2ed9aSIngo Molnar printk("-----------------------------------------------------------------\n");
2929cae2ed9aSIngo Molnar } else if (expected_testcase_failures && testcase_successes) {
2930cae2ed9aSIngo Molnar printk("--------------------------------------------------------\n");
2931cae2ed9aSIngo Molnar printk("%3d out of %3d testcases failed, as expected. |\n",
2932cae2ed9aSIngo Molnar expected_testcase_failures, testcase_total);
2933cae2ed9aSIngo Molnar printk("----------------------------------------------------\n");
2934cae2ed9aSIngo Molnar debug_locks = 1;
2935cae2ed9aSIngo Molnar } else if (expected_testcase_failures && !testcase_successes) {
2936cae2ed9aSIngo Molnar printk("--------------------------------------------------------\n");
2937cae2ed9aSIngo Molnar printk("All %3d testcases failed, as expected. |\n",
2938cae2ed9aSIngo Molnar expected_testcase_failures);
2939cae2ed9aSIngo Molnar printk("----------------------------------------\n");
2940cae2ed9aSIngo Molnar debug_locks = 1;
2941cae2ed9aSIngo Molnar } else {
2942cae2ed9aSIngo Molnar printk("-------------------------------------------------------\n");
2943cae2ed9aSIngo Molnar printk("Good, all %3d testcases passed! |\n",
2944cae2ed9aSIngo Molnar testcase_successes);
2945cae2ed9aSIngo Molnar printk("---------------------------------\n");
2946cae2ed9aSIngo Molnar debug_locks = 1;
2947cae2ed9aSIngo Molnar }
2948cdc84d79SBart Van Assche lockdep_set_selftest_task(NULL);
2949cae2ed9aSIngo Molnar debug_locks_silent = 0;
2950cae2ed9aSIngo Molnar }
2951