Browse Source

[PATCH] lockdep: locking API self tests

Introduce DEBUG_LOCKING_API_SELFTESTS, which uses the generic lock debugging
code's silent-failure feature to run a matrix of testcases.  There are 210
testcases currently:

  +-----------------------
  | Locking API testsuite:
  +------------------------------+------+------+------+------+------+------+
                                 | spin |wlock |rlock |mutex | wsem | rsem |
  -------------------------------+------+------+------+------+------+------+
                     A-A deadlock:  ok  |  ok  |  ok  |  ok  |  ok  |  ok  |
                 A-B-B-A deadlock:  ok  |  ok  |  ok  |  ok  |  ok  |  ok  |
             A-B-B-C-C-A deadlock:  ok  |  ok  |  ok  |  ok  |  ok  |  ok  |
             A-B-C-A-B-C deadlock:  ok  |  ok  |  ok  |  ok  |  ok  |  ok  |
         A-B-B-C-C-D-D-A deadlock:  ok  |  ok  |  ok  |  ok  |  ok  |  ok  |
         A-B-C-D-B-D-D-A deadlock:  ok  |  ok  |  ok  |  ok  |  ok  |  ok  |
         A-B-C-D-B-C-D-A deadlock:  ok  |  ok  |  ok  |  ok  |  ok  |  ok  |
                    double unlock:  ok  |  ok  |  ok  |  ok  |  ok  |  ok  |
                 bad unlock order:  ok  |  ok  |  ok  |  ok  |  ok  |  ok  |
  --------------------------------------+------+------+------+------+------+
              recursive read-lock:             |  ok  |             |  ok  |
  --------------------------------------+------+------+------+------+------+
                non-nested unlock:  ok  |  ok  |  ok  |  ok  |
  --------------------------------------+------+------+------+
     hard-irqs-on + irq-safe-A/12:  ok  |  ok  |  ok  |
     soft-irqs-on + irq-safe-A/12:  ok  |  ok  |  ok  |
     hard-irqs-on + irq-safe-A/21:  ok  |  ok  |  ok  |
     soft-irqs-on + irq-safe-A/21:  ok  |  ok  |  ok  |
       sirq-safe-A => hirqs-on/12:  ok  |  ok  |  ok  |
       sirq-safe-A => hirqs-on/21:  ok  |  ok  |  ok  |
         hard-safe-A + irqs-on/12:  ok  |  ok  |  ok  |
         soft-safe-A + irqs-on/12:  ok  |  ok  |  ok  |
         hard-safe-A + irqs-on/21:  ok  |  ok  |  ok  |
         soft-safe-A + irqs-on/21:  ok  |  ok  |  ok  |
    hard-safe-A + unsafe-B #1/123:  ok  |  ok  |  ok  |
    soft-safe-A + unsafe-B #1/123:  ok  |  ok  |  ok  |
    hard-safe-A + unsafe-B #1/132:  ok  |  ok  |  ok  |
    soft-safe-A + unsafe-B #1/132:  ok  |  ok  |  ok  |
    hard-safe-A + unsafe-B #1/213:  ok  |  ok  |  ok  |
    soft-safe-A + unsafe-B #1/213:  ok  |  ok  |  ok  |
    hard-safe-A + unsafe-B #1/231:  ok  |  ok  |  ok  |
    soft-safe-A + unsafe-B #1/231:  ok  |  ok  |  ok  |
    hard-safe-A + unsafe-B #1/312:  ok  |  ok  |  ok  |
    soft-safe-A + unsafe-B #1/312:  ok  |  ok  |  ok  |
    hard-safe-A + unsafe-B #1/321:  ok  |  ok  |  ok  |
    soft-safe-A + unsafe-B #1/321:  ok  |  ok  |  ok  |
    hard-safe-A + unsafe-B #2/123:  ok  |  ok  |  ok  |
    soft-safe-A + unsafe-B #2/123:  ok  |  ok  |  ok  |
    hard-safe-A + unsafe-B #2/132:  ok  |  ok  |  ok  |
    soft-safe-A + unsafe-B #2/132:  ok  |  ok  |  ok  |
    hard-safe-A + unsafe-B #2/213:  ok  |  ok  |  ok  |
    soft-safe-A + unsafe-B #2/213:  ok  |  ok  |  ok  |
    hard-safe-A + unsafe-B #2/231:  ok  |  ok  |  ok  |
    soft-safe-A + unsafe-B #2/231:  ok  |  ok  |  ok  |
    hard-safe-A + unsafe-B #2/312:  ok  |  ok  |  ok  |
    soft-safe-A + unsafe-B #2/312:  ok  |  ok  |  ok  |
    hard-safe-A + unsafe-B #2/321:  ok  |  ok  |  ok  |
    soft-safe-A + unsafe-B #2/321:  ok  |  ok  |  ok  |
      hard-irq lock-inversion/123:  ok  |  ok  |  ok  |
      soft-irq lock-inversion/123:  ok  |  ok  |  ok  |
      hard-irq lock-inversion/132:  ok  |  ok  |  ok  |
      soft-irq lock-inversion/132:  ok  |  ok  |  ok  |
      hard-irq lock-inversion/213:  ok  |  ok  |  ok  |
      soft-irq lock-inversion/213:  ok  |  ok  |  ok  |
      hard-irq lock-inversion/231:  ok  |  ok  |  ok  |
      soft-irq lock-inversion/231:  ok  |  ok  |  ok  |
      hard-irq lock-inversion/312:  ok  |  ok  |  ok  |
      soft-irq lock-inversion/312:  ok  |  ok  |  ok  |
      hard-irq lock-inversion/321:  ok  |  ok  |  ok  |
      soft-irq lock-inversion/321:  ok  |  ok  |  ok  |
      hard-irq read-recursion/123:  ok  |
      soft-irq read-recursion/123:  ok  |
      hard-irq read-recursion/132:  ok  |
      soft-irq read-recursion/132:  ok  |
      hard-irq read-recursion/213:  ok  |
      soft-irq read-recursion/213:  ok  |
      hard-irq read-recursion/231:  ok  |
      soft-irq read-recursion/231:  ok  |
      hard-irq read-recursion/312:  ok  |
      soft-irq read-recursion/312:  ok  |
      hard-irq read-recursion/321:  ok  |
      soft-irq read-recursion/321:  ok  |
  --------------------------------+-----+----------------
  Good, all 210 testcases passed! |
  --------------------------------+

Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
master
Ingo Molnar 15 years ago
committed by Linus Torvalds
parent
commit
cae2ed9aa5
18 changed files with 1347 additions and 0 deletions
  1. +9
    -0
      Documentation/kernel-parameters.txt
  2. +11
    -0
      lib/Kconfig.debug
  3. +1
    -0
      lib/Makefile
  4. +9
    -0
      lib/locking-selftest-hardirq.h
  5. +11
    -0
      lib/locking-selftest-mutex.h
  6. +2
    -0
      lib/locking-selftest-rlock-hardirq.h
  7. +2
    -0
      lib/locking-selftest-rlock-softirq.h
  8. +14
    -0
      lib/locking-selftest-rlock.h
  9. +14
    -0
      lib/locking-selftest-rsem.h
  10. +9
    -0
      lib/locking-selftest-softirq.h
  11. +2
    -0
      lib/locking-selftest-spin-hardirq.h
  12. +2
    -0
      lib/locking-selftest-spin-softirq.h
  13. +11
    -0
      lib/locking-selftest-spin.h
  14. +2
    -0
      lib/locking-selftest-wlock-hardirq.h
  15. +2
    -0
      lib/locking-selftest-wlock-softirq.h
  16. +14
    -0
      lib/locking-selftest-wlock.h
  17. +14
    -0
      lib/locking-selftest-wsem.h
  18. +1218
    -0
      lib/locking-selftest.c

