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