blob: dd09e517c492bab2f019f7e0a72e5085dd89acc8 [file] [log] [blame]
Ingo Molnarcae2ed92006-07-03 00:24:48 -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>
Maarten Lankhorst1b375dc2013-07-05 09:29:32 +020015#include <linux/ww_mutex.h>
Ingo Molnarcae2ed92006-07-03 00:24:48 -070016#include <linux/sched.h>
17#include <linux/delay.h>
Ingo Molnarfbb9ce952006-07-03 00:24:50 -070018#include <linux/lockdep.h>
Ingo Molnarcae2ed92006-07-03 00:24:48 -070019#include <linux/spinlock.h>
20#include <linux/kallsyms.h>
21#include <linux/interrupt.h>
22#include <linux/debug_locks.h>
23#include <linux/irqflags.h>
24
25/*
26 * Change this to 1 if you want to see the failure printouts:
27 */
28static unsigned int debug_locks_verbose;
29
Maarten Lankhorst1de99442013-06-20 13:31:24 +020030static DEFINE_WW_CLASS(ww_lockdep);
31
Ingo Molnarcae2ed92006-07-03 00:24:48 -070032static int __init setup_debug_locks_verbose(char *str)
33{
34 get_option(&str, &debug_locks_verbose);
35
36 return 1;
37}
38
39__setup("debug_locks_verbose=", setup_debug_locks_verbose);
40
41#define FAILURE 0
42#define SUCCESS 1
43
44#define LOCKTYPE_SPIN 0x1
45#define LOCKTYPE_RWLOCK 0x2
46#define LOCKTYPE_MUTEX 0x4
47#define LOCKTYPE_RWSEM 0x8
Maarten Lankhorst1de99442013-06-20 13:31:24 +020048#define LOCKTYPE_WW 0x10
49
50static struct ww_acquire_ctx t, t2;
Maarten Lankhorstf3cf1392013-06-20 13:31:42 +020051static struct ww_mutex o, o2, o3;
Ingo Molnarcae2ed92006-07-03 00:24:48 -070052
53/*
54 * Normal standalone locks, for the circular and irq-context
55 * dependency tests:
56 */
Yong Zhang9fb1b902012-04-16 15:01:55 +080057static DEFINE_RAW_SPINLOCK(lock_A);
58static DEFINE_RAW_SPINLOCK(lock_B);
59static DEFINE_RAW_SPINLOCK(lock_C);
60static DEFINE_RAW_SPINLOCK(lock_D);
Ingo Molnarcae2ed92006-07-03 00:24:48 -070061
62static DEFINE_RWLOCK(rwlock_A);
63static DEFINE_RWLOCK(rwlock_B);
64static DEFINE_RWLOCK(rwlock_C);
65static DEFINE_RWLOCK(rwlock_D);
66
67static DEFINE_MUTEX(mutex_A);
68static DEFINE_MUTEX(mutex_B);
69static DEFINE_MUTEX(mutex_C);
70static DEFINE_MUTEX(mutex_D);
71
72static DECLARE_RWSEM(rwsem_A);
73static DECLARE_RWSEM(rwsem_B);
74static DECLARE_RWSEM(rwsem_C);
75static DECLARE_RWSEM(rwsem_D);
76
77/*
78 * Locks that we initialize dynamically as well so that
79 * e.g. X1 and X2 becomes two instances of the same class,
80 * but X* and Y* are different classes. We do this so that
81 * we do not trigger a real lockup:
82 */
Yong Zhang9fb1b902012-04-16 15:01:55 +080083static DEFINE_RAW_SPINLOCK(lock_X1);
84static DEFINE_RAW_SPINLOCK(lock_X2);
85static DEFINE_RAW_SPINLOCK(lock_Y1);
86static DEFINE_RAW_SPINLOCK(lock_Y2);
87static DEFINE_RAW_SPINLOCK(lock_Z1);
88static DEFINE_RAW_SPINLOCK(lock_Z2);
Ingo Molnarcae2ed92006-07-03 00:24:48 -070089
90static DEFINE_RWLOCK(rwlock_X1);
91static DEFINE_RWLOCK(rwlock_X2);
92static DEFINE_RWLOCK(rwlock_Y1);
93static DEFINE_RWLOCK(rwlock_Y2);
94static DEFINE_RWLOCK(rwlock_Z1);
95static DEFINE_RWLOCK(rwlock_Z2);
96
97static DEFINE_MUTEX(mutex_X1);
98static DEFINE_MUTEX(mutex_X2);
99static DEFINE_MUTEX(mutex_Y1);
100static DEFINE_MUTEX(mutex_Y2);
101static DEFINE_MUTEX(mutex_Z1);
102static DEFINE_MUTEX(mutex_Z2);
103
104static DECLARE_RWSEM(rwsem_X1);
105static DECLARE_RWSEM(rwsem_X2);
106static DECLARE_RWSEM(rwsem_Y1);
107static DECLARE_RWSEM(rwsem_Y2);
108static DECLARE_RWSEM(rwsem_Z1);
109static DECLARE_RWSEM(rwsem_Z2);
110
111/*
112 * non-inlined runtime initializers, to let separate locks share
113 * the same lock-class:
114 */
115#define INIT_CLASS_FUNC(class) \
116static noinline void \
Yong Zhang9fb1b902012-04-16 15:01:55 +0800117init_class_##class(raw_spinlock_t *lock, rwlock_t *rwlock, \
118 struct mutex *mutex, struct rw_semaphore *rwsem)\
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700119{ \
Yong Zhang9fb1b902012-04-16 15:01:55 +0800120 raw_spin_lock_init(lock); \
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700121 rwlock_init(rwlock); \
122 mutex_init(mutex); \
123 init_rwsem(rwsem); \
124}
125
126INIT_CLASS_FUNC(X)
127INIT_CLASS_FUNC(Y)
128INIT_CLASS_FUNC(Z)
129
130static void init_shared_classes(void)
131{
132 init_class_X(&lock_X1, &rwlock_X1, &mutex_X1, &rwsem_X1);
133 init_class_X(&lock_X2, &rwlock_X2, &mutex_X2, &rwsem_X2);
134
135 init_class_Y(&lock_Y1, &rwlock_Y1, &mutex_Y1, &rwsem_Y1);
136 init_class_Y(&lock_Y2, &rwlock_Y2, &mutex_Y2, &rwsem_Y2);
137
138 init_class_Z(&lock_Z1, &rwlock_Z1, &mutex_Z1, &rwsem_Z1);
139 init_class_Z(&lock_Z2, &rwlock_Z2, &mutex_Z2, &rwsem_Z2);
140}
141
142/*
143 * For spinlocks and rwlocks we also do hardirq-safe / softirq-safe tests.
144 * The following functions use a lock from a simulated hardirq/softirq
145 * context, causing the locks to be marked as hardirq-safe/softirq-safe:
146 */
147
148#define HARDIRQ_DISABLE local_irq_disable
149#define HARDIRQ_ENABLE local_irq_enable
150
151#define HARDIRQ_ENTER() \
152 local_irq_disable(); \
Frederic Weisbeckerba9f2072011-05-20 02:09:54 +0200153 __irq_enter(); \
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700154 WARN_ON(!in_irq());
155
156#define HARDIRQ_EXIT() \
157 __irq_exit(); \
158 local_irq_enable();
159
160#define SOFTIRQ_DISABLE local_bh_disable
161#define SOFTIRQ_ENABLE local_bh_enable
162
163#define SOFTIRQ_ENTER() \
164 local_bh_disable(); \
165 local_irq_disable(); \
Ingo Molnard820ac42009-03-13 01:30:40 +0100166 lockdep_softirq_enter(); \
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700167 WARN_ON(!in_softirq());
168
169#define SOFTIRQ_EXIT() \
Ingo Molnard820ac42009-03-13 01:30:40 +0100170 lockdep_softirq_exit(); \
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700171 local_irq_enable(); \
172 local_bh_enable();
173
174/*
175 * Shortcuts for lock/unlock API variants, to keep
176 * the testcases compact:
177 */
Yong Zhang9fb1b902012-04-16 15:01:55 +0800178#define L(x) raw_spin_lock(&lock_##x)
179#define U(x) raw_spin_unlock(&lock_##x)
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700180#define LU(x) L(x); U(x)
Yong Zhang9fb1b902012-04-16 15:01:55 +0800181#define SI(x) raw_spin_lock_init(&lock_##x)
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700182
183#define WL(x) write_lock(&rwlock_##x)
184#define WU(x) write_unlock(&rwlock_##x)
185#define WLU(x) WL(x); WU(x)
186
187#define RL(x) read_lock(&rwlock_##x)
188#define RU(x) read_unlock(&rwlock_##x)
189#define RLU(x) RL(x); RU(x)
190#define RWI(x) rwlock_init(&rwlock_##x)
191
192#define ML(x) mutex_lock(&mutex_##x)
193#define MU(x) mutex_unlock(&mutex_##x)
194#define MI(x) mutex_init(&mutex_##x)
195
196#define WSL(x) down_write(&rwsem_##x)
197#define WSU(x) up_write(&rwsem_##x)
198
199#define RSL(x) down_read(&rwsem_##x)
200#define RSU(x) up_read(&rwsem_##x)
201#define RWSI(x) init_rwsem(&rwsem_##x)
202
Maarten Lankhorst1de99442013-06-20 13:31:24 +0200203#ifndef CONFIG_DEBUG_WW_MUTEX_SLOWPATH
204#define WWAI(x) ww_acquire_init(x, &ww_lockdep)
205#else
206#define WWAI(x) do { ww_acquire_init(x, &ww_lockdep); (x)->deadlock_inject_countdown = ~0U; } while (0)
207#endif
208#define WWAD(x) ww_acquire_done(x)
209#define WWAF(x) ww_acquire_fini(x)
210
211#define WWL(x, c) ww_mutex_lock(x, c)
212#define WWT(x) ww_mutex_trylock(x)
213#define WWL1(x) ww_mutex_lock(x, NULL)
214#define WWU(x) ww_mutex_unlock(x)
215
216
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700217#define LOCK_UNLOCK_2(x,y) LOCK(x); LOCK(y); UNLOCK(y); UNLOCK(x)
218
219/*
220 * Generate different permutations of the same testcase, using
221 * the same basic lock-dependency/state events:
222 */
223
224#define GENERATE_TESTCASE(name) \
225 \
226static void name(void) { E(); }
227
228#define GENERATE_PERMUTATIONS_2_EVENTS(name) \
229 \
230static void name##_12(void) { E1(); E2(); } \
231static void name##_21(void) { E2(); E1(); }
232
233#define GENERATE_PERMUTATIONS_3_EVENTS(name) \
234 \
235static void name##_123(void) { E1(); E2(); E3(); } \
236static void name##_132(void) { E1(); E3(); E2(); } \
237static void name##_213(void) { E2(); E1(); E3(); } \
238static void name##_231(void) { E2(); E3(); E1(); } \
239static void name##_312(void) { E3(); E1(); E2(); } \
240static void name##_321(void) { E3(); E2(); E1(); }
241
242/*
243 * AA deadlock:
244 */
245
246#define E() \
247 \
248 LOCK(X1); \
249 LOCK(X2); /* this one should fail */
250
251/*
252 * 6 testcases:
253 */
254#include "locking-selftest-spin.h"
255GENERATE_TESTCASE(AA_spin)
256#include "locking-selftest-wlock.h"
257GENERATE_TESTCASE(AA_wlock)
258#include "locking-selftest-rlock.h"
259GENERATE_TESTCASE(AA_rlock)
260#include "locking-selftest-mutex.h"
261GENERATE_TESTCASE(AA_mutex)
262#include "locking-selftest-wsem.h"
263GENERATE_TESTCASE(AA_wsem)
264#include "locking-selftest-rsem.h"
265GENERATE_TESTCASE(AA_rsem)
266
267#undef E
268
269/*
270 * Special-case for read-locking, they are
Ingo Molnar6c9076e2006-07-03 00:24:51 -0700271 * allowed to recurse on the same lock class:
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700272 */
273static void rlock_AA1(void)
274{
275 RL(X1);
276 RL(X1); // this one should NOT fail
277}
278
279static void rlock_AA1B(void)
280{
281 RL(X1);
Ingo Molnar6c9076e2006-07-03 00:24:51 -0700282 RL(X2); // this one should NOT fail
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700283}
284
285static void rsem_AA1(void)
286{
287 RSL(X1);
288 RSL(X1); // this one should fail
289}
290
291static void rsem_AA1B(void)
292{
293 RSL(X1);
294 RSL(X2); // this one should fail
295}
296/*
297 * The mixing of read and write locks is not allowed:
298 */
299static void rlock_AA2(void)
300{
301 RL(X1);
302 WL(X2); // this one should fail
303}
304
305static void rsem_AA2(void)
306{
307 RSL(X1);
308 WSL(X2); // this one should fail
309}
310
311static void rlock_AA3(void)
312{
313 WL(X1);
314 RL(X2); // this one should fail
315}
316
317static void rsem_AA3(void)
318{
319 WSL(X1);
320 RSL(X2); // this one should fail
321}
322
323/*
324 * ABBA deadlock:
325 */
326
327#define E() \
328 \
329 LOCK_UNLOCK_2(A, B); \
330 LOCK_UNLOCK_2(B, A); /* fail */
331
332/*
333 * 6 testcases:
334 */
335#include "locking-selftest-spin.h"
336GENERATE_TESTCASE(ABBA_spin)
337#include "locking-selftest-wlock.h"
338GENERATE_TESTCASE(ABBA_wlock)
339#include "locking-selftest-rlock.h"
340GENERATE_TESTCASE(ABBA_rlock)
341#include "locking-selftest-mutex.h"
342GENERATE_TESTCASE(ABBA_mutex)
343#include "locking-selftest-wsem.h"
344GENERATE_TESTCASE(ABBA_wsem)
345#include "locking-selftest-rsem.h"
346GENERATE_TESTCASE(ABBA_rsem)
347
348#undef E
349
350/*
351 * AB BC CA deadlock:
352 */
353
354#define E() \
355 \
356 LOCK_UNLOCK_2(A, B); \
357 LOCK_UNLOCK_2(B, C); \
358 LOCK_UNLOCK_2(C, A); /* fail */
359
360/*
361 * 6 testcases:
362 */
363#include "locking-selftest-spin.h"
364GENERATE_TESTCASE(ABBCCA_spin)
365#include "locking-selftest-wlock.h"
366GENERATE_TESTCASE(ABBCCA_wlock)
367#include "locking-selftest-rlock.h"
368GENERATE_TESTCASE(ABBCCA_rlock)
369#include "locking-selftest-mutex.h"
370GENERATE_TESTCASE(ABBCCA_mutex)
371#include "locking-selftest-wsem.h"
372GENERATE_TESTCASE(ABBCCA_wsem)
373#include "locking-selftest-rsem.h"
374GENERATE_TESTCASE(ABBCCA_rsem)
375
376#undef E
377
378/*
379 * AB CA BC deadlock:
380 */
381
382#define E() \
383 \
384 LOCK_UNLOCK_2(A, B); \
385 LOCK_UNLOCK_2(C, A); \
386 LOCK_UNLOCK_2(B, C); /* fail */
387
388/*
389 * 6 testcases:
390 */
391#include "locking-selftest-spin.h"
392GENERATE_TESTCASE(ABCABC_spin)
393#include "locking-selftest-wlock.h"
394GENERATE_TESTCASE(ABCABC_wlock)
395#include "locking-selftest-rlock.h"
396GENERATE_TESTCASE(ABCABC_rlock)
397#include "locking-selftest-mutex.h"
398GENERATE_TESTCASE(ABCABC_mutex)
399#include "locking-selftest-wsem.h"
400GENERATE_TESTCASE(ABCABC_wsem)
401#include "locking-selftest-rsem.h"
402GENERATE_TESTCASE(ABCABC_rsem)
403
404#undef E
405
406/*
407 * AB BC CD DA deadlock:
408 */
409
410#define E() \
411 \
412 LOCK_UNLOCK_2(A, B); \
413 LOCK_UNLOCK_2(B, C); \
414 LOCK_UNLOCK_2(C, D); \
415 LOCK_UNLOCK_2(D, A); /* fail */
416
417/*
418 * 6 testcases:
419 */
420#include "locking-selftest-spin.h"
421GENERATE_TESTCASE(ABBCCDDA_spin)
422#include "locking-selftest-wlock.h"
423GENERATE_TESTCASE(ABBCCDDA_wlock)
424#include "locking-selftest-rlock.h"
425GENERATE_TESTCASE(ABBCCDDA_rlock)
426#include "locking-selftest-mutex.h"
427GENERATE_TESTCASE(ABBCCDDA_mutex)
428#include "locking-selftest-wsem.h"
429GENERATE_TESTCASE(ABBCCDDA_wsem)
430#include "locking-selftest-rsem.h"
431GENERATE_TESTCASE(ABBCCDDA_rsem)
432
433#undef E
434
435/*
436 * AB CD BD DA deadlock:
437 */
438#define E() \
439 \
440 LOCK_UNLOCK_2(A, B); \
441 LOCK_UNLOCK_2(C, D); \
442 LOCK_UNLOCK_2(B, D); \
443 LOCK_UNLOCK_2(D, A); /* fail */
444
445/*
446 * 6 testcases:
447 */
448#include "locking-selftest-spin.h"
449GENERATE_TESTCASE(ABCDBDDA_spin)
450#include "locking-selftest-wlock.h"
451GENERATE_TESTCASE(ABCDBDDA_wlock)
452#include "locking-selftest-rlock.h"
453GENERATE_TESTCASE(ABCDBDDA_rlock)
454#include "locking-selftest-mutex.h"
455GENERATE_TESTCASE(ABCDBDDA_mutex)
456#include "locking-selftest-wsem.h"
457GENERATE_TESTCASE(ABCDBDDA_wsem)
458#include "locking-selftest-rsem.h"
459GENERATE_TESTCASE(ABCDBDDA_rsem)
460
461#undef E
462
463/*
464 * AB CD BC DA deadlock:
465 */
466#define E() \
467 \
468 LOCK_UNLOCK_2(A, B); \
469 LOCK_UNLOCK_2(C, D); \
470 LOCK_UNLOCK_2(B, C); \
471 LOCK_UNLOCK_2(D, A); /* fail */
472
473/*
474 * 6 testcases:
475 */
476#include "locking-selftest-spin.h"
477GENERATE_TESTCASE(ABCDBCDA_spin)
478#include "locking-selftest-wlock.h"
479GENERATE_TESTCASE(ABCDBCDA_wlock)
480#include "locking-selftest-rlock.h"
481GENERATE_TESTCASE(ABCDBCDA_rlock)
482#include "locking-selftest-mutex.h"
483GENERATE_TESTCASE(ABCDBCDA_mutex)
484#include "locking-selftest-wsem.h"
485GENERATE_TESTCASE(ABCDBCDA_wsem)
486#include "locking-selftest-rsem.h"
487GENERATE_TESTCASE(ABCDBCDA_rsem)
488
489#undef E
490
491/*
492 * Double unlock:
493 */
494#define E() \
495 \
496 LOCK(A); \
497 UNLOCK(A); \
498 UNLOCK(A); /* fail */
499
500/*
501 * 6 testcases:
502 */
503#include "locking-selftest-spin.h"
504GENERATE_TESTCASE(double_unlock_spin)
505#include "locking-selftest-wlock.h"
506GENERATE_TESTCASE(double_unlock_wlock)
507#include "locking-selftest-rlock.h"
508GENERATE_TESTCASE(double_unlock_rlock)
509#include "locking-selftest-mutex.h"
510GENERATE_TESTCASE(double_unlock_mutex)
511#include "locking-selftest-wsem.h"
512GENERATE_TESTCASE(double_unlock_wsem)
513#include "locking-selftest-rsem.h"
514GENERATE_TESTCASE(double_unlock_rsem)
515
516#undef E
517
518/*
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700519 * initializing a held lock:
520 */
521#define E() \
522 \
523 LOCK(A); \
524 INIT(A); /* fail */
525
526/*
527 * 6 testcases:
528 */
529#include "locking-selftest-spin.h"
530GENERATE_TESTCASE(init_held_spin)
531#include "locking-selftest-wlock.h"
532GENERATE_TESTCASE(init_held_wlock)
533#include "locking-selftest-rlock.h"
534GENERATE_TESTCASE(init_held_rlock)
535#include "locking-selftest-mutex.h"
536GENERATE_TESTCASE(init_held_mutex)
537#include "locking-selftest-wsem.h"
538GENERATE_TESTCASE(init_held_wsem)
539#include "locking-selftest-rsem.h"
540GENERATE_TESTCASE(init_held_rsem)
541
542#undef E
543
544/*
545 * locking an irq-safe lock with irqs enabled:
546 */
547#define E1() \
548 \
549 IRQ_ENTER(); \
550 LOCK(A); \
551 UNLOCK(A); \
552 IRQ_EXIT();
553
554#define E2() \
555 \
556 LOCK(A); \
557 UNLOCK(A);
558
559/*
560 * Generate 24 testcases:
561 */
562#include "locking-selftest-spin-hardirq.h"
563GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_spin)
564
565#include "locking-selftest-rlock-hardirq.h"
566GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_rlock)
567
568#include "locking-selftest-wlock-hardirq.h"
569GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_wlock)
570
571#include "locking-selftest-spin-softirq.h"
572GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_spin)
573
574#include "locking-selftest-rlock-softirq.h"
575GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_rlock)
576
577#include "locking-selftest-wlock-softirq.h"
578GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_wlock)
579
580#undef E1
581#undef E2
582
583/*
584 * Enabling hardirqs with a softirq-safe lock held:
585 */
586#define E1() \
587 \
588 SOFTIRQ_ENTER(); \
589 LOCK(A); \
590 UNLOCK(A); \
591 SOFTIRQ_EXIT();
592
593#define E2() \
594 \
595 HARDIRQ_DISABLE(); \
596 LOCK(A); \
597 HARDIRQ_ENABLE(); \
598 UNLOCK(A);
599
600/*
601 * Generate 12 testcases:
602 */
603#include "locking-selftest-spin.h"
604GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_spin)
605
606#include "locking-selftest-wlock.h"
607GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_wlock)
608
609#include "locking-selftest-rlock.h"
610GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_rlock)
611
612#undef E1
613#undef E2
614
615/*
616 * Enabling irqs with an irq-safe lock held:
617 */
618#define E1() \
619 \
620 IRQ_ENTER(); \
621 LOCK(A); \
622 UNLOCK(A); \
623 IRQ_EXIT();
624
625#define E2() \
626 \
627 IRQ_DISABLE(); \
628 LOCK(A); \
629 IRQ_ENABLE(); \
630 UNLOCK(A);
631
632/*
633 * Generate 24 testcases:
634 */
635#include "locking-selftest-spin-hardirq.h"
636GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_spin)
637
638#include "locking-selftest-rlock-hardirq.h"
639GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_rlock)
640
641#include "locking-selftest-wlock-hardirq.h"
642GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_wlock)
643
644#include "locking-selftest-spin-softirq.h"
645GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_spin)
646
647#include "locking-selftest-rlock-softirq.h"
648GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_rlock)
649
650#include "locking-selftest-wlock-softirq.h"
651GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock)
652
653#undef E1
654#undef E2
655
656/*
657 * Acquiring a irq-unsafe lock while holding an irq-safe-lock:
658 */
659#define E1() \
660 \
661 LOCK(A); \
662 LOCK(B); \
663 UNLOCK(B); \
664 UNLOCK(A); \
665
666#define E2() \
667 \
668 LOCK(B); \
669 UNLOCK(B);
670
671#define E3() \
672 \
673 IRQ_ENTER(); \
674 LOCK(A); \
675 UNLOCK(A); \
676 IRQ_EXIT();
677
678/*
679 * Generate 36 testcases:
680 */
681#include "locking-selftest-spin-hardirq.h"
682GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_spin)
683
684#include "locking-selftest-rlock-hardirq.h"
685GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_rlock)
686
687#include "locking-selftest-wlock-hardirq.h"
688GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_wlock)
689
690#include "locking-selftest-spin-softirq.h"
691GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_spin)
692
693#include "locking-selftest-rlock-softirq.h"
694GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_rlock)
695
696#include "locking-selftest-wlock-softirq.h"
697GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock)
698
699#undef E1
700#undef E2
701#undef E3
702
703/*
704 * If a lock turns into softirq-safe, but earlier it took
705 * a softirq-unsafe lock:
706 */
707
708#define E1() \
709 IRQ_DISABLE(); \
710 LOCK(A); \
711 LOCK(B); \
712 UNLOCK(B); \
713 UNLOCK(A); \
714 IRQ_ENABLE();
715
716#define E2() \
717 LOCK(B); \
718 UNLOCK(B);
719
720#define E3() \
721 IRQ_ENTER(); \
722 LOCK(A); \
723 UNLOCK(A); \
724 IRQ_EXIT();
725
726/*
727 * Generate 36 testcases:
728 */
729#include "locking-selftest-spin-hardirq.h"
730GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_spin)
731
732#include "locking-selftest-rlock-hardirq.h"
733GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_rlock)
734
735#include "locking-selftest-wlock-hardirq.h"
736GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_wlock)
737
738#include "locking-selftest-spin-softirq.h"
739GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_spin)
740
741#include "locking-selftest-rlock-softirq.h"
742GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_rlock)
743
744#include "locking-selftest-wlock-softirq.h"
745GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_wlock)
746
747#undef E1
748#undef E2
749#undef E3
750
751/*
752 * read-lock / write-lock irq inversion.
753 *
754 * Deadlock scenario:
755 *
756 * CPU#1 is at #1, i.e. it has write-locked A, but has not
757 * taken B yet.
758 *
759 * CPU#2 is at #2, i.e. it has locked B.
760 *
761 * Hardirq hits CPU#2 at point #2 and is trying to read-lock A.
762 *
763 * The deadlock occurs because CPU#1 will spin on B, and CPU#2
764 * will spin on A.
765 */
766
767#define E1() \
768 \
769 IRQ_DISABLE(); \
770 WL(A); \
771 LOCK(B); \
772 UNLOCK(B); \
773 WU(A); \
774 IRQ_ENABLE();
775
776#define E2() \
777 \
778 LOCK(B); \
779 UNLOCK(B);
780
781#define E3() \
782 \
783 IRQ_ENTER(); \
784 RL(A); \
785 RU(A); \
786 IRQ_EXIT();
787
788/*
789 * Generate 36 testcases:
790 */
791#include "locking-selftest-spin-hardirq.h"
792GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_spin)
793
794#include "locking-selftest-rlock-hardirq.h"
795GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_rlock)
796
797#include "locking-selftest-wlock-hardirq.h"
798GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_hard_wlock)
799
800#include "locking-selftest-spin-softirq.h"
801GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_spin)
802
803#include "locking-selftest-rlock-softirq.h"
804GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_rlock)
805
806#include "locking-selftest-wlock-softirq.h"
807GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_wlock)
808
809#undef E1
810#undef E2
811#undef E3
812
813/*
814 * read-lock / write-lock recursion that is actually safe.
815 */
816
817#define E1() \
818 \
819 IRQ_DISABLE(); \
820 WL(A); \
821 WU(A); \
822 IRQ_ENABLE();
823
824#define E2() \
825 \
826 RL(A); \
827 RU(A); \
828
829#define E3() \
830 \
831 IRQ_ENTER(); \
832 RL(A); \
833 L(B); \
834 U(B); \
835 RU(A); \
836 IRQ_EXIT();
837
838/*
839 * Generate 12 testcases:
840 */
841#include "locking-selftest-hardirq.h"
842GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard)
843
844#include "locking-selftest-softirq.h"
845GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft)
846
847#undef E1
848#undef E2
849#undef E3
850
851/*
852 * read-lock / write-lock recursion that is unsafe.
853 */
854
855#define E1() \
856 \
857 IRQ_DISABLE(); \
858 L(B); \
859 WL(A); \
860 WU(A); \
861 U(B); \
862 IRQ_ENABLE();
863
864#define E2() \
865 \
866 RL(A); \
867 RU(A); \
868
869#define E3() \
870 \
871 IRQ_ENTER(); \
872 L(B); \
873 U(B); \
874 IRQ_EXIT();
875
876/*
877 * Generate 12 testcases:
878 */
879#include "locking-selftest-hardirq.h"
880// GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard)
881
882#include "locking-selftest-softirq.h"
883// GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft)
884
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700885#ifdef CONFIG_DEBUG_LOCK_ALLOC
886# define I_SPINLOCK(x) lockdep_reset_lock(&lock_##x.dep_map)
887# define I_RWLOCK(x) lockdep_reset_lock(&rwlock_##x.dep_map)
888# define I_MUTEX(x) lockdep_reset_lock(&mutex_##x.dep_map)
889# define I_RWSEM(x) lockdep_reset_lock(&rwsem_##x.dep_map)
Maarten Lankhorst1de99442013-06-20 13:31:24 +0200890# define I_WW(x) lockdep_reset_lock(&x.dep_map)
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700891#else
892# define I_SPINLOCK(x)
893# define I_RWLOCK(x)
894# define I_MUTEX(x)
895# define I_RWSEM(x)
Maarten Lankhorst1de99442013-06-20 13:31:24 +0200896# define I_WW(x)
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700897#endif
898
899#define I1(x) \
900 do { \
901 I_SPINLOCK(x); \
902 I_RWLOCK(x); \
903 I_MUTEX(x); \
904 I_RWSEM(x); \
905 } while (0)
906
907#define I2(x) \
908 do { \
Yong Zhang9fb1b902012-04-16 15:01:55 +0800909 raw_spin_lock_init(&lock_##x); \
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700910 rwlock_init(&rwlock_##x); \
911 mutex_init(&mutex_##x); \
912 init_rwsem(&rwsem_##x); \
913 } while (0)
914
915static void reset_locks(void)
916{
917 local_irq_disable();
Maarten Lankhorst1de99442013-06-20 13:31:24 +0200918 lockdep_free_key_range(&ww_lockdep.acquire_key, 1);
919 lockdep_free_key_range(&ww_lockdep.mutex_key, 1);
920
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700921 I1(A); I1(B); I1(C); I1(D);
922 I1(X1); I1(X2); I1(Y1); I1(Y2); I1(Z1); I1(Z2);
Maarten Lankhorstf3cf1392013-06-20 13:31:42 +0200923 I_WW(t); I_WW(t2); I_WW(o.base); I_WW(o2.base); I_WW(o3.base);
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700924 lockdep_reset();
925 I2(A); I2(B); I2(C); I2(D);
926 init_shared_classes();
Maarten Lankhorst1de99442013-06-20 13:31:24 +0200927
Maarten Lankhorstf3cf1392013-06-20 13:31:42 +0200928 ww_mutex_init(&o, &ww_lockdep); ww_mutex_init(&o2, &ww_lockdep); ww_mutex_init(&o3, &ww_lockdep);
Maarten Lankhorst1de99442013-06-20 13:31:24 +0200929 memset(&t, 0, sizeof(t)); memset(&t2, 0, sizeof(t2));
930 memset(&ww_lockdep.acquire_key, 0, sizeof(ww_lockdep.acquire_key));
931 memset(&ww_lockdep.mutex_key, 0, sizeof(ww_lockdep.mutex_key));
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700932 local_irq_enable();
933}
934
935#undef I
936
937static int testcase_total;
938static int testcase_successes;
939static int expected_testcase_failures;
940static int unexpected_testcase_failures;
941
942static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask)
943{
944 unsigned long saved_preempt_count = preempt_count();
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700945
946 WARN_ON(irqs_disabled());
947
948 testcase_fn();
949 /*
950 * Filter out expected failures:
951 */
Maarten Lankhorst1de99442013-06-20 13:31:24 +0200952#ifndef CONFIG_PROVE_LOCKING
Maarten Lankhorst166989e2013-06-20 13:31:51 +0200953 if (expected == FAILURE && debug_locks) {
Maarten Lankhorst1de99442013-06-20 13:31:24 +0200954 expected_testcase_failures++;
Michael Ellerman25139402016-11-25 09:45:28 +1100955 pr_cont("failed|");
Maarten Lankhorst166989e2013-06-20 13:31:51 +0200956 }
957 else
958#endif
959 if (debug_locks != expected) {
Maarten Lankhorst1de99442013-06-20 13:31:24 +0200960 unexpected_testcase_failures++;
Michael Ellerman25139402016-11-25 09:45:28 +1100961 pr_cont("FAILED|");
Ingo Molnar2ee91f12006-12-06 20:39:32 -0800962
Maarten Lankhorst1de99442013-06-20 13:31:24 +0200963 dump_stack();
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700964 } else {
965 testcase_successes++;
Michael Ellerman25139402016-11-25 09:45:28 +1100966 pr_cont(" ok |");
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700967 }
968 testcase_total++;
969
970 if (debug_locks_verbose)
Michael Ellerman25139402016-11-25 09:45:28 +1100971 pr_cont(" lockclass mask: %x, debug_locks: %d, expected: %d\n",
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700972 lockclass_mask, debug_locks, expected);
973 /*
974 * Some tests (e.g. double-unlock) might corrupt the preemption
975 * count, so restore it:
976 */
Peter Zijlstra4a2b4b22013-08-14 14:55:24 +0200977 preempt_count_set(saved_preempt_count);
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700978#ifdef CONFIG_TRACE_IRQFLAGS
979 if (softirq_count())
980 current->softirqs_enabled = 0;
981 else
982 current->softirqs_enabled = 1;
983#endif
984
985 reset_locks();
986}
987
988static inline void print_testname(const char *testname)
989{
990 printk("%33s:", testname);
991}
992
993#define DO_TESTCASE_1(desc, name, nr) \
994 print_testname(desc"/"#nr); \
995 dotest(name##_##nr, SUCCESS, LOCKTYPE_RWLOCK); \
Michael Ellerman25139402016-11-25 09:45:28 +1100996 pr_cont("\n");
Ingo Molnarcae2ed92006-07-03 00:24:48 -0700997
998#define DO_TESTCASE_1B(desc, name, nr) \
999 print_testname(desc"/"#nr); \
1000 dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK); \
Michael Ellerman25139402016-11-25 09:45:28 +11001001 pr_cont("\n");
Ingo Molnarcae2ed92006-07-03 00:24:48 -07001002
1003#define DO_TESTCASE_3(desc, name, nr) \
1004 print_testname(desc"/"#nr); \
1005 dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN); \
1006 dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK); \
1007 dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK); \
Michael Ellerman25139402016-11-25 09:45:28 +11001008 pr_cont("\n");
Ingo Molnarcae2ed92006-07-03 00:24:48 -07001009
1010#define DO_TESTCASE_3RW(desc, name, nr) \
1011 print_testname(desc"/"#nr); \
1012 dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN|LOCKTYPE_RWLOCK);\
1013 dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK); \
1014 dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK); \
Michael Ellerman25139402016-11-25 09:45:28 +11001015 pr_cont("\n");
Ingo Molnarcae2ed92006-07-03 00:24:48 -07001016
1017#define DO_TESTCASE_6(desc, name) \
1018 print_testname(desc); \
1019 dotest(name##_spin, FAILURE, LOCKTYPE_SPIN); \
1020 dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK); \
1021 dotest(name##_rlock, FAILURE, LOCKTYPE_RWLOCK); \
1022 dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \
1023 dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \
1024 dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \
Michael Ellerman25139402016-11-25 09:45:28 +11001025 pr_cont("\n");
Ingo Molnarcae2ed92006-07-03 00:24:48 -07001026
1027#define DO_TESTCASE_6_SUCCESS(desc, name) \
1028 print_testname(desc); \
1029 dotest(name##_spin, SUCCESS, LOCKTYPE_SPIN); \
1030 dotest(name##_wlock, SUCCESS, LOCKTYPE_RWLOCK); \
1031 dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK); \
1032 dotest(name##_mutex, SUCCESS, LOCKTYPE_MUTEX); \
1033 dotest(name##_wsem, SUCCESS, LOCKTYPE_RWSEM); \
1034 dotest(name##_rsem, SUCCESS, LOCKTYPE_RWSEM); \
Michael Ellerman25139402016-11-25 09:45:28 +11001035 pr_cont("\n");
Ingo Molnarcae2ed92006-07-03 00:24:48 -07001036
1037/*
1038 * 'read' variant: rlocks must not trigger.
1039 */
1040#define DO_TESTCASE_6R(desc, name) \
1041 print_testname(desc); \
1042 dotest(name##_spin, FAILURE, LOCKTYPE_SPIN); \
1043 dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK); \
1044 dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK); \
1045 dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \
1046 dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \
1047 dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \
Michael Ellerman25139402016-11-25 09:45:28 +11001048 pr_cont("\n");
Ingo Molnarcae2ed92006-07-03 00:24:48 -07001049
1050#define DO_TESTCASE_2I(desc, name, nr) \
1051 DO_TESTCASE_1("hard-"desc, name##_hard, nr); \
1052 DO_TESTCASE_1("soft-"desc, name##_soft, nr);
1053
1054#define DO_TESTCASE_2IB(desc, name, nr) \
1055 DO_TESTCASE_1B("hard-"desc, name##_hard, nr); \
1056 DO_TESTCASE_1B("soft-"desc, name##_soft, nr);
1057
1058#define DO_TESTCASE_6I(desc, name, nr) \
1059 DO_TESTCASE_3("hard-"desc, name##_hard, nr); \
1060 DO_TESTCASE_3("soft-"desc, name##_soft, nr);
1061
1062#define DO_TESTCASE_6IRW(desc, name, nr) \
1063 DO_TESTCASE_3RW("hard-"desc, name##_hard, nr); \
1064 DO_TESTCASE_3RW("soft-"desc, name##_soft, nr);
1065
1066#define DO_TESTCASE_2x3(desc, name) \
1067 DO_TESTCASE_3(desc, name, 12); \
1068 DO_TESTCASE_3(desc, name, 21);
1069
1070#define DO_TESTCASE_2x6(desc, name) \
1071 DO_TESTCASE_6I(desc, name, 12); \
1072 DO_TESTCASE_6I(desc, name, 21);
1073
1074#define DO_TESTCASE_6x2(desc, name) \
1075 DO_TESTCASE_2I(desc, name, 123); \
1076 DO_TESTCASE_2I(desc, name, 132); \
1077 DO_TESTCASE_2I(desc, name, 213); \
1078 DO_TESTCASE_2I(desc, name, 231); \
1079 DO_TESTCASE_2I(desc, name, 312); \
1080 DO_TESTCASE_2I(desc, name, 321);
1081
1082#define DO_TESTCASE_6x2B(desc, name) \
1083 DO_TESTCASE_2IB(desc, name, 123); \
1084 DO_TESTCASE_2IB(desc, name, 132); \
1085 DO_TESTCASE_2IB(desc, name, 213); \
1086 DO_TESTCASE_2IB(desc, name, 231); \
1087 DO_TESTCASE_2IB(desc, name, 312); \
1088 DO_TESTCASE_2IB(desc, name, 321);
1089
1090#define DO_TESTCASE_6x6(desc, name) \
1091 DO_TESTCASE_6I(desc, name, 123); \
1092 DO_TESTCASE_6I(desc, name, 132); \
1093 DO_TESTCASE_6I(desc, name, 213); \
1094 DO_TESTCASE_6I(desc, name, 231); \
1095 DO_TESTCASE_6I(desc, name, 312); \
1096 DO_TESTCASE_6I(desc, name, 321);
1097
1098#define DO_TESTCASE_6x6RW(desc, name) \
1099 DO_TESTCASE_6IRW(desc, name, 123); \
1100 DO_TESTCASE_6IRW(desc, name, 132); \
1101 DO_TESTCASE_6IRW(desc, name, 213); \
1102 DO_TESTCASE_6IRW(desc, name, 231); \
1103 DO_TESTCASE_6IRW(desc, name, 312); \
1104 DO_TESTCASE_6IRW(desc, name, 321);
1105
Maarten Lankhorst1de99442013-06-20 13:31:24 +02001106static void ww_test_fail_acquire(void)
1107{
1108 int ret;
1109
1110 WWAI(&t);
1111 t.stamp++;
1112
1113 ret = WWL(&o, &t);
1114
1115 if (WARN_ON(!o.ctx) ||
1116 WARN_ON(ret))
1117 return;
1118
1119 /* No lockdep test, pure API */
1120 ret = WWL(&o, &t);
1121 WARN_ON(ret != -EALREADY);
1122
1123 ret = WWT(&o);
1124 WARN_ON(ret);
1125
1126 t2 = t;
1127 t2.stamp++;
1128 ret = WWL(&o, &t2);
1129 WARN_ON(ret != -EDEADLK);
1130 WWU(&o);
1131
1132 if (WWT(&o))
1133 WWU(&o);
1134#ifdef CONFIG_DEBUG_LOCK_ALLOC
1135 else
1136 DEBUG_LOCKS_WARN_ON(1);
1137#endif
1138}
1139
Maarten Lankhorst2fe3d4b2013-06-20 13:31:30 +02001140static void ww_test_normal(void)
1141{
1142 int ret;
1143
1144 WWAI(&t);
1145
1146 /*
1147 * None of the ww_mutex codepaths should be taken in the 'normal'
1148 * mutex calls. The easiest way to verify this is by using the
1149 * normal mutex calls, and making sure o.ctx is unmodified.
1150 */
1151
1152 /* mutex_lock (and indirectly, mutex_lock_nested) */
1153 o.ctx = (void *)~0UL;
1154 mutex_lock(&o.base);
1155 mutex_unlock(&o.base);
1156 WARN_ON(o.ctx != (void *)~0UL);
1157
1158 /* mutex_lock_interruptible (and *_nested) */
1159 o.ctx = (void *)~0UL;
1160 ret = mutex_lock_interruptible(&o.base);
1161 if (!ret)
1162 mutex_unlock(&o.base);
1163 else
1164 WARN_ON(1);
1165 WARN_ON(o.ctx != (void *)~0UL);
1166
1167 /* mutex_lock_killable (and *_nested) */
1168 o.ctx = (void *)~0UL;
1169 ret = mutex_lock_killable(&o.base);
1170 if (!ret)
1171 mutex_unlock(&o.base);
1172 else
1173 WARN_ON(1);
1174 WARN_ON(o.ctx != (void *)~0UL);
1175
1176 /* trylock, succeeding */
1177 o.ctx = (void *)~0UL;
1178 ret = mutex_trylock(&o.base);
1179 WARN_ON(!ret);
1180 if (ret)
1181 mutex_unlock(&o.base);
1182 else
1183 WARN_ON(1);
1184 WARN_ON(o.ctx != (void *)~0UL);
1185
1186 /* trylock, failing */
1187 o.ctx = (void *)~0UL;
1188 mutex_lock(&o.base);
1189 ret = mutex_trylock(&o.base);
1190 WARN_ON(ret);
1191 mutex_unlock(&o.base);
1192 WARN_ON(o.ctx != (void *)~0UL);
1193
1194 /* nest_lock */
1195 o.ctx = (void *)~0UL;
1196 mutex_lock_nest_lock(&o.base, &t);
1197 mutex_unlock(&o.base);
1198 WARN_ON(o.ctx != (void *)~0UL);
1199}
1200
Maarten Lankhorst1de99442013-06-20 13:31:24 +02001201static void ww_test_two_contexts(void)
1202{
1203 WWAI(&t);
1204 WWAI(&t2);
1205}
1206
1207static void ww_test_diff_class(void)
1208{
1209 WWAI(&t);
1210#ifdef CONFIG_DEBUG_MUTEXES
1211 t.ww_class = NULL;
1212#endif
1213 WWL(&o, &t);
1214}
1215
1216static void ww_test_context_done_twice(void)
1217{
1218 WWAI(&t);
1219 WWAD(&t);
1220 WWAD(&t);
1221 WWAF(&t);
1222}
1223
1224static void ww_test_context_unlock_twice(void)
1225{
1226 WWAI(&t);
1227 WWAD(&t);
1228 WWAF(&t);
1229 WWAF(&t);
1230}
1231
1232static void ww_test_context_fini_early(void)
1233{
1234 WWAI(&t);
1235 WWL(&o, &t);
1236 WWAD(&t);
1237 WWAF(&t);
1238}
1239
1240static void ww_test_context_lock_after_done(void)
1241{
1242 WWAI(&t);
1243 WWAD(&t);
1244 WWL(&o, &t);
1245}
1246
1247static void ww_test_object_unlock_twice(void)
1248{
1249 WWL1(&o);
1250 WWU(&o);
1251 WWU(&o);
1252}
1253
1254static void ww_test_object_lock_unbalanced(void)
1255{
1256 WWAI(&t);
1257 WWL(&o, &t);
1258 t.acquired = 0;
1259 WWU(&o);
1260 WWAF(&t);
1261}
1262
1263static void ww_test_object_lock_stale_context(void)
1264{
1265 WWAI(&t);
1266 o.ctx = &t2;
1267 WWL(&o, &t);
1268}
1269
Maarten Lankhorstf3cf1392013-06-20 13:31:42 +02001270static void ww_test_edeadlk_normal(void)
1271{
1272 int ret;
1273
1274 mutex_lock(&o2.base);
1275 o2.ctx = &t2;
1276 mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1277
1278 WWAI(&t);
1279 t2 = t;
1280 t2.stamp--;
1281
1282 ret = WWL(&o, &t);
1283 WARN_ON(ret);
1284
1285 ret = WWL(&o2, &t);
1286 WARN_ON(ret != -EDEADLK);
1287
1288 o2.ctx = NULL;
1289 mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
1290 mutex_unlock(&o2.base);
1291 WWU(&o);
1292
1293 WWL(&o2, &t);
1294}
1295
1296static void ww_test_edeadlk_normal_slow(void)
1297{
1298 int ret;
1299
1300 mutex_lock(&o2.base);
1301 mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1302 o2.ctx = &t2;
1303
1304 WWAI(&t);
1305 t2 = t;
1306 t2.stamp--;
1307
1308 ret = WWL(&o, &t);
1309 WARN_ON(ret);
1310
1311 ret = WWL(&o2, &t);
1312 WARN_ON(ret != -EDEADLK);
1313
1314 o2.ctx = NULL;
1315 mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
1316 mutex_unlock(&o2.base);
1317 WWU(&o);
1318
1319 ww_mutex_lock_slow(&o2, &t);
1320}
1321
1322static void ww_test_edeadlk_no_unlock(void)
1323{
1324 int ret;
1325
1326 mutex_lock(&o2.base);
1327 o2.ctx = &t2;
1328 mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1329
1330 WWAI(&t);
1331 t2 = t;
1332 t2.stamp--;
1333
1334 ret = WWL(&o, &t);
1335 WARN_ON(ret);
1336
1337 ret = WWL(&o2, &t);
1338 WARN_ON(ret != -EDEADLK);
1339
1340 o2.ctx = NULL;
1341 mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
1342 mutex_unlock(&o2.base);
1343
1344 WWL(&o2, &t);
1345}
1346
1347static void ww_test_edeadlk_no_unlock_slow(void)
1348{
1349 int ret;
1350
1351 mutex_lock(&o2.base);
1352 mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1353 o2.ctx = &t2;
1354
1355 WWAI(&t);
1356 t2 = t;
1357 t2.stamp--;
1358
1359 ret = WWL(&o, &t);
1360 WARN_ON(ret);
1361
1362 ret = WWL(&o2, &t);
1363 WARN_ON(ret != -EDEADLK);
1364
1365 o2.ctx = NULL;
1366 mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_);
1367 mutex_unlock(&o2.base);
1368
1369 ww_mutex_lock_slow(&o2, &t);
1370}
1371
1372static void ww_test_edeadlk_acquire_more(void)
1373{
1374 int ret;
1375
1376 mutex_lock(&o2.base);
1377 mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1378 o2.ctx = &t2;
1379
1380 WWAI(&t);
1381 t2 = t;
1382 t2.stamp--;
1383
1384 ret = WWL(&o, &t);
1385 WARN_ON(ret);
1386
1387 ret = WWL(&o2, &t);
1388 WARN_ON(ret != -EDEADLK);
1389
1390 ret = WWL(&o3, &t);
1391}
1392
1393static void ww_test_edeadlk_acquire_more_slow(void)
1394{
1395 int ret;
1396
1397 mutex_lock(&o2.base);
1398 mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1399 o2.ctx = &t2;
1400
1401 WWAI(&t);
1402 t2 = t;
1403 t2.stamp--;
1404
1405 ret = WWL(&o, &t);
1406 WARN_ON(ret);
1407
1408 ret = WWL(&o2, &t);
1409 WARN_ON(ret != -EDEADLK);
1410
1411 ww_mutex_lock_slow(&o3, &t);
1412}
1413
1414static void ww_test_edeadlk_acquire_more_edeadlk(void)
1415{
1416 int ret;
1417
1418 mutex_lock(&o2.base);
1419 mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1420 o2.ctx = &t2;
1421
1422 mutex_lock(&o3.base);
1423 mutex_release(&o3.base.dep_map, 1, _THIS_IP_);
1424 o3.ctx = &t2;
1425
1426 WWAI(&t);
1427 t2 = t;
1428 t2.stamp--;
1429
1430 ret = WWL(&o, &t);
1431 WARN_ON(ret);
1432
1433 ret = WWL(&o2, &t);
1434 WARN_ON(ret != -EDEADLK);
1435
1436 ret = WWL(&o3, &t);
1437 WARN_ON(ret != -EDEADLK);
1438}
1439
1440static void ww_test_edeadlk_acquire_more_edeadlk_slow(void)
1441{
1442 int ret;
1443
1444 mutex_lock(&o2.base);
1445 mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1446 o2.ctx = &t2;
1447
1448 mutex_lock(&o3.base);
1449 mutex_release(&o3.base.dep_map, 1, _THIS_IP_);
1450 o3.ctx = &t2;
1451
1452 WWAI(&t);
1453 t2 = t;
1454 t2.stamp--;
1455
1456 ret = WWL(&o, &t);
1457 WARN_ON(ret);
1458
1459 ret = WWL(&o2, &t);
1460 WARN_ON(ret != -EDEADLK);
1461
1462 ww_mutex_lock_slow(&o3, &t);
1463}
1464
1465static void ww_test_edeadlk_acquire_wrong(void)
1466{
1467 int ret;
1468
1469 mutex_lock(&o2.base);
1470 mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1471 o2.ctx = &t2;
1472
1473 WWAI(&t);
1474 t2 = t;
1475 t2.stamp--;
1476
1477 ret = WWL(&o, &t);
1478 WARN_ON(ret);
1479
1480 ret = WWL(&o2, &t);
1481 WARN_ON(ret != -EDEADLK);
1482 if (!ret)
1483 WWU(&o2);
1484
1485 WWU(&o);
1486
1487 ret = WWL(&o3, &t);
1488}
1489
1490static void ww_test_edeadlk_acquire_wrong_slow(void)
1491{
1492 int ret;
1493
1494 mutex_lock(&o2.base);
1495 mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1496 o2.ctx = &t2;
1497
1498 WWAI(&t);
1499 t2 = t;
1500 t2.stamp--;
1501
1502 ret = WWL(&o, &t);
1503 WARN_ON(ret);
1504
1505 ret = WWL(&o2, &t);
1506 WARN_ON(ret != -EDEADLK);
1507 if (!ret)
1508 WWU(&o2);
1509
1510 WWU(&o);
1511
1512 ww_mutex_lock_slow(&o3, &t);
1513}
1514
Maarten Lankhorst1de99442013-06-20 13:31:24 +02001515static void ww_test_spin_nest_unlocked(void)
1516{
1517 raw_spin_lock_nest_lock(&lock_A, &o.base);
1518 U(A);
1519}
1520
1521static void ww_test_unneeded_slow(void)
1522{
1523 WWAI(&t);
1524
1525 ww_mutex_lock_slow(&o, &t);
1526}
1527
1528static void ww_test_context_block(void)
1529{
1530 int ret;
1531
1532 WWAI(&t);
1533
1534 ret = WWL(&o, &t);
1535 WARN_ON(ret);
1536 WWL1(&o2);
1537}
1538
1539static void ww_test_context_try(void)
1540{
1541 int ret;
1542
1543 WWAI(&t);
1544
1545 ret = WWL(&o, &t);
1546 WARN_ON(ret);
1547
1548 ret = WWT(&o2);
1549 WARN_ON(!ret);
1550 WWU(&o2);
1551 WWU(&o);
1552}
1553
1554static void ww_test_context_context(void)
1555{
1556 int ret;
1557
1558 WWAI(&t);
1559
1560 ret = WWL(&o, &t);
1561 WARN_ON(ret);
1562
1563 ret = WWL(&o2, &t);
1564 WARN_ON(ret);
1565
1566 WWU(&o2);
1567 WWU(&o);
1568}
1569
1570static void ww_test_try_block(void)
1571{
1572 bool ret;
1573
1574 ret = WWT(&o);
1575 WARN_ON(!ret);
1576
1577 WWL1(&o2);
1578 WWU(&o2);
1579 WWU(&o);
1580}
1581
1582static void ww_test_try_try(void)
1583{
1584 bool ret;
1585
1586 ret = WWT(&o);
1587 WARN_ON(!ret);
1588 ret = WWT(&o2);
1589 WARN_ON(!ret);
1590 WWU(&o2);
1591 WWU(&o);
1592}
1593
1594static void ww_test_try_context(void)
1595{
1596 int ret;
1597
1598 ret = WWT(&o);
1599 WARN_ON(!ret);
1600
1601 WWAI(&t);
1602
1603 ret = WWL(&o2, &t);
1604 WARN_ON(ret);
1605}
1606
1607static void ww_test_block_block(void)
1608{
1609 WWL1(&o);
1610 WWL1(&o2);
1611}
1612
1613static void ww_test_block_try(void)
1614{
1615 bool ret;
1616
1617 WWL1(&o);
1618 ret = WWT(&o2);
1619 WARN_ON(!ret);
1620}
1621
1622static void ww_test_block_context(void)
1623{
1624 int ret;
1625
1626 WWL1(&o);
1627 WWAI(&t);
1628
1629 ret = WWL(&o2, &t);
1630 WARN_ON(ret);
1631}
1632
1633static void ww_test_spin_block(void)
1634{
1635 L(A);
1636 U(A);
1637
1638 WWL1(&o);
1639 L(A);
1640 U(A);
1641 WWU(&o);
1642
1643 L(A);
1644 WWL1(&o);
1645 WWU(&o);
1646 U(A);
1647}
1648
1649static void ww_test_spin_try(void)
1650{
1651 bool ret;
1652
1653 L(A);
1654 U(A);
1655
1656 ret = WWT(&o);
1657 WARN_ON(!ret);
1658 L(A);
1659 U(A);
1660 WWU(&o);
1661
1662 L(A);
1663 ret = WWT(&o);
1664 WARN_ON(!ret);
1665 WWU(&o);
1666 U(A);
1667}
1668
1669static void ww_test_spin_context(void)
1670{
1671 int ret;
1672
1673 L(A);
1674 U(A);
1675
1676 WWAI(&t);
1677
1678 ret = WWL(&o, &t);
1679 WARN_ON(ret);
1680 L(A);
1681 U(A);
1682 WWU(&o);
1683
1684 L(A);
1685 ret = WWL(&o, &t);
1686 WARN_ON(ret);
1687 WWU(&o);
1688 U(A);
1689}
1690
1691static void ww_tests(void)
1692{
1693 printk(" --------------------------------------------------------------------------\n");
1694 printk(" | Wound/wait tests |\n");
1695 printk(" ---------------------\n");
1696
1697 print_testname("ww api failures");
1698 dotest(ww_test_fail_acquire, SUCCESS, LOCKTYPE_WW);
Maarten Lankhorst2fe3d4b2013-06-20 13:31:30 +02001699 dotest(ww_test_normal, SUCCESS, LOCKTYPE_WW);
Maarten Lankhorst1de99442013-06-20 13:31:24 +02001700 dotest(ww_test_unneeded_slow, FAILURE, LOCKTYPE_WW);
Michael Ellerman25139402016-11-25 09:45:28 +11001701 pr_cont("\n");
Maarten Lankhorst1de99442013-06-20 13:31:24 +02001702
1703 print_testname("ww contexts mixing");
1704 dotest(ww_test_two_contexts, FAILURE, LOCKTYPE_WW);
1705 dotest(ww_test_diff_class, FAILURE, LOCKTYPE_WW);
Michael Ellerman25139402016-11-25 09:45:28 +11001706 pr_cont("\n");
Maarten Lankhorst1de99442013-06-20 13:31:24 +02001707
1708 print_testname("finishing ww context");
1709 dotest(ww_test_context_done_twice, FAILURE, LOCKTYPE_WW);
1710 dotest(ww_test_context_unlock_twice, FAILURE, LOCKTYPE_WW);
1711 dotest(ww_test_context_fini_early, FAILURE, LOCKTYPE_WW);
1712 dotest(ww_test_context_lock_after_done, FAILURE, LOCKTYPE_WW);
Michael Ellerman25139402016-11-25 09:45:28 +11001713 pr_cont("\n");
Maarten Lankhorst1de99442013-06-20 13:31:24 +02001714
1715 print_testname("locking mismatches");
1716 dotest(ww_test_object_unlock_twice, FAILURE, LOCKTYPE_WW);
1717 dotest(ww_test_object_lock_unbalanced, FAILURE, LOCKTYPE_WW);
1718 dotest(ww_test_object_lock_stale_context, FAILURE, LOCKTYPE_WW);
Michael Ellerman25139402016-11-25 09:45:28 +11001719 pr_cont("\n");
Maarten Lankhorst1de99442013-06-20 13:31:24 +02001720
Maarten Lankhorstf3cf1392013-06-20 13:31:42 +02001721 print_testname("EDEADLK handling");
1722 dotest(ww_test_edeadlk_normal, SUCCESS, LOCKTYPE_WW);
1723 dotest(ww_test_edeadlk_normal_slow, SUCCESS, LOCKTYPE_WW);
1724 dotest(ww_test_edeadlk_no_unlock, FAILURE, LOCKTYPE_WW);
1725 dotest(ww_test_edeadlk_no_unlock_slow, FAILURE, LOCKTYPE_WW);
1726 dotest(ww_test_edeadlk_acquire_more, FAILURE, LOCKTYPE_WW);
1727 dotest(ww_test_edeadlk_acquire_more_slow, FAILURE, LOCKTYPE_WW);
1728 dotest(ww_test_edeadlk_acquire_more_edeadlk, FAILURE, LOCKTYPE_WW);
1729 dotest(ww_test_edeadlk_acquire_more_edeadlk_slow, FAILURE, LOCKTYPE_WW);
1730 dotest(ww_test_edeadlk_acquire_wrong, FAILURE, LOCKTYPE_WW);
1731 dotest(ww_test_edeadlk_acquire_wrong_slow, FAILURE, LOCKTYPE_WW);
Michael Ellerman25139402016-11-25 09:45:28 +11001732 pr_cont("\n");
Maarten Lankhorstf3cf1392013-06-20 13:31:42 +02001733
Maarten Lankhorst1de99442013-06-20 13:31:24 +02001734 print_testname("spinlock nest unlocked");
1735 dotest(ww_test_spin_nest_unlocked, FAILURE, LOCKTYPE_WW);
Michael Ellerman25139402016-11-25 09:45:28 +11001736 pr_cont("\n");
Maarten Lankhorst1de99442013-06-20 13:31:24 +02001737
1738 printk(" -----------------------------------------------------\n");
1739 printk(" |block | try |context|\n");
1740 printk(" -----------------------------------------------------\n");
1741
1742 print_testname("context");
1743 dotest(ww_test_context_block, FAILURE, LOCKTYPE_WW);
1744 dotest(ww_test_context_try, SUCCESS, LOCKTYPE_WW);
1745 dotest(ww_test_context_context, SUCCESS, LOCKTYPE_WW);
Michael Ellerman25139402016-11-25 09:45:28 +11001746 pr_cont("\n");
Maarten Lankhorst1de99442013-06-20 13:31:24 +02001747
1748 print_testname("try");
1749 dotest(ww_test_try_block, FAILURE, LOCKTYPE_WW);
1750 dotest(ww_test_try_try, SUCCESS, LOCKTYPE_WW);
1751 dotest(ww_test_try_context, FAILURE, LOCKTYPE_WW);
Michael Ellerman25139402016-11-25 09:45:28 +11001752 pr_cont("\n");
Maarten Lankhorst1de99442013-06-20 13:31:24 +02001753
1754 print_testname("block");
1755 dotest(ww_test_block_block, FAILURE, LOCKTYPE_WW);
1756 dotest(ww_test_block_try, SUCCESS, LOCKTYPE_WW);
1757 dotest(ww_test_block_context, FAILURE, LOCKTYPE_WW);
Michael Ellerman25139402016-11-25 09:45:28 +11001758 pr_cont("\n");
Maarten Lankhorst1de99442013-06-20 13:31:24 +02001759
1760 print_testname("spinlock");
1761 dotest(ww_test_spin_block, FAILURE, LOCKTYPE_WW);
1762 dotest(ww_test_spin_try, SUCCESS, LOCKTYPE_WW);
1763 dotest(ww_test_spin_context, FAILURE, LOCKTYPE_WW);
Michael Ellerman25139402016-11-25 09:45:28 +11001764 pr_cont("\n");
Maarten Lankhorst1de99442013-06-20 13:31:24 +02001765}
Ingo Molnarcae2ed92006-07-03 00:24:48 -07001766
1767void locking_selftest(void)
1768{
1769 /*
1770 * Got a locking failure before the selftest ran?
1771 */
1772 if (!debug_locks) {
1773 printk("----------------------------------\n");
1774 printk("| Locking API testsuite disabled |\n");
1775 printk("----------------------------------\n");
1776 return;
1777 }
1778
1779 /*
1780 * Run the testsuite:
1781 */
1782 printk("------------------------\n");
1783 printk("| Locking API testsuite:\n");
1784 printk("----------------------------------------------------------------------------\n");
1785 printk(" | spin |wlock |rlock |mutex | wsem | rsem |\n");
1786 printk(" --------------------------------------------------------------------------\n");
1787
1788 init_shared_classes();
1789 debug_locks_silent = !debug_locks_verbose;
1790
Ingo Molnar6c9076e2006-07-03 00:24:51 -07001791 DO_TESTCASE_6R("A-A deadlock", AA);
Ingo Molnarcae2ed92006-07-03 00:24:48 -07001792 DO_TESTCASE_6R("A-B-B-A deadlock", ABBA);
1793 DO_TESTCASE_6R("A-B-B-C-C-A deadlock", ABBCCA);
1794 DO_TESTCASE_6R("A-B-C-A-B-C deadlock", ABCABC);
1795 DO_TESTCASE_6R("A-B-B-C-C-D-D-A deadlock", ABBCCDDA);
1796 DO_TESTCASE_6R("A-B-C-D-B-D-D-A deadlock", ABCDBDDA);
1797 DO_TESTCASE_6R("A-B-C-D-B-C-D-A deadlock", ABCDBCDA);
1798 DO_TESTCASE_6("double unlock", double_unlock);
1799 DO_TESTCASE_6("initialize held", init_held);
Ingo Molnarcae2ed92006-07-03 00:24:48 -07001800
1801 printk(" --------------------------------------------------------------------------\n");
1802 print_testname("recursive read-lock");
Michael Ellerman25139402016-11-25 09:45:28 +11001803 pr_cont(" |");
Ingo Molnarcae2ed92006-07-03 00:24:48 -07001804 dotest(rlock_AA1, SUCCESS, LOCKTYPE_RWLOCK);
Michael Ellerman25139402016-11-25 09:45:28 +11001805 pr_cont(" |");
Ingo Molnarcae2ed92006-07-03 00:24:48 -07001806 dotest(rsem_AA1, FAILURE, LOCKTYPE_RWSEM);
Michael Ellerman25139402016-11-25 09:45:28 +11001807 pr_cont("\n");
Ingo Molnarcae2ed92006-07-03 00:24:48 -07001808
1809 print_testname("recursive read-lock #2");
Michael Ellerman25139402016-11-25 09:45:28 +11001810 pr_cont(" |");
Ingo Molnar6c9076e2006-07-03 00:24:51 -07001811 dotest(rlock_AA1B, SUCCESS, LOCKTYPE_RWLOCK);
Michael Ellerman25139402016-11-25 09:45:28 +11001812 pr_cont(" |");
Ingo Molnarcae2ed92006-07-03 00:24:48 -07001813 dotest(rsem_AA1B, FAILURE, LOCKTYPE_RWSEM);
Michael Ellerman25139402016-11-25 09:45:28 +11001814 pr_cont("\n");
Ingo Molnarcae2ed92006-07-03 00:24:48 -07001815
1816 print_testname("mixed read-write-lock");
Michael Ellerman25139402016-11-25 09:45:28 +11001817 pr_cont(" |");
Ingo Molnarcae2ed92006-07-03 00:24:48 -07001818 dotest(rlock_AA2, FAILURE, LOCKTYPE_RWLOCK);
Michael Ellerman25139402016-11-25 09:45:28 +11001819 pr_cont(" |");
Ingo Molnarcae2ed92006-07-03 00:24:48 -07001820 dotest(rsem_AA2, FAILURE, LOCKTYPE_RWSEM);
Michael Ellerman25139402016-11-25 09:45:28 +11001821 pr_cont("\n");
Ingo Molnarcae2ed92006-07-03 00:24:48 -07001822
1823 print_testname("mixed write-read-lock");
Michael Ellerman25139402016-11-25 09:45:28 +11001824 pr_cont(" |");
Ingo Molnarcae2ed92006-07-03 00:24:48 -07001825 dotest(rlock_AA3, FAILURE, LOCKTYPE_RWLOCK);
Michael Ellerman25139402016-11-25 09:45:28 +11001826 pr_cont(" |");
Ingo Molnarcae2ed92006-07-03 00:24:48 -07001827 dotest(rsem_AA3, FAILURE, LOCKTYPE_RWSEM);
Michael Ellerman25139402016-11-25 09:45:28 +11001828 pr_cont("\n");
Ingo Molnarcae2ed92006-07-03 00:24:48 -07001829
1830 printk(" --------------------------------------------------------------------------\n");
1831
1832 /*
1833 * irq-context testcases:
1834 */
1835 DO_TESTCASE_2x6("irqs-on + irq-safe-A", irqsafe1);
1836 DO_TESTCASE_2x3("sirq-safe-A => hirqs-on", irqsafe2A);
1837 DO_TESTCASE_2x6("safe-A + irqs-on", irqsafe2B);
1838 DO_TESTCASE_6x6("safe-A + unsafe-B #1", irqsafe3);
1839 DO_TESTCASE_6x6("safe-A + unsafe-B #2", irqsafe4);
1840 DO_TESTCASE_6x6RW("irq lock-inversion", irq_inversion);
1841
1842 DO_TESTCASE_6x2("irq read-recursion", irq_read_recursion);
1843// DO_TESTCASE_6x2B("irq read-recursion #2", irq_read_recursion2);
1844
Maarten Lankhorst1de99442013-06-20 13:31:24 +02001845 ww_tests();
1846
Ingo Molnarcae2ed92006-07-03 00:24:48 -07001847 if (unexpected_testcase_failures) {
1848 printk("-----------------------------------------------------------------\n");
1849 debug_locks = 0;
1850 printk("BUG: %3d unexpected failures (out of %3d) - debugging disabled! |\n",
1851 unexpected_testcase_failures, testcase_total);
1852 printk("-----------------------------------------------------------------\n");
1853 } else if (expected_testcase_failures && testcase_successes) {
1854 printk("--------------------------------------------------------\n");
1855 printk("%3d out of %3d testcases failed, as expected. |\n",
1856 expected_testcase_failures, testcase_total);
1857 printk("----------------------------------------------------\n");
1858 debug_locks = 1;
1859 } else if (expected_testcase_failures && !testcase_successes) {
1860 printk("--------------------------------------------------------\n");
1861 printk("All %3d testcases failed, as expected. |\n",
1862 expected_testcase_failures);
1863 printk("----------------------------------------\n");
1864 debug_locks = 1;
1865 } else {
1866 printk("-------------------------------------------------------\n");
1867 printk("Good, all %3d testcases passed! |\n",
1868 testcase_successes);
1869 printk("---------------------------------\n");
1870 debug_locks = 1;
1871 }
1872 debug_locks_silent = 0;
1873}