diff options
Diffstat (limited to 'lib/locking-selftest.c')
| -rw-r--r-- | lib/locking-selftest.c | 133 | 
1 files changed, 105 insertions, 28 deletions
diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c index f3a217ea0388..6f2b135dc5e8 100644 --- a/lib/locking-selftest.c +++ b/lib/locking-selftest.c @@ -21,6 +21,7 @@  #include <linux/interrupt.h>  #include <linux/debug_locks.h>  #include <linux/irqflags.h> +#include <linux/rtmutex.h>  /*   * Change this to 1 if you want to see the failure printouts: @@ -46,6 +47,7 @@ __setup("debug_locks_verbose=", setup_debug_locks_verbose);  #define LOCKTYPE_MUTEX	0x4  #define LOCKTYPE_RWSEM	0x8  #define LOCKTYPE_WW	0x10 +#define LOCKTYPE_RTMUTEX 0x20  static struct ww_acquire_ctx t, t2;  static struct ww_mutex o, o2, o3; @@ -74,6 +76,15 @@ static DECLARE_RWSEM(rwsem_B);  static DECLARE_RWSEM(rwsem_C);  static DECLARE_RWSEM(rwsem_D); +#ifdef CONFIG_RT_MUTEXES + +static DEFINE_RT_MUTEX(rtmutex_A); +static DEFINE_RT_MUTEX(rtmutex_B); +static DEFINE_RT_MUTEX(rtmutex_C); +static DEFINE_RT_MUTEX(rtmutex_D); + +#endif +  /*   * Locks that we initialize dynamically as well so that   * e.g. X1 and X2 becomes two instances of the same class, @@ -108,6 +119,17 @@ static DECLARE_RWSEM(rwsem_Y2);  static DECLARE_RWSEM(rwsem_Z1);  static DECLARE_RWSEM(rwsem_Z2); +#ifdef CONFIG_RT_MUTEXES + +static DEFINE_RT_MUTEX(rtmutex_X1); +static DEFINE_RT_MUTEX(rtmutex_X2); +static DEFINE_RT_MUTEX(rtmutex_Y1); +static DEFINE_RT_MUTEX(rtmutex_Y2); +static DEFINE_RT_MUTEX(rtmutex_Z1); +static DEFINE_RT_MUTEX(rtmutex_Z2); + +#endif +  /*   * non-inlined runtime initializers, to let separate locks share   * the same lock-class: @@ -129,6 +151,17 @@ INIT_CLASS_FUNC(Z)  static void init_shared_classes(void)  { +#ifdef CONFIG_RT_MUTEXES +	static struct lock_class_key rt_X, rt_Y, rt_Z; + +	__rt_mutex_init(&rtmutex_X1, __func__, &rt_X); +	__rt_mutex_init(&rtmutex_X2, __func__, &rt_X); +	__rt_mutex_init(&rtmutex_Y1, __func__, &rt_Y); +	__rt_mutex_init(&rtmutex_Y2, __func__, &rt_Y); +	__rt_mutex_init(&rtmutex_Z1, __func__, &rt_Z); +	__rt_mutex_init(&rtmutex_Z2, __func__, &rt_Z); +#endif +  	init_class_X(&lock_X1, &rwlock_X1, &mutex_X1, &rwsem_X1);  	init_class_X(&lock_X2, &rwlock_X2, &mutex_X2, &rwsem_X2); @@ -193,6 +226,10 @@ static void init_shared_classes(void)  #define MU(x)			mutex_unlock(&mutex_##x)  #define MI(x)			mutex_init(&mutex_##x) +#define RTL(x)			rt_mutex_lock(&rtmutex_##x) +#define RTU(x)			rt_mutex_unlock(&rtmutex_##x) +#define RTI(x)			rt_mutex_init(&rtmutex_##x) +  #define WSL(x)			down_write(&rwsem_##x)  #define WSU(x)			up_write(&rwsem_##x) @@ -264,6 +301,11 @@ GENERATE_TESTCASE(AA_wsem)  #include "locking-selftest-rsem.h"  GENERATE_TESTCASE(AA_rsem) +#ifdef CONFIG_RT_MUTEXES +#include "locking-selftest-rtmutex.h" +GENERATE_TESTCASE(AA_rtmutex); +#endif +  #undef E  /* @@ -345,6 +387,11 @@ GENERATE_TESTCASE(ABBA_wsem)  #include "locking-selftest-rsem.h"  GENERATE_TESTCASE(ABBA_rsem) +#ifdef CONFIG_RT_MUTEXES +#include "locking-selftest-rtmutex.h" +GENERATE_TESTCASE(ABBA_rtmutex); +#endif +  #undef E  /* @@ -373,6 +420,11 @@ GENERATE_TESTCASE(ABBCCA_wsem)  #include "locking-selftest-rsem.h"  GENERATE_TESTCASE(ABBCCA_rsem) +#ifdef CONFIG_RT_MUTEXES +#include "locking-selftest-rtmutex.h" +GENERATE_TESTCASE(ABBCCA_rtmutex); +#endif +  #undef E  /* @@ -401,6 +453,11 @@ GENERATE_TESTCASE(ABCABC_wsem)  #include "locking-selftest-rsem.h"  GENERATE_TESTCASE(ABCABC_rsem) +#ifdef CONFIG_RT_MUTEXES +#include "locking-selftest-rtmutex.h" +GENERATE_TESTCASE(ABCABC_rtmutex); +#endif +  #undef E  /* @@ -430,6 +487,11 @@ GENERATE_TESTCASE(ABBCCDDA_wsem)  #include "locking-selftest-rsem.h"  GENERATE_TESTCASE(ABBCCDDA_rsem) +#ifdef CONFIG_RT_MUTEXES +#include "locking-selftest-rtmutex.h" +GENERATE_TESTCASE(ABBCCDDA_rtmutex); +#endif +  #undef E  /* @@ -458,6 +520,11 @@ GENERATE_TESTCASE(ABCDBDDA_wsem)  #include "locking-selftest-rsem.h"  GENERATE_TESTCASE(ABCDBDDA_rsem) +#ifdef CONFIG_RT_MUTEXES +#include "locking-selftest-rtmutex.h" +GENERATE_TESTCASE(ABCDBDDA_rtmutex); +#endif +  #undef E  /* @@ -486,6 +553,11 @@ GENERATE_TESTCASE(ABCDBCDA_wsem)  #include "locking-selftest-rsem.h"  GENERATE_TESTCASE(ABCDBCDA_rsem) +#ifdef CONFIG_RT_MUTEXES +#include "locking-selftest-rtmutex.h" +GENERATE_TESTCASE(ABCDBCDA_rtmutex); +#endif +  #undef E  /* @@ -513,33 +585,10 @@ GENERATE_TESTCASE(double_unlock_wsem)  #include "locking-selftest-rsem.h"  GENERATE_TESTCASE(double_unlock_rsem) -#undef E - -/* - * Bad unlock ordering: - */ -#define E()					\ -						\ -	LOCK(A);				\ -	LOCK(B);				\ -	UNLOCK(A); /* fail */			\ -	UNLOCK(B); - -/* - * 6 testcases: - */ -#include "locking-selftest-spin.h" -GENERATE_TESTCASE(bad_unlock_order_spin) -#include "locking-selftest-wlock.h" -GENERATE_TESTCASE(bad_unlock_order_wlock) -#include "locking-selftest-rlock.h" -GENERATE_TESTCASE(bad_unlock_order_rlock) -#include "locking-selftest-mutex.h" -GENERATE_TESTCASE(bad_unlock_order_mutex) -#include "locking-selftest-wsem.h" -GENERATE_TESTCASE(bad_unlock_order_wsem) -#include "locking-selftest-rsem.h" -GENERATE_TESTCASE(bad_unlock_order_rsem) +#ifdef CONFIG_RT_MUTEXES +#include "locking-selftest-rtmutex.h" +GENERATE_TESTCASE(double_unlock_rtmutex); +#endif  #undef E @@ -567,6 +616,11 @@ GENERATE_TESTCASE(init_held_wsem)  #include "locking-selftest-rsem.h"  GENERATE_TESTCASE(init_held_rsem) +#ifdef CONFIG_RT_MUTEXES +#include "locking-selftest-rtmutex.h" +GENERATE_TESTCASE(init_held_rtmutex); +#endif +  #undef E  /* @@ -916,6 +970,9 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft)  # 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) +#ifdef CONFIG_RT_MUTEXES +# define I_RTMUTEX(x)	lockdep_reset_lock(&rtmutex_##x.dep_map) +#endif  #else  # define I_SPINLOCK(x)  # define I_RWLOCK(x) @@ -924,12 +981,23 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft)  # define I_WW(x)  #endif +#ifndef I_RTMUTEX +# define I_RTMUTEX(x) +#endif + +#ifdef CONFIG_RT_MUTEXES +#define I2_RTMUTEX(x)	rt_mutex_init(&rtmutex_##x) +#else +#define I2_RTMUTEX(x) +#endif +  #define I1(x)					\  	do {					\  		I_SPINLOCK(x);			\  		I_RWLOCK(x);			\  		I_MUTEX(x);			\  		I_RWSEM(x);			\ +		I_RTMUTEX(x);			\  	} while (0)  #define I2(x)					\ @@ -938,6 +1006,7 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft)  		rwlock_init(&rwlock_##x);	\  		mutex_init(&mutex_##x);		\  		init_rwsem(&rwsem_##x);		\ +		I2_RTMUTEX(x);			\  	} while (0)  static void reset_locks(void) @@ -1013,6 +1082,12 @@ static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask)  	reset_locks();  } +#ifdef CONFIG_RT_MUTEXES +#define dotest_rt(fn, e, m)	dotest((fn), (e), (m)) +#else +#define dotest_rt(fn, e, m) +#endif +  static inline void print_testname(const char *testname)  {  	printk("%33s:", testname); @@ -1050,6 +1125,7 @@ static inline void print_testname(const char *testname)  	dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX);		\  	dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM);		\  	dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM);		\ +	dotest_rt(name##_rtmutex, FAILURE, LOCKTYPE_RTMUTEX);	\  	pr_cont("\n");  #define DO_TESTCASE_6_SUCCESS(desc, name)			\ @@ -1060,6 +1136,7 @@ static inline void print_testname(const char *testname)  	dotest(name##_mutex, SUCCESS, LOCKTYPE_MUTEX);		\  	dotest(name##_wsem, SUCCESS, LOCKTYPE_RWSEM);		\  	dotest(name##_rsem, SUCCESS, LOCKTYPE_RWSEM);		\ +	dotest_rt(name##_rtmutex, SUCCESS, LOCKTYPE_RTMUTEX);	\  	pr_cont("\n");  /* @@ -1073,6 +1150,7 @@ static inline void print_testname(const char *testname)  	dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX);		\  	dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM);		\  	dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM);		\ +	dotest_rt(name##_rtmutex, FAILURE, LOCKTYPE_RTMUTEX);	\  	pr_cont("\n");  #define DO_TESTCASE_2I(desc, name, nr)				\ @@ -1825,7 +1903,6 @@ void locking_selftest(void)  	DO_TESTCASE_6R("A-B-C-D-B-C-D-A deadlock", ABCDBCDA);  	DO_TESTCASE_6("double unlock", double_unlock);  	DO_TESTCASE_6("initialize held", init_held); -	DO_TESTCASE_6_SUCCESS("bad unlock order", bad_unlock_order);  	printk("  --------------------------------------------------------------------------\n");  	print_testname("recursive read-lock");  |