+ 9
- 0
Documentation/kernel-parameters.txt View File

@ -435,6 +435,15 @@ running once the system is up.
debug [KNL] Enable kernel debugging (events log level).
debug_locks_verbose=
[KNL] verbose self-tests
Format=<0|1>
Print debugging info while doing the locking API
self-tests.
We default to 0 (no extra messages), setting it to
1 will print _a lot_ more information - normally
only useful to kernel developers.
decnet= [HW,NET]
Format: <area>[,<node>]
See also Documentation/networking/decnet.txt.


+ 11
- 0
lib/Kconfig.debug View File

@ -149,6 +149,17 @@ config DEBUG_SPINLOCK_SLEEP
If you say Y here, various routines which may sleep will become very
noisy if they are called with a spinlock held.
config DEBUG_LOCKING_API_SELFTESTS
bool "Locking API boot-time self-tests"
depends on DEBUG_KERNEL
help
Say Y here if you want the kernel to run a short self-test during
bootup. The self-test checks whether common types of locking bugs
are detected by debugging mechanisms or not. (if you disable
lock debugging then those bugs wont be detected of course.)
The following locking APIs are covered: spinlocks, rwlocks,
mutexes and rwsems.
config STACKTRACE
bool
depends on STACKTRACE_SUPPORT


