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