[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>
This commit is contained in:
Ingo Molnar 2006-07-03 00:24:48 -07:00 committed by Linus Torvalds
parent 1f194a4c39
commit cae2ed9aa5
18 changed files with 1347 additions and 0 deletions

View file

@ -435,6 +435,15 @@ running once the system is up.
debug [KNL] Enable kernel debugging (events log level). 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] decnet= [HW,NET]
Format: <area>[,<node>] Format: <area>[,<node>]
See also Documentation/networking/decnet.txt. See also Documentation/networking/decnet.txt.

View file

@ -149,6 +149,17 @@ config DEBUG_SPINLOCK_SLEEP
If you say Y here, various routines which may sleep will become very If you say Y here, various routines which may sleep will become very
noisy if they are called with a spinlock held. 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 config STACKTRACE
bool bool
depends on STACKTRACE_SUPPORT depends on STACKTRACE_SUPPORT

View file

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

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

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

View file

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

View file

@ -0,0 +1,2 @@
#include "locking-selftest-rlock.h"
#include "locking-selftest-softirq.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

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

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

View file

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

View file

@ -0,0 +1,2 @@
#include "locking-selftest-spin.h"
#include "locking-selftest-softirq.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

View file

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

View file

@ -0,0 +1,2 @@
#include "locking-selftest-wlock.h"
#include "locking-selftest-softirq.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

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
lib/locking-selftest.c Normal file

File diff suppressed because it is too large Load diff