+ 1
- 0
lib/Makefile View File

@ -18,6 +18,7 @@ CFLAGS_kobject.o += -DDEBUG
CFLAGS_kobject_uevent.o += -DDEBUG
endif
obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o
obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o
lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o


+ 9
- 0
lib/locking-selftest-hardirq.h View File

@ -0,0 +1,9 @@
#undef IRQ_DISABLE
#undef IRQ_ENABLE
#undef IRQ_ENTER
#undef IRQ_EXIT
#define IRQ_ENABLE HARDIRQ_ENABLE
#define IRQ_DISABLE HARDIRQ_DISABLE
#define IRQ_ENTER HARDIRQ_ENTER
#define IRQ_EXIT HARDIRQ_EXIT

+ 11
- 0
lib/locking-selftest-mutex.h View File

@ -0,0 +1,11 @@
#undef LOCK
#define LOCK ML
#undef UNLOCK
#define UNLOCK MU
#undef RLOCK
#undef WLOCK
#undef INIT
#define INIT MI

+ 2
- 0
lib/locking-selftest-rlock-hardirq.h View File

@ -0,0 +1,2 @@
#include "locking-selftest-rlock.h"
#include "locking-selftest-hardirq.h"

+ 2
- 0
lib/locking-selftest-rlock-softirq.h View File

@ -0,0 +1,2 @@
#include "locking-selftest-rlock.h"
#include "locking-selftest-softirq.h"

+ 14
- 0
lib/locking-selftest-rlock.h View File

@ -0,0 +1,14 @@
#undef LOCK
#define LOCK RL
#undef UNLOCK
#define UNLOCK RU
#undef RLOCK
#define RLOCK RL
#undef WLOCK
#define WLOCK WL
#undef INIT
#define INIT RWI

+ 14
- 0
lib/locking-selftest-rsem.h View File

@ -0,0 +1,14 @@
#undef LOCK
#define LOCK RSL
#undef UNLOCK
#define UNLOCK RSU
#undef RLOCK
#define RLOCK RSL
#undef WLOCK
#define WLOCK WSL
#undef INIT
#define INIT RWSI

+ 9
- 0
lib/locking-selftest-softirq.h View File

@ -0,0 +1,9 @@
#undef IRQ_DISABLE
#undef IRQ_ENABLE
#undef IRQ_ENTER
#undef IRQ_EXIT
#define IRQ_DISABLE SOFTIRQ_DISABLE
#define IRQ_ENABLE SOFTIRQ_ENABLE
#define IRQ_ENTER SOFTIRQ_ENTER
#define IRQ_EXIT SOFTIRQ_EXIT

+ 2
- 0
lib/locking-selftest-spin-hardirq.h View File

@ -0,0 +1,2 @@
#include "locking-selftest-spin.h"
#include "locking-selftest-hardirq.h"

+ 2
- 0
lib/locking-selftest-spin-softirq.h View File

@ -0,0 +1,2 @@
#include "locking-selftest-spin.h"
#include "locking-selftest-softirq.h"

+ 11
- 0
lib/locking-selftest-spin.h View File

@ -0,0 +1,11 @@
#undef LOCK
#define LOCK L
#undef UNLOCK
#define UNLOCK U
#undef RLOCK
#undef WLOCK
#undef INIT
#define INIT SI

+ 2
- 0
lib/locking-selftest-wlock-hardirq.h View File

@ -0,0 +1,2 @@
#include "locking-selftest-wlock.h"
#include "locking-selftest-hardirq.h"

+ 2
- 0
lib/locking-selftest-wlock-softirq.h View File

@ -0,0 +1,2 @@
#include "locking-selftest-wlock.h"
#include "locking-selftest-softirq.h"

+ 14
- 0
lib/locking-selftest-wlock.h View File

@ -0,0 +1,14 @@
#undef LOCK
#define LOCK WL
#undef UNLOCK
#define UNLOCK WU
#undef RLOCK
#define RLOCK RL
#undef WLOCK
#define WLOCK WL
#undef INIT
#define INIT RWI

+ 14
- 0
lib/locking-selftest-wsem.h View File

@ -0,0 +1,14 @@
#undef LOCK
#define LOCK WSL
#undef UNLOCK
#define UNLOCK WSU
#undef RLOCK
#define RLOCK RSL
#undef WLOCK
#define WLOCK WSL
#undef INIT
#define INIT RWSI

+ 1218
- 0
lib/locking-selftest.c
File diff suppressed because it is too large
View File


Loading…
Cancel
Save