blob: 3508e2c804656b3e521e5c2c1c87002d5ccf7c05 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/*
2 * lib/locking-selftest.c
3 *
4 * Testsuite for various locking APIs: spinlocks, rwlocks,
5 * mutexes and rw-semaphores.
6 *
7 * It is checking both false positives and false negatives.
8 *
9 * Started by Ingo Molnar:
10 *
11 * Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
12 */
13#include <linux/rwsem.h>
14#include <linux/mutex.h>
15#include <linux/sched.h>
16#include <linux/delay.h>
17#include <linux/lockdep.h>
18#include <linux/spinlock.h>
19#include <linux/kallsyms.h>
20#include <linux/interrupt.h>
21#include <linux/debug_locks.h>
22#include <linux/irqflags.h>
23
24/*
25 * Change this to 1 if you want to see the failure printouts:
26 */
27static unsigned int debug_locks_verbose;
28
29static int __init setup_debug_locks_verbose(char *str)
30{
31 get_option(&str, &debug_locks_verbose);
32
33 return 1;
34}
35
36__setup("debug_locks_verbose=", setup_debug_locks_verbose);
37
38#define FAILURE 0
39#define SUCCESS 1
40
41#define LOCKTYPE_SPIN 0x1
42#define LOCKTYPE_RWLOCK 0x2
43#define LOCKTYPE_MUTEX 0x4
44#define LOCKTYPE_RWSEM 0x8
45
46/*
47 * Normal standalone locks, for the circular and irq-context
48 * dependency tests:
49 */
50static DEFINE_RAW_SPINLOCK(lock_A);
51static DEFINE_RAW_SPINLOCK(lock_B);
52static DEFINE_RAW_SPINLOCK(lock_C);
53static DEFINE_RAW_SPINLOCK(lock_D);
54
55static DEFINE_RWLOCK(rwlock_A);
56static DEFINE_RWLOCK(rwlock_B);
57static DEFINE_RWLOCK(rwlock_C);
58static DEFINE_RWLOCK(rwlock_D);
59
60static DEFINE_MUTEX(mutex_A);
61static DEFINE_MUTEX(mutex_B);
62static DEFINE_MUTEX(mutex_C);
63static DEFINE_MUTEX(mutex_D);
64
65static DECLARE_RWSEM(rwsem_A);
66static DECLARE_RWSEM(rwsem_B);
67static DECLARE_RWSEM(rwsem_C);
68static DECLARE_RWSEM(rwsem_D);
69
70/*
71 * Locks that we initialize dynamically as well so that
72 * e.g. X1 and X2 becomes two instances of the same class,
73 * but X* and Y* are different classes. We do this so that
74 * we do not trigger a real lockup:
75 */
76static DEFINE_RAW_SPINLOCK(lock_X1);
77static DEFINE_RAW_SPINLOCK(lock_X2);
78static DEFINE_RAW_SPINLOCK(lock_Y1);
79static DEFINE_RAW_SPINLOCK(lock_Y2);
80static DEFINE_RAW_SPINLOCK(lock_Z1);
81static DEFINE_RAW_SPINLOCK(lock_Z2);
82
83static DEFINE_RWLOCK(rwlock_X1);
84static DEFINE_RWLOCK(rwlock_X2);
85static DEFINE_RWLOCK(rwlock_Y1);
86static DEFINE_RWLOCK(rwlock_Y2);
87static DEFINE_RWLOCK(rwlock_Z1);
88static DEFINE_RWLOCK(rwlock_Z2);
89
90static DEFINE_MUTEX(mutex_X1);
91static DEFINE_MUTEX(mutex_X2);
92static DEFINE_MUTEX(mutex_Y1);
93static DEFINE_MUTEX(mutex_Y2);
94static DEFINE_MUTEX(mutex_Z1);
95static DEFINE_MUTEX(mutex_Z2);
96
97static DECLARE_RWSEM(rwsem_X1);
98static DECLARE_RWSEM(rwsem_X2);
99static DECLARE_RWSEM(rwsem_Y1);
100static DECLARE_RWSEM(rwsem_Y2);
101static DECLARE_RWSEM(rwsem_Z1);
102static DECLARE_RWSEM(rwsem_Z2);
103
104/*
105 * non-inlined runtime initializers, to let separate locks share
106 * the same lock-class:
107 */
108#define INIT_CLASS_FUNC(class) \
109static noinline void \
110init_class_##class(raw_spinlock_t *lock, rwlock_t *rwlock, \
111 struct mutex *mutex, struct rw_semaphore *rwsem)\
112{ \
113 raw_spin_lock_init(lock); \
114 rwlock_init(rwlock); \
115 mutex_init(mutex); \
116 init_rwsem(rwsem); \
117}
118
119INIT_CLASS_FUNC(X)
120INIT_CLASS_FUNC(Y)
121INIT_CLASS_FUNC(Z)
122
123static void init_shared_classes(void)
124{
125 init_class_X(&lock_X1, &rwlock_X1, &mutex_X1, &rwsem_X1);
126 init_class_X(&lock_X2, &rwlock_X2, &mutex_X2, &rwsem_X2);
127
128 init_class_Y(&lock_Y1, &rwlock_Y1, &mutex_Y1, &rwsem_Y1);
129 init_class_Y(&lock_Y2, &rwlock_Y2, &mutex_Y2, &rwsem_Y2);
130
131 init_class_Z(&lock_Z1, &rwlock_Z1, &mutex_Z1, &rwsem_Z1);
132 init_class_Z(&lock_Z2, &rwlock_Z2, &mutex_Z2, &rwsem_Z2);
133}
134
135/*
136 * For spinlocks and rwlocks we also do hardirq-safe / softirq-safe tests.
137 * The following functions use a lock from a simulated hardirq/softirq
138 * context, causing the locks to be marked as hardirq-safe/softirq-safe:
139 */
140
141#define HARDIRQ_DISABLE local_irq_disable
142#define HARDIRQ_ENABLE local_irq_enable
143
144#define HARDIRQ_ENTER() \
145 local_irq_disable(); \
146 __irq_enter(); \
147 WARN_ON(!in_irq());
148
149#define HARDIRQ_EXIT() \
150 __irq_exit(); \
151 local_irq_enable();
152
153#define SOFTIRQ_DISABLE local_bh_disable
154#define SOFTIRQ_ENABLE local_bh_enable
155
156#define SOFTIRQ_ENTER() \
157 local_bh_disable(); \
158 local_irq_disable(); \
159 lockdep_softirq_enter(); \
160 WARN_ON(!in_softirq());
161
162#define SOFTIRQ_EXIT() \
163 lockdep_softirq_exit(); \
164 local_irq_enable(); \
165 local_bh_enable();
166
167/*
168 * Shortcuts for lock/unlock API variants, to keep
169 * the testcases compact:
170 */
171#define L(x) raw_spin_lock(&lock_##x)
172#define U(x) raw_spin_unlock(&lock_##x)
173#define LU(x) L(x); U(x)
174#define SI(x) raw_spin_lock_init(&lock_##x)
175
176#define WL(x) write_lock(&rwlock_##x)
177#define WU(x) write_unlock(&rwlock_##x)
178#define WLU(x) WL(x); WU(x)
179
180#define RL(x) read_lock(&rwlock_##x)
181#define RU(x) read_unlock(&rwlock_##x)
182#define RLU(x) RL(x); RU(x)
183#define RWI(x) rwlock_init(&rwlock_##x)
184
185#define ML(x) mutex_lock(&mutex_##x)
186#define MU(x) mutex_unlock(&mutex_##x)
187#define MI(x) mutex_init(&mutex_##x)
188
189#define WSL(x) down_write(&rwsem_##x)
190#define WSU(x) up_write(&rwsem_##x)
191
192#define RSL(x) down_read(&rwsem_##x)
193#define RSU(x) up_read(&rwsem_##x)
194#define RWSI(x) init_rwsem(&rwsem_##x)
195
196#define LOCK_UNLOCK_2(x,y) LOCK(x); LOCK(y); UNLOCK(y); UNLOCK(x)
197
198/*
199 * Generate different permutations of the same testcase, using
200 * the same basic lock-dependency/state events:
201 */
202
203#define GENERATE_TESTCASE(name) \
204 \
205static void name(void) { E(); }
206
207#define GENERATE_PERMUTATIONS_2_EVENTS(name) \
208 \
209static void name##_12(void) { E1(); E2(); } \
210static void name##_21(void) { E2(); E1(); }
211
212#define GENERATE_PERMUTATIONS_3_EVENTS(name) \
213 \
214static void name##_123(void) { E1(); E2(); E3(); } \
215static void name##_132(void) { E1(); E3(); E2(); } \
216static void name##_213(void) { E2(); E1(); E3(); } \
217static void name##_231(void) { E2(); E3(); E1(); } \
218static void name##_312(void) { E3(); E1(); E2(); } \
219static void name##_321(void) { E3(); E2(); E1(); }
220
221/*
222 * AA deadlock:
223 */
224
225#define E() \
226 \
227 LOCK(X1); \
228 LOCK(X2); /* this one should fail */
229
230/*
231 * 6 testcases:
232 */
233#include "locking-selftest-spin.h"
234GENERATE_TESTCASE(AA_spin)
235#include "locking-selftest-wlock.h"
236GENERATE_TESTCASE(AA_wlock)
237#include "locking-selftest-rlock.h"
238GENERATE_TESTCASE(AA_rlock)
239#include "locking-selftest-mutex.h"
240GENERATE_TESTCASE(AA_mutex)
241#include "locking-selftest-wsem.h"
242GENERATE_TESTCASE(AA_wsem)
243#include "locking-selftest-rsem.h"
244GENERATE_TESTCASE(AA_rsem)
245
246#undef E
247
248/*
249 * Special-case for read-locking, they are
250 * allowed to recurse on the same lock class:
251 */
252static void rlock_AA1(void)
253{
254 RL(X1);
255 RL(X1); // this one should NOT fail
256}
257
258static void rlock_AA1B(void)
259{
260 RL(X1);
261 RL(X2); // this one should NOT fail
262}
263
264static void rsem_AA1(void)
265{
266 RSL(X1);
267 RSL(X1); // this one should fail
268}
269
270static void rsem_AA1B(void)
271{
272 RSL(X1);
273 RSL(X2); // this one should fail
274}
275/*
276 * The mixing of read and write locks is not allowed:
277 */
278static void rlock_AA2(void)
279{
280 RL(X1);
281 WL(X2); // this one should fail
282}
283
284static void rsem_AA2(void)
285{
286 RSL(X1);
287 WSL(X2); // this one should fail
288}
289
290static void rlock_AA3(void)
291{
292 WL(X1);
293 RL(X2); // this one should fail
294}
295
296static void rsem_AA3(void)
297{
298 WSL(X1);
299 RSL(X2); // this one should fail
300}
301
302/*
303 * ABBA deadlock:
304 */
305
306#define E() \
307 \
308 LOCK_UNLOCK_2(A, B); \
309 LOCK_UNLOCK_2(B, A); /* fail */
310
311/*
312 * 6 testcases:
313 */
314#include "locking-selftest-spin.h"
315GENERATE_TESTCASE(ABBA_spin)
316#include "locking-selftest-wlock.h"
317GENERATE_TESTCASE(ABBA_wlock)
318#include "locking-selftest-rlock.h"
319GENERATE_TESTCASE(ABBA_rlock)
320#include "locking-selftest-mutex.h"
321GENERATE_TESTCASE(ABBA_mutex)
322#include "locking-selftest-wsem.h"
323GENERATE_TESTCASE(ABBA_wsem)
324#include "locking-selftest-rsem.h"
325GENERATE_TESTCASE(ABBA_rsem)
326
327#undef E
328
329/*
330 * AB BC CA deadlock:
331 */
332
333#define E() \
334 \
335 LOCK_UNLOCK_2(A, B); \
336 LOCK_UNLOCK_2(B, C); \
337 LOCK_UNLOCK_2(C, A); /* fail */
338
339/*
340 * 6 testcases:
341 */
342#include "locking-selftest-spin.h"
343GENERATE_TESTCASE(ABBCCA_spin)
344#include "locking-selftest-wlock.h"
345GENERATE_TESTCASE(ABBCCA_wlock)
346#include "locking-selftest-rlock.h"
347GENERATE_TESTCASE(ABBCCA_rlock)
348#include "locking-selftest-mutex.h"
349GENERATE_TESTCASE(ABBCCA_mutex)
350#include "locking-selftest-wsem.h"
351GENERATE_TESTCASE(ABBCCA_wsem)
352#include "locking-selftest-rsem.h"
353GENERATE_TESTCASE(ABBCCA_rsem)
354
355#undef E
356
357/*
358 * AB CA BC deadlock:
359 */
360
361#define E() \
362 \
363 LOCK_UNLOCK_2(A, B); \
364 LOCK_UNLOCK_2(C, A); \
365 LOCK_UNLOCK_2(B, C); /* fail */
366
367/*
368 * 6 testcases:
369 */
370#include "locking-selftest-spin.h"
371GENERATE_TESTCASE(ABCABC_spin)
372#include "locking-selftest-wlock.h"
373GENERATE_TESTCASE(ABCABC_wlock)
374#include "locking-selftest-rlock.h"
375GENERATE_TESTCASE(ABCABC_rlock)
376#include "locking-selftest-mutex.h"
377GENERATE_TESTCASE(ABCABC_mutex)
378#include "locking-selftest-wsem.h"
379GENERATE_TESTCASE(ABCABC_wsem)
380#include "locking-selftest-rsem.h"
381GENERATE_TESTCASE(ABCABC_rsem)
382
383#undef E
384
385/*
386 * AB BC CD DA deadlock:
387 */
388
389#define E() \
390 \
391 LOCK_UNLOCK_2(A, B); \
392 LOCK_UNLOCK_2(B, C); \
393 LOCK_UNLOCK_2(C, D); \
394 LOCK_UNLOCK_2(D, A); /* fail */
395
396/*
397 * 6 testcases:
398 */
399#include "locking-selftest-spin.h"
400GENERATE_TESTCASE(ABBCCDDA_spin)
401#include "locking-selftest-wlock.h"
402GENERATE_TESTCASE(ABBCCDDA_wlock)
403#include "locking-selftest-rlock.h"
404GENERATE_TESTCASE(ABBCCDDA_rlock)
405#include "locking-selftest-mutex.h"
406GENERATE_TESTCASE(ABBCCDDA_mutex)
407#include "locking-selftest-wsem.h"
408GENERATE_TESTCASE(ABBCCDDA_wsem)
409#include "locking-selftest-rsem.h"
410GENERATE_TESTCASE(ABBCCDDA_rsem)
411
412#undef E
413
414/*
415 * AB CD BD DA deadlock:
416 */
417#define E() \
418 \
419 LOCK_UNLOCK_2(A, B); \
420 LOCK_UNLOCK_2(C, D); \
421 LOCK_UNLOCK_2(B, D); \
422 LOCK_UNLOCK_2(D, A); /* fail */
423
424/*
425 * 6 testcases:
426 */
427#include "locking-selftest-spin.h"
428GENERATE_TESTCASE(ABCDBDDA_spin)
429#include "locking-selftest-wlock.h"
430GENERATE_TESTCASE(ABCDBDDA_wlock)
431#include "locking-selftest-rlock.h"
432GENERATE_TESTCASE(ABCDBDDA_rlock)
433#include "locking-selftest-mutex.h"
434GENERATE_TESTCASE(ABCDBDDA_mutex)
435#include "locking-selftest-wsem.h"
436GENERATE_TESTCASE(ABCDBDDA_wsem)
437#include "locking-selftest-rsem.h"
438GENERATE_TESTCASE(ABCDBDDA_rsem)
439
440#undef E
441
442/*
443 * AB CD BC DA deadlock:
444 */
445#define E() \
446 \
447 LOCK_UNLOCK_2(A, B); \
448 LOCK_UNLOCK_2(C, D); \
449 LOCK_UNLOCK_2(B, C); \
450 LOCK_UNLOCK_2(D, A); /* fail */
451
452/*
453 * 6 testcases:
454 */
455#include "locking-selftest-spin.h"
456GENERATE_TESTCASE(ABCDBCDA_spin)
457#include "locking-selftest-wlock.h"
458GENERATE_TESTCASE(ABCDBCDA_wlock)
459#include "locking-selftest-rlock.h"
460GENERATE_TESTCASE(ABCDBCDA_rlock)
461#include "locking-selftest-mutex.h"
462GENERATE_TESTCASE(ABCDBCDA_mutex)
463#include "locking-selftest-wsem.h"
464GENERATE_TESTCASE(ABCDBCDA_wsem)
465#include "locking-selftest-rsem.h"
466GENERATE_TESTCASE(ABCDBCDA_rsem)
467
468#undef E
469
470/*
471 * Double unlock:
472 */
473#define E() \
474 \
475 LOCK(A); \
476 UNLOCK(A); \
477 UNLOCK(A); /* fail */
478
479/*
480 * 6 testcases:
481 */
482#include "locking-selftest-spin.h"
483GENERATE_TESTCASE(double_unlock_spin)
484#include "locking-selftest-wlock.h"
485GENERATE_TESTCASE(double_unlock_wlock)
486#include "locking-selftest-rlock.h"
487GENERATE_TESTCASE(double_unlock_rlock)
488#include "locking-selftest-mutex.h"
489GENERATE_TESTCASE(double_unlock_mutex)
490#include "locking-selftest-wsem.h"
491GENERATE_TESTCASE(double_unlock_wsem)
492#include "locking-selftest-rsem.h"
493GENERATE_TESTCASE(double_unlock_rsem)
494
495#undef E
496
497/*
498 * Bad unlock ordering:
499 */
500#define E() \
501 \
502 LOCK(A); \
503 LOCK(B); \
504 UNLOCK(A); /* fail */ \
505 UNLOCK(B);
506
507/*
508 * 6 testcases:
509 */
510#include "locking-selftest-spin.h"
511GENERATE_TESTCASE(bad_unlock_order_spin)
512#include "locking-selftest-wlock.h"
513GENERATE_TESTCASE(bad_unlock_order_wlock)
514#include "locking-selftest-rlock.h"
515GENERATE_TESTCASE(bad_unlock_order_rlock)
516#include "locking-selftest-mutex.h"
517GENERATE_TESTCASE(bad_unlock_order_mutex)
518#include "locking-selftest-wsem.h"
519GENERATE_TESTCASE(bad_unlock_order_wsem)
520#include "locking-selftest-rsem.h"
521GENERATE_TESTCASE(bad_unlock_order_rsem)
522
523#undef E
524
525/*
526 * initializing a held lock:
527 */
528#define E() \
529 \
530 LOCK(A); \
531 INIT(A); /* fail */
532
533/*
534 * 6 testcases:
535 */
536#include "locking-selftest-spin.h"
537GENERATE_TESTCASE(init_held_spin)
538#include "locking-selftest-wlock.h"
539GENERATE_TESTCASE(init_held_wlock)
540#include "locking-selftest-rlock.h"
541GENERATE_TESTCASE(init_held_rlock)
542#include "locking-selftest-mutex.h"
543GENERATE_TESTCASE(init_held_mutex)
544#include "locking-selftest-wsem.h"
545GENERATE_TESTCASE(init_held_wsem)
546#include "locking-selftest-rsem.h"
547GENERATE_TESTCASE(init_held_rsem)
548
549#undef E
550
551/*
552 * locking an irq-safe lock with irqs enabled:
553 */
554#define E1() \
555 \
556 IRQ_ENTER(); \
557 LOCK(A); \
558 UNLOCK(A); \
559 IRQ_EXIT();
560
561#define E2() \
562 \
563 LOCK(A); \
564 UNLOCK(A);
565
566/*
567 * Generate 24 testcases:
568 */
569#include "locking-selftest-spin-hardirq.h"
570GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_spin)
571
572#ifndef CONFIG_PREEMPT_RT_FULL
573
574#include "locking-selftest-rlock-hardirq.h"
575GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_rlock)
576
577#include "locking-selftest-wlock-hardirq.h"
578GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_wlock)
579
580#include "locking-selftest-spin-softirq.h"
581GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_spin)
582
583#include "locking-selftest-rlock-softirq.h"
584GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_rlock)
585
586#include "locking-selftest-wlock-softirq.h"
587GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_wlock)
588
589#endif
590
591#undef E1
592#undef E2
593
594#ifndef CONFIG_PREEMPT_RT_FULL
595/*
596 * Enabling hardirqs with a softirq-safe lock held:
597 */
598#define E1() \
599 \
600 SOFTIRQ_ENTER(); \
601 LOCK(A); \
602 UNLOCK(A); \
603 SOFTIRQ_EXIT();
604
605#define E2() \
606 \
607 HARDIRQ_DISABLE(); \
608 LOCK(A); \
609 HARDIRQ_ENABLE(); \
610 UNLOCK(A);
611
612/*
613 * Generate 12 testcases:
614 */
615#include "locking-selftest-spin.h"
616GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_spin)
617
618#include "locking-selftest-wlock.h"
619GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_wlock)
620
621#include "locking-selftest-rlock.h"
622GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_rlock)
623
624#undef E1
625#undef E2
626
627#endif
628
629/*
630 * Enabling irqs with an irq-safe lock held:
631 */
632#define E1() \
633 \
634 IRQ_ENTER(); \
635 LOCK(A); \
636 UNLOCK(A); \
637 IRQ_EXIT();
638
639#define E2() \
640 \
641 IRQ_DISABLE(); \
642 LOCK(A); \
643 IRQ_ENABLE(); \
644 UNLOCK(A);
645
646/*
647 * Generate 24 testcases:
648 */
649#include "locking-selftest-spin-hardirq.h"
650GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_spin)
651
652#ifndef CONFIG_PREEMPT_RT_FULL
653
654#include "locking-selftest-rlock-hardirq.h"
655GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_rlock)
656
657#include "locking-selftest-wlock-hardirq.h"
658GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_wlock)
659
660#include "locking-selftest-spin-softirq.h"
661GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_spin)
662
663#include "locking-selftest-rlock-softirq.h"
664GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_rlock)
665
666#include "locking-selftest-wlock-softirq.h"
667GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock)
668
669#endif
670
671#undef E1
672#undef E2
673
674/*
675 * Acquiring a irq-unsafe lock while holding an irq-safe-lock:
676 */
677#define E1() \
678 \
679 LOCK(A); \
680 LOCK(B); \
681 UNLOCK(B); \
682 UNLOCK(A); \
683
684#define E2() \
685 \
686 LOCK(B); \
687 UNLOCK(B);
688
689#define E3() \
690 \
691 IRQ_ENTER(); \
692 LOCK(A); \
693 UNLOCK(A); \
694 IRQ_EXIT();
695
696/*
697 * Generate 36 testcases:
698 */
699#include "locking-selftest-spin-hardirq.h"
700GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_spin)
701
702#ifndef CONFIG_PREEMPT_RT_FULL
703
704#include "locking-selftest-rlock-hardirq.h"
705GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_rlock)
706
707#include "locking-selftest-wlock-hardirq.h"
708GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_wlock)
709
710#include "locking-selftest-spin-softirq.h"
711GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_spin)
712
713#include "locking-selftest-rlock-softirq.h"
714GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_rlock)
715
716#include "locking-selftest-wlock-softirq.h"
717GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock)
718
719#endif
720
721#undef E1
722#undef E2
723#undef E3
724
725/*
726 * If a lock turns into softirq-safe, but earlier it took
727 * a softirq-unsafe lock:
728 */
729
730#define E1() \
731 IRQ_DISABLE(); \
732 LOCK(A); \
733 LOCK(B); \
734 UNLOCK(B); \
735 UNLOCK(A); \
736 IRQ_ENABLE();
737
738#define E2() \
739 LOCK(B); \
740 UNLOCK(B);
741
742#define E3() \
743 IRQ_ENTER(); \
744 LOCK(A); \
745 UNLOCK(A); \
746 IRQ_EXIT();
747
748/*
749 * Generate 36 testcases:
750 */
751#include "locking-selftest-spin-hardirq.h"
752GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_spin)
753
754#ifndef CONFIG_PREEMPT_RT_FULL
755
756#include "locking-selftest-rlock-hardirq.h"
757GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_rlock)
758
759#include "locking-selftest-wlock-hardirq.h"
760GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_wlock)
761
762#include "locking-selftest-spin-softirq.h"
763GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_spin)
764
765#include "locking-selftest-rlock-softirq.h"
766GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_rlock)
767
768#include "locking-selftest-wlock-softirq.h"
769GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_wlock)
770
771#endif
772
773#undef E1
774#undef E2
775#undef E3
776
777#ifndef CONFIG_PREEMPT_RT_FULL
778
779/*
780 * read-lock / write-lock irq inversion.
781 *
782 * Deadlock scenario:
783 *
784 * CPU#1 is at #1, i.e. it has write-locked A, but has not
785 * taken B yet.
786 *
787 * CPU#2 is at #2, i.e. it has locked B.
788 *
789 * Hardirq hits CPU#2 at point #2 and is trying to read-lock A.
790 *
791 * The deadlock occurs because CPU#1 will spin on B, and CPU#2
792 * will spin on A.
793 */
794
795#define E1() \
796 \
797 IRQ_DISABLE(); \
798 WL(A); \
799 LOCK(B); \
800 UNLOCK(B); \
801 WU(A); \
802 IRQ_ENABLE();
803
804#define E2() \
805 \
806 LOCK(B); \
807 UNLOCK(B);
808
809#define E3() \
810 \
811 IRQ_ENTER(); \
812 RL(A); \
813 RU(A); \
814 IRQ_EXIT();
815
816/*
817 * Generate 36 testcases:
818 */
819#include "locking-selftest-spin-hardirq.h"
820GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_spin)
821
822#include "locking-selftest-rlock-hardirq.h"
823GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_rlock)
824
825#include "locking-selftest-wlock-hardirq.h"
826GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_wlock)
827
828#include "locking-selftest-spin-softirq.h"
829GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_spin)
830
831#include "locking-selftest-rlock-softirq.h"
832GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_rlock)
833
834#include "locking-selftest-wlock-softirq.h"
835GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_wlock)
836
837#undef E1
838#undef E2
839#undef E3
840
841#endif
842
843#ifndef CONFIG_PREEMPT_RT_FULL
844
845/*
846 * read-lock / write-lock recursion that is actually safe.
847 */
848
849#define E1() \
850 \
851 IRQ_DISABLE(); \
852 WL(A); \
853 WU(A); \
854 IRQ_ENABLE();
855
856#define E2() \
857 \
858 RL(A); \
859 RU(A); \
860
861#define E3() \
862 \
863 IRQ_ENTER(); \
864 RL(A); \
865 L(B); \
866 U(B); \
867 RU(A); \
868 IRQ_EXIT();
869
870/*
871 * Generate 12 testcases:
872 */
873#include "locking-selftest-hardirq.h"
874GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard)
875
876#include "locking-selftest-softirq.h"
877GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft)
878
879#undef E1
880#undef E2
881#undef E3
882
883#endif
884
885/*
886 * read-lock / write-lock recursion that is unsafe.
887 */
888
889#define E1() \
890 \
891 IRQ_DISABLE(); \
892 L(B); \
893 WL(A); \
894 WU(A); \
895 U(B); \
896 IRQ_ENABLE();
897
898#define E2() \
899 \
900 RL(A); \
901 RU(A); \
902
903#define E3() \
904 \
905 IRQ_ENTER(); \
906 L(B); \
907 U(B); \
908 IRQ_EXIT();
909
910/*
911 * Generate 12 testcases:
912 */
913#include "locking-selftest-hardirq.h"
914// GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard)
915
916#include "locking-selftest-softirq.h"
917// GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft)
918
919#ifdef CONFIG_DEBUG_LOCK_ALLOC
920# define I_SPINLOCK(x) lockdep_reset_lock(&lock_##x.dep_map)
921# define I_RWLOCK(x) lockdep_reset_lock(&rwlock_##x.dep_map)
922# define I_MUTEX(x) lockdep_reset_lock(&mutex_##x.dep_map)
923# define I_RWSEM(x) lockdep_reset_lock(&rwsem_##x.dep_map)
924#else
925# define I_SPINLOCK(x)
926# define I_RWLOCK(x)
927# define I_MUTEX(x)
928# define I_RWSEM(x)
929#endif
930
931#define I1(x) \
932 do { \
933 I_SPINLOCK(x); \
934 I_RWLOCK(x); \
935 I_MUTEX(x); \
936 I_RWSEM(x); \
937 } while (0)
938
939#define I2(x) \
940 do { \
941 raw_spin_lock_init(&lock_##x); \
942 rwlock_init(&rwlock_##x); \
943 mutex_init(&mutex_##x); \
944 init_rwsem(&rwsem_##x); \
945 } while (0)
946
947static void reset_locks(void)
948{
949 local_irq_disable();
950 I1(A); I1(B); I1(C); I1(D);
951 I1(X1); I1(X2); I1(Y1); I1(Y2); I1(Z1); I1(Z2);
952 lockdep_reset();
953 I2(A); I2(B); I2(C); I2(D);
954 init_shared_classes();
955 local_irq_enable();
956}
957
958#undef I
959
960static int testcase_total;
961static int testcase_successes;
962static int expected_testcase_failures;
963static int unexpected_testcase_failures;
964
965static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask)
966{
967 unsigned long saved_preempt_count = preempt_count();
968 int expected_failure = 0;
969
970 WARN_ON(irqs_disabled());
971
972 testcase_fn();
973 /*
974 * Filter out expected failures:
975 */
976#ifndef CONFIG_PROVE_LOCKING
977 if ((lockclass_mask & LOCKTYPE_SPIN) && debug_locks != expected)
978 expected_failure = 1;
979 if ((lockclass_mask & LOCKTYPE_RWLOCK) && debug_locks != expected)
980 expected_failure = 1;
981 if ((lockclass_mask & LOCKTYPE_MUTEX) && debug_locks != expected)
982 expected_failure = 1;
983 if ((lockclass_mask & LOCKTYPE_RWSEM) && debug_locks != expected)
984 expected_failure = 1;
985#endif
986 if (debug_locks != expected) {
987 if (expected_failure) {
988 expected_testcase_failures++;
989 printk("failed|");
990 } else {
991 unexpected_testcase_failures++;
992
993 printk("FAILED|");
994 dump_stack();
995 }
996 } else {
997 testcase_successes++;
998 printk(" ok |");
999 }
1000 testcase_total++;
1001
1002 if (debug_locks_verbose)
1003 printk(" lockclass mask: %x, debug_locks: %d, expected: %d\n",
1004 lockclass_mask, debug_locks, expected);
1005 /*
1006 * Some tests (e.g. double-unlock) might corrupt the preemption
1007 * count, so restore it:
1008 */
1009 preempt_count() = saved_preempt_count;
1010#ifdef CONFIG_TRACE_IRQFLAGS
1011 if (softirq_count())
1012 current->softirqs_enabled = 0;
1013 else
1014 current->softirqs_enabled = 1;
1015#endif
1016
1017 reset_locks();
1018}
1019
1020static inline void print_testname(const char *testname)
1021{
1022 printk("%33s:", testname);
1023}
1024
1025#define DO_TESTCASE_1(desc, name, nr) \
1026 print_testname(desc"/"#nr); \
1027 dotest(name##_##nr, SUCCESS, LOCKTYPE_RWLOCK); \
1028 printk("\n");
1029
1030#define DO_TESTCASE_1B(desc, name, nr) \
1031 print_testname(desc"/"#nr); \
1032 dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK); \
1033 printk("\n");
1034
1035#define DO_TESTCASE_3(desc, name, nr) \
1036 print_testname(desc"/"#nr); \
1037 dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN); \
1038 dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK); \
1039 dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK); \
1040 printk("\n");
1041
1042#define DO_TESTCASE_3RW(desc, name, nr) \
1043 print_testname(desc"/"#nr); \
1044 dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN|LOCKTYPE_RWLOCK);\
1045 dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK); \
1046 dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK); \
1047 printk("\n");
1048
1049#define DO_TESTCASE_6(desc, name) \
1050 print_testname(desc); \
1051 dotest(name##_spin, FAILURE, LOCKTYPE_SPIN); \
1052 dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK); \
1053 dotest(name##_rlock, FAILURE, LOCKTYPE_RWLOCK); \
1054 dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \
1055 dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \
1056 dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \
1057 printk("\n");
1058
1059#define DO_TESTCASE_6_SUCCESS(desc, name) \
1060 print_testname(desc); \
1061 dotest(name##_spin, SUCCESS, LOCKTYPE_SPIN); \
1062 dotest(name##_wlock, SUCCESS, LOCKTYPE_RWLOCK); \
1063 dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK); \
1064 dotest(name##_mutex, SUCCESS, LOCKTYPE_MUTEX); \
1065 dotest(name##_wsem, SUCCESS, LOCKTYPE_RWSEM); \
1066 dotest(name##_rsem, SUCCESS, LOCKTYPE_RWSEM); \
1067 printk("\n");
1068
1069/*
1070 * 'read' variant: rlocks must not trigger.
1071 */
1072#define DO_TESTCASE_6R(desc, name) \
1073 print_testname(desc); \
1074 dotest(name##_spin, FAILURE, LOCKTYPE_SPIN); \
1075 dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK); \
1076 dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK); \
1077 dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \
1078 dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \
1079 dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \
1080 printk("\n");
1081
1082#define DO_TESTCASE_2I(desc, name, nr) \
1083 DO_TESTCASE_1("hard-"desc, name##_hard, nr); \
1084 DO_TESTCASE_1("soft-"desc, name##_soft, nr);
1085
1086#define DO_TESTCASE_2IB(desc, name, nr) \
1087 DO_TESTCASE_1B("hard-"desc, name##_hard, nr); \
1088 DO_TESTCASE_1B("soft-"desc, name##_soft, nr);
1089
1090#define DO_TESTCASE_6I(desc, name, nr) \
1091 DO_TESTCASE_3("hard-"desc, name##_hard, nr); \
1092 DO_TESTCASE_3("soft-"desc, name##_soft, nr);
1093
1094#define DO_TESTCASE_6IRW(desc, name, nr) \
1095 DO_TESTCASE_3RW("hard-"desc, name##_hard, nr); \
1096 DO_TESTCASE_3RW("soft-"desc, name##_soft, nr);
1097
1098#define DO_TESTCASE_2x3(desc, name) \
1099 DO_TESTCASE_3(desc, name, 12); \
1100 DO_TESTCASE_3(desc, name, 21);
1101
1102#define DO_TESTCASE_2x6(desc, name) \
1103 DO_TESTCASE_6I(desc, name, 12); \
1104 DO_TESTCASE_6I(desc, name, 21);
1105
1106#define DO_TESTCASE_6x2(desc, name) \
1107 DO_TESTCASE_2I(desc, name, 123); \
1108 DO_TESTCASE_2I(desc, name, 132); \
1109 DO_TESTCASE_2I(desc, name, 213); \
1110 DO_TESTCASE_2I(desc, name, 231); \
1111 DO_TESTCASE_2I(desc, name, 312); \
1112 DO_TESTCASE_2I(desc, name, 321);
1113
1114#define DO_TESTCASE_6x2B(desc, name) \
1115 DO_TESTCASE_2IB(desc, name, 123); \
1116 DO_TESTCASE_2IB(desc, name, 132); \
1117 DO_TESTCASE_2IB(desc, name, 213); \
1118 DO_TESTCASE_2IB(desc, name, 231); \
1119 DO_TESTCASE_2IB(desc, name, 312); \
1120 DO_TESTCASE_2IB(desc, name, 321);
1121
1122#define DO_TESTCASE_6x6(desc, name) \
1123 DO_TESTCASE_6I(desc, name, 123); \
1124 DO_TESTCASE_6I(desc, name, 132); \
1125 DO_TESTCASE_6I(desc, name, 213); \
1126 DO_TESTCASE_6I(desc, name, 231); \
1127 DO_TESTCASE_6I(desc, name, 312); \
1128 DO_TESTCASE_6I(desc, name, 321);
1129
1130#define DO_TESTCASE_6x6RW(desc, name) \
1131 DO_TESTCASE_6IRW(desc, name, 123); \
1132 DO_TESTCASE_6IRW(desc, name, 132); \
1133 DO_TESTCASE_6IRW(desc, name, 213); \
1134 DO_TESTCASE_6IRW(desc, name, 231); \
1135 DO_TESTCASE_6IRW(desc, name, 312); \
1136 DO_TESTCASE_6IRW(desc, name, 321);
1137
1138
1139void locking_selftest(void)
1140{
1141 /*
1142 * Got a locking failure before the selftest ran?
1143 */
1144 if (!debug_locks) {
1145 printk("----------------------------------\n");
1146 printk("| Locking API testsuite disabled |\n");
1147 printk("----------------------------------\n");
1148 return;
1149 }
1150
1151 /*
1152 * Run the testsuite:
1153 */
1154 printk("------------------------\n");
1155 printk("| Locking API testsuite:\n");
1156 printk("----------------------------------------------------------------------------\n");
1157 printk(" | spin |wlock |rlock |mutex | wsem | rsem |\n");
1158 printk(" --------------------------------------------------------------------------\n");
1159
1160 init_shared_classes();
1161 debug_locks_silent = !debug_locks_verbose;
1162
1163 DO_TESTCASE_6R("A-A deadlock", AA);
1164 DO_TESTCASE_6R("A-B-B-A deadlock", ABBA);
1165 DO_TESTCASE_6R("A-B-B-C-C-A deadlock", ABBCCA);
1166 DO_TESTCASE_6R("A-B-C-A-B-C deadlock", ABCABC);
1167 DO_TESTCASE_6R("A-B-B-C-C-D-D-A deadlock", ABBCCDDA);
1168 DO_TESTCASE_6R("A-B-C-D-B-D-D-A deadlock", ABCDBDDA);
1169 DO_TESTCASE_6R("A-B-C-D-B-C-D-A deadlock", ABCDBCDA);
1170 DO_TESTCASE_6("double unlock", double_unlock);
1171 DO_TESTCASE_6("initialize held", init_held);
1172 DO_TESTCASE_6_SUCCESS("bad unlock order", bad_unlock_order);
1173
1174 printk(" --------------------------------------------------------------------------\n");
1175 print_testname("recursive read-lock");
1176 printk(" |");
1177 dotest(rlock_AA1, SUCCESS, LOCKTYPE_RWLOCK);
1178 printk(" |");
1179 dotest(rsem_AA1, FAILURE, LOCKTYPE_RWSEM);
1180 printk("\n");
1181
1182 print_testname("recursive read-lock #2");
1183 printk(" |");
1184 dotest(rlock_AA1B, SUCCESS, LOCKTYPE_RWLOCK);
1185 printk(" |");
1186 dotest(rsem_AA1B, FAILURE, LOCKTYPE_RWSEM);
1187 printk("\n");
1188
1189 print_testname("mixed read-write-lock");
1190 printk(" |");
1191 dotest(rlock_AA2, FAILURE, LOCKTYPE_RWLOCK);
1192 printk(" |");
1193 dotest(rsem_AA2, FAILURE, LOCKTYPE_RWSEM);
1194 printk("\n");
1195
1196 print_testname("mixed write-read-lock");
1197 printk(" |");
1198 dotest(rlock_AA3, FAILURE, LOCKTYPE_RWLOCK);
1199 printk(" |");
1200 dotest(rsem_AA3, FAILURE, LOCKTYPE_RWSEM);
1201 printk("\n");
1202
1203 printk(" --------------------------------------------------------------------------\n");
1204
1205#ifndef CONFIG_PREEMPT_RT_FULL
1206 /*
1207 * irq-context testcases:
1208 */
1209 DO_TESTCASE_2x6("irqs-on + irq-safe-A", irqsafe1);
1210 DO_TESTCASE_2x3("sirq-safe-A => hirqs-on", irqsafe2A);
1211 DO_TESTCASE_2x6("safe-A + irqs-on", irqsafe2B);
1212 DO_TESTCASE_6x6("safe-A + unsafe-B #1", irqsafe3);
1213 DO_TESTCASE_6x6("safe-A + unsafe-B #2", irqsafe4);
1214 DO_TESTCASE_6x6RW("irq lock-inversion", irq_inversion);
1215
1216 DO_TESTCASE_6x2("irq read-recursion", irq_read_recursion);
1217// DO_TESTCASE_6x2B("irq read-recursion #2", irq_read_recursion2);
1218#else
1219 /* On -rt, we only do hardirq context test for raw spinlock */
1220 DO_TESTCASE_1B("hard-irqs-on + irq-safe-A", irqsafe1_hard_spin, 12);
1221 DO_TESTCASE_1B("hard-irqs-on + irq-safe-A", irqsafe1_hard_spin, 21);
1222
1223 DO_TESTCASE_1B("hard-safe-A + irqs-on", irqsafe2B_hard_spin, 12);
1224 DO_TESTCASE_1B("hard-safe-A + irqs-on", irqsafe2B_hard_spin, 21);
1225
1226 DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 123);
1227 DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 132);
1228 DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 213);
1229 DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 231);
1230 DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 312);
1231 DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 321);
1232
1233 DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 123);
1234 DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 132);
1235 DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 213);
1236 DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 231);
1237 DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 312);
1238 DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 321);
1239#endif
1240
1241 if (unexpected_testcase_failures) {
1242 printk("-----------------------------------------------------------------\n");
1243 debug_locks = 0;
1244 printk("BUG: %3d unexpected failures (out of %3d) - debugging disabled! |\n",
1245 unexpected_testcase_failures, testcase_total);
1246 printk("-----------------------------------------------------------------\n");
1247 } else if (expected_testcase_failures && testcase_successes) {
1248 printk("--------------------------------------------------------\n");
1249 printk("%3d out of %3d testcases failed, as expected. |\n",
1250 expected_testcase_failures, testcase_total);
1251 printk("----------------------------------------------------\n");
1252 debug_locks = 1;
1253 } else if (expected_testcase_failures && !testcase_successes) {
1254 printk("--------------------------------------------------------\n");
1255 printk("All %3d testcases failed, as expected. |\n",
1256 expected_testcase_failures);
1257 printk("----------------------------------------\n");
1258 debug_locks = 1;
1259 } else {
1260 printk("-------------------------------------------------------\n");
1261 printk("Good, all %3d testcases passed! |\n",
1262 testcase_successes);
1263 printk("---------------------------------\n");
1264 debug_locks = 1;
1265 }
1266 debug_locks_silent = 0;
1267}