[patch, -rc5-mm2] locking-API self-test fix

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Subject: locking-API self-test fix
From: Ingo Molnar <[email protected]>

Paolo Ornati's config triggered a CONFIG_DEBUG_LOCKING_API_SELFTESTS
bug: if CONFIG_PROVE_SPIN_LOCKING was enabled but CONFIG_PROVE_RW_LOCKING
was disabled, then the irq-recursion test incorrectly flagged the test
failure as an unexpected failure.

the fix is to pass in a 'mask' of lock types used in a particular
testcase, so that the generic testcase code can correctly figure out
whether a test's failure is expected or not.

there were two related bugs as well: rsem_AA1 used the wrong lock type
flag, and all the mutex tests used LOCKTYPE_SPIN instead of
LOCKTYPE_MUTEX.

with all these fixes all the separate debugging variants work fine now
if enabled standalone.

Signed-off-by: Ingo Molnar <[email protected]>
Signed-off-by: Arjan van de Ven <[email protected]>
---
 lib/locking-selftest.c |   81 +++++++++++++++++++++++++++++++------------------
 1 file changed, 52 insertions(+), 29 deletions(-)

Index: linux/lib/locking-selftest.c
===================================================================
--- linux.orig/lib/locking-selftest.c
+++ linux/lib/locking-selftest.c
@@ -39,12 +39,10 @@ __setup("debug_locks_verbose=", setup_de
 #define FAILURE		0
 #define SUCCESS		1
 
-enum {
-	LOCKTYPE_SPIN,
-	LOCKTYPE_RWLOCK,
-	LOCKTYPE_MUTEX,
-	LOCKTYPE_RWSEM,
-};
+#define LOCKTYPE_SPIN	0x1
+#define LOCKTYPE_RWLOCK	0x2
+#define LOCKTYPE_MUTEX	0x4
+#define LOCKTYPE_RWSEM	0x8
 
 /*
  * Normal standalone locks, for the circular and irq-context
@@ -931,37 +929,40 @@ static int testcase_successes;
 static int expected_testcase_failures;
 static int unexpected_testcase_failures;
 
-static void dotest(void (*testcase_fn)(void), int expected, int locktype)
+static void dotest(void (*testcase_fn)(void), int expected, int locktype_mask)
 {
 	unsigned long saved_preempt_count = preempt_count();
-	int unexpected_failure = 0;
+	int expected_failure = 0;
 
 	WARN_ON(irqs_disabled());
 
 	testcase_fn();
-#ifdef CONFIG_PROVE_SPIN_LOCKING
-	if (locktype == LOCKTYPE_SPIN && debug_locks != expected)
-		unexpected_failure = 1;
+	/*
+	 * Filter out expected failures:
+	 */
+#ifndef CONFIG_PROVE_SPIN_LOCKING
+	if ((locktype_mask & LOCKTYPE_SPIN) && debug_locks != expected)
+		expected_failure = 1;
 #endif
-#ifdef CONFIG_PROVE_RW_LOCKING
-	if (locktype == LOCKTYPE_RWLOCK && debug_locks != expected)
-		unexpected_failure = 1;
+#ifndef CONFIG_PROVE_RW_LOCKING
+	if ((locktype_mask & LOCKTYPE_RWLOCK) && debug_locks != expected)
+		expected_failure = 1;
 #endif
-#ifdef CONFIG_PROVE_MUTEX_LOCKING
-	if (locktype == LOCKTYPE_MUTEX && debug_locks != expected)
-		unexpected_failure = 1;
+#ifndef CONFIG_PROVE_MUTEX_LOCKING
+	if ((locktype_mask & LOCKTYPE_MUTEX) && debug_locks != expected)
+		expected_failure = 1;
 #endif
-#ifdef CONFIG_PROVE_RWSEM_LOCKING
-	if (locktype == LOCKTYPE_RWSEM && debug_locks != expected)
-		unexpected_failure = 1;
+#ifndef CONFIG_PROVE_RWSEM_LOCKING
+	if ((locktype_mask & LOCKTYPE_RWSEM) && debug_locks != expected)
+		expected_failure = 1;
 #endif
 	if (debug_locks != expected) {
-		if (unexpected_failure) {
-			unexpected_testcase_failures++;
-			printk("FAILED|");
-		} else {
+		if (expected_failure) {
 			expected_testcase_failures++;
 			printk("failed|");
+		} else {
+			unexpected_testcase_failures++;
+			printk("FAILED|");
 		}
 	} else {
 		testcase_successes++;
@@ -969,6 +970,9 @@ static void dotest(void (*testcase_fn)(v
 	}
 	testcase_total++;
 
+	if (debug_locks_verbose)
+		printk(" locktype mask: %x, debug_locks: %d, expected: %d\n",
+			locktype_mask, debug_locks, expected);
 	/*
 	 * Some tests (e.g. double-unlock) might corrupt the preemption
 	 * count, so restore it:
@@ -1006,12 +1010,19 @@ static inline void print_testname(const 
 	dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK);	\
 	printk("\n");
 
+#define DO_TESTCASE_3RW(desc, name, nr)				\
+	print_testname(desc"/"#nr);				\
+	dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN|LOCKTYPE_RWLOCK);\
+	dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK);	\
+	dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK);	\
+	printk("\n");
+
 #define DO_TESTCASE_6(desc, name)				\
 	print_testname(desc);					\
 	dotest(name##_spin, FAILURE, LOCKTYPE_SPIN);		\
 	dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK);		\
 	dotest(name##_rlock, FAILURE, LOCKTYPE_RWLOCK);		\
-	dotest(name##_mutex, FAILURE, LOCKTYPE_SPIN);		\
+	dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX);		\
 	dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM);		\
 	dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM);		\
 	printk("\n");
@@ -1024,7 +1035,7 @@ static inline void print_testname(const 
 	dotest(name##_spin, FAILURE, LOCKTYPE_SPIN);		\
 	dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK);		\
 	dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK);		\
-	dotest(name##_mutex, FAILURE, LOCKTYPE_SPIN);		\
+	dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX);		\
 	dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM);		\
 	dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM);		\
 	printk("\n");
@@ -1041,6 +1052,10 @@ static inline void print_testname(const 
 	DO_TESTCASE_3("hard-"desc, name##_hard, nr);		\
 	DO_TESTCASE_3("soft-"desc, name##_soft, nr);
 
+#define DO_TESTCASE_6IRW(desc, name, nr)			\
+	DO_TESTCASE_3RW("hard-"desc, name##_hard, nr);		\
+	DO_TESTCASE_3RW("soft-"desc, name##_soft, nr);
+
 #define DO_TESTCASE_2x3(desc, name)				\
 	DO_TESTCASE_3(desc, name, 12);				\
 	DO_TESTCASE_3(desc, name, 21);
@@ -1065,7 +1080,6 @@ static inline void print_testname(const 
 	DO_TESTCASE_2IB(desc, name, 312);			\
 	DO_TESTCASE_2IB(desc, name, 321);
 
-
 #define DO_TESTCASE_6x6(desc, name)				\
 	DO_TESTCASE_6I(desc, name, 123);			\
 	DO_TESTCASE_6I(desc, name, 132);			\
@@ -1074,6 +1088,15 @@ static inline void print_testname(const 
 	DO_TESTCASE_6I(desc, name, 312);			\
 	DO_TESTCASE_6I(desc, name, 321);
 
+#define DO_TESTCASE_6x6RW(desc, name)				\
+	DO_TESTCASE_6IRW(desc, name, 123);			\
+	DO_TESTCASE_6IRW(desc, name, 132);			\
+	DO_TESTCASE_6IRW(desc, name, 213);			\
+	DO_TESTCASE_6IRW(desc, name, 231);			\
+	DO_TESTCASE_6IRW(desc, name, 312);			\
+	DO_TESTCASE_6IRW(desc, name, 321);
+
+
 void locking_selftest(void)
 {
 	/*
@@ -1113,7 +1136,7 @@ void locking_selftest(void)
 	printk("             |");
 	dotest(rlock_AA1, SUCCESS, LOCKTYPE_RWLOCK);
 	printk("             |");
-	dotest(rsem_AA1, FAILURE, LOCKTYPE_RWLOCK);
+	dotest(rsem_AA1, FAILURE, LOCKTYPE_RWSEM);
 	printk("\n");
 
 	printk("  --------------------------------------------------------------------------\n");
@@ -1135,7 +1158,7 @@ void locking_selftest(void)
 	DO_TESTCASE_2x6("safe-A + irqs-on", irqsafe2B);
 	DO_TESTCASE_6x6("safe-A + unsafe-B #1", irqsafe3);
 	DO_TESTCASE_6x6("safe-A + unsafe-B #2", irqsafe4);
-	DO_TESTCASE_6x6("irq lock-inversion", irq_inversion);
+	DO_TESTCASE_6x6RW("irq lock-inversion", irq_inversion);
 
 	DO_TESTCASE_6x2("irq read-recursion", irq_read_recursion);
 //	DO_TESTCASE_6x2B("irq read-recursion #2", irq_read_recursion2);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux