[PATCH v3 3/3] mutex: Add ww tests to lib/locking-selftest.c. v3

2013-04-28 Thread Maarten Lankhorst
This stresses the lockdep code in some ways specifically useful to
ww_mutexes. It adds checks for most of the common locking errors.

Changes since v1:
 - Add tests to verify reservation_id is untouched.
 - Use L() and U() macros where possible.

Changes since v2:
 - Use the ww_mutex api directly.
 - Use macros for most of the code.

Signed-off-by: Maarten Lankhorst 
---
 lib/locking-selftest.c |  439 ++--
 1 file changed, 420 insertions(+), 19 deletions(-)

diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c
index c3eb261..9cef196 100644
--- a/lib/locking-selftest.c
+++ b/lib/locking-selftest.c
@@ -26,6 +26,8 @@
  */
 static unsigned int debug_locks_verbose;
 
+static DEFINE_WW_CLASS(ww_lockdep);
+
 static int __init setup_debug_locks_verbose(char *str)
 {
get_option(, _locks_verbose);
@@ -42,6 +44,10 @@ __setup("debug_locks_verbose=", setup_debug_locks_verbose);
 #define LOCKTYPE_RWLOCK0x2
 #define LOCKTYPE_MUTEX 0x4
 #define LOCKTYPE_RWSEM 0x8
+#define LOCKTYPE_WW0x10
+
+static struct ww_acquire_ctx t, t2;
+static struct ww_mutex o, o2;
 
 /*
  * Normal standalone locks, for the circular and irq-context
@@ -193,6 +199,17 @@ static void init_shared_classes(void)
 #define RSU(x) up_read(_##x)
 #define RWSI(x)init_rwsem(_##x)
 
+#define WWAI(x)ww_acquire_init(x, _lockdep)
+#define WWAD(x)ww_acquire_done(x)
+#define WWAF(x)ww_acquire_fini(x)
+
+#define WWL(x, c)  ww_mutex_lock(x, c)
+#define WWU(x) ww_mutex_unlock(x)
+
+#define WWL1(x)ww_mutex_lock_single(x)
+#define WWT1(x)ww_mutex_trylock_single(x)
+#define WWU1(x)ww_mutex_unlock_single(x)
+
 #define LOCK_UNLOCK_2(x,y) LOCK(x); LOCK(y); UNLOCK(y); UNLOCK(x)
 
 /*
@@ -894,11 +911,13 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft)
 # define I_RWLOCK(x)   lockdep_reset_lock(_##x.dep_map)
 # define I_MUTEX(x)lockdep_reset_lock(_##x.dep_map)
 # define I_RWSEM(x)lockdep_reset_lock(_##x.dep_map)
+# define I_WW(x)   lockdep_reset_lock(_map)
 #else
 # define I_SPINLOCK(x)
 # define I_RWLOCK(x)
 # define I_MUTEX(x)
 # define I_RWSEM(x)
+# define I_WW(x)
 #endif
 
 #define I1(x)  \
@@ -920,11 +939,20 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft)
 static void reset_locks(void)
 {
local_irq_disable();
+   lockdep_free_key_range(_lockdep.acquire_key, 1);
+   lockdep_free_key_range(_lockdep.mutex_key, 1);
+
I1(A); I1(B); I1(C); I1(D);
I1(X1); I1(X2); I1(Y1); I1(Y2); I1(Z1); I1(Z2);
+   I_WW(t); I_WW(t2); I_WW(o.base); I_WW(o2.base);
lockdep_reset();
I2(A); I2(B); I2(C); I2(D);
init_shared_classes();
+
+   ww_mutex_init(, _lockdep); ww_mutex_init(, _lockdep);
+   memset(, 0, sizeof(t)); memset(, 0, sizeof(t2));
+   memset(_lockdep.acquire_key, 0, sizeof(ww_lockdep.acquire_key));
+   memset(_lockdep.mutex_key, 0, sizeof(ww_lockdep.mutex_key));
local_irq_enable();
 }
 
@@ -938,7 +966,6 @@ static int unexpected_testcase_failures;
 static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask)
 {
unsigned long saved_preempt_count = preempt_count();
-   int expected_failure = 0;
 
WARN_ON(irqs_disabled());
 
@@ -946,26 +973,16 @@ static void dotest(void (*testcase_fn)(void), int 
expected, int lockclass_mask)
/*
 * Filter out expected failures:
 */
+   if (debug_locks != expected) {
 #ifndef CONFIG_PROVE_LOCKING
-   if ((lockclass_mask & LOCKTYPE_SPIN) && debug_locks != expected)
-   expected_failure = 1;
-   if ((lockclass_mask & LOCKTYPE_RWLOCK) && debug_locks != expected)
-   expected_failure = 1;
-   if ((lockclass_mask & LOCKTYPE_MUTEX) && debug_locks != expected)
-   expected_failure = 1;
-   if ((lockclass_mask & LOCKTYPE_RWSEM) && debug_locks != expected)
-   expected_failure = 1;
+   expected_testcase_failures++;
+   printk("failed|");
+#else
+   unexpected_testcase_failures++;
+   printk("FAILED|");
+
+   dump_stack();
 #endif
-   if (debug_locks != expected) {
-   if (expected_failure) {
-   expected_testcase_failures++;
-   printk("failed|");
-   } else {
-   unexpected_testcase_failures++;
-
-   printk("FAILED|");
-   dump_stack();
-   }
} else {
testcase_successes++;
printk("  ok  |");
@@ -1108,6 +1125,388 @@ static inline void print_testname(const char *testname)
DO_TESTCASE_6IRW(desc, name, 312);  \
DO_TESTCASE_6IRW(desc, name, 

[PATCH v3 3/3] mutex: Add ww tests to lib/locking-selftest.c. v3

2013-04-28 Thread Maarten Lankhorst
This stresses the lockdep code in some ways specifically useful to
ww_mutexes. It adds checks for most of the common locking errors.

Changes since v1:
 - Add tests to verify reservation_id is untouched.
 - Use L() and U() macros where possible.

Changes since v2:
 - Use the ww_mutex api directly.
 - Use macros for most of the code.

Signed-off-by: Maarten Lankhorst maarten.lankho...@canonical.com
---
 lib/locking-selftest.c |  439 ++--
 1 file changed, 420 insertions(+), 19 deletions(-)

diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c
index c3eb261..9cef196 100644
--- a/lib/locking-selftest.c
+++ b/lib/locking-selftest.c
@@ -26,6 +26,8 @@
  */
 static unsigned int debug_locks_verbose;
 
+static DEFINE_WW_CLASS(ww_lockdep);
+
 static int __init setup_debug_locks_verbose(char *str)
 {
get_option(str, debug_locks_verbose);
@@ -42,6 +44,10 @@ __setup(debug_locks_verbose=, setup_debug_locks_verbose);
 #define LOCKTYPE_RWLOCK0x2
 #define LOCKTYPE_MUTEX 0x4
 #define LOCKTYPE_RWSEM 0x8
+#define LOCKTYPE_WW0x10
+
+static struct ww_acquire_ctx t, t2;
+static struct ww_mutex o, o2;
 
 /*
  * Normal standalone locks, for the circular and irq-context
@@ -193,6 +199,17 @@ static void init_shared_classes(void)
 #define RSU(x) up_read(rwsem_##x)
 #define RWSI(x)init_rwsem(rwsem_##x)
 
+#define WWAI(x)ww_acquire_init(x, ww_lockdep)
+#define WWAD(x)ww_acquire_done(x)
+#define WWAF(x)ww_acquire_fini(x)
+
+#define WWL(x, c)  ww_mutex_lock(x, c)
+#define WWU(x) ww_mutex_unlock(x)
+
+#define WWL1(x)ww_mutex_lock_single(x)
+#define WWT1(x)ww_mutex_trylock_single(x)
+#define WWU1(x)ww_mutex_unlock_single(x)
+
 #define LOCK_UNLOCK_2(x,y) LOCK(x); LOCK(y); UNLOCK(y); UNLOCK(x)
 
 /*
@@ -894,11 +911,13 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft)
 # define I_RWLOCK(x)   lockdep_reset_lock(rwlock_##x.dep_map)
 # define I_MUTEX(x)lockdep_reset_lock(mutex_##x.dep_map)
 # define I_RWSEM(x)lockdep_reset_lock(rwsem_##x.dep_map)
+# define I_WW(x)   lockdep_reset_lock(x.dep_map)
 #else
 # define I_SPINLOCK(x)
 # define I_RWLOCK(x)
 # define I_MUTEX(x)
 # define I_RWSEM(x)
+# define I_WW(x)
 #endif
 
 #define I1(x)  \
@@ -920,11 +939,20 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft)
 static void reset_locks(void)
 {
local_irq_disable();
+   lockdep_free_key_range(ww_lockdep.acquire_key, 1);
+   lockdep_free_key_range(ww_lockdep.mutex_key, 1);
+
I1(A); I1(B); I1(C); I1(D);
I1(X1); I1(X2); I1(Y1); I1(Y2); I1(Z1); I1(Z2);
+   I_WW(t); I_WW(t2); I_WW(o.base); I_WW(o2.base);
lockdep_reset();
I2(A); I2(B); I2(C); I2(D);
init_shared_classes();
+
+   ww_mutex_init(o, ww_lockdep); ww_mutex_init(o2, ww_lockdep);
+   memset(t, 0, sizeof(t)); memset(t2, 0, sizeof(t2));
+   memset(ww_lockdep.acquire_key, 0, sizeof(ww_lockdep.acquire_key));
+   memset(ww_lockdep.mutex_key, 0, sizeof(ww_lockdep.mutex_key));
local_irq_enable();
 }
 
@@ -938,7 +966,6 @@ static int unexpected_testcase_failures;
 static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask)
 {
unsigned long saved_preempt_count = preempt_count();
-   int expected_failure = 0;
 
WARN_ON(irqs_disabled());
 
@@ -946,26 +973,16 @@ static void dotest(void (*testcase_fn)(void), int 
expected, int lockclass_mask)
/*
 * Filter out expected failures:
 */
+   if (debug_locks != expected) {
 #ifndef CONFIG_PROVE_LOCKING
-   if ((lockclass_mask  LOCKTYPE_SPIN)  debug_locks != expected)
-   expected_failure = 1;
-   if ((lockclass_mask  LOCKTYPE_RWLOCK)  debug_locks != expected)
-   expected_failure = 1;
-   if ((lockclass_mask  LOCKTYPE_MUTEX)  debug_locks != expected)
-   expected_failure = 1;
-   if ((lockclass_mask  LOCKTYPE_RWSEM)  debug_locks != expected)
-   expected_failure = 1;
+   expected_testcase_failures++;
+   printk(failed|);
+#else
+   unexpected_testcase_failures++;
+   printk(FAILED|);
+
+   dump_stack();
 #endif
-   if (debug_locks != expected) {
-   if (expected_failure) {
-   expected_testcase_failures++;
-   printk(failed|);
-   } else {
-   unexpected_testcase_failures++;
-
-   printk(FAILED|);
-   dump_stack();
-   }
} else {
testcase_successes++;
printk(  ok  |);
@@ -1108,6 +1125,388 @@ static inline void print_testname(const char *testname)
DO_TESTCASE_6IRW(desc, name,