Commit 018956d6 authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar

locking/selftest: Add RT-mutex support

Now that RT-mutex has lockdep annotations, add them to the selftest.
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent cfb61333
#undef LOCK
#define LOCK RTL
#undef UNLOCK
#define UNLOCK RTU
#undef RLOCK
#undef WLOCK
#undef INIT
#define INIT RTI
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/debug_locks.h> #include <linux/debug_locks.h>
#include <linux/irqflags.h> #include <linux/irqflags.h>
#include <linux/rtmutex.h>
/* /*
* Change this to 1 if you want to see the failure printouts: * Change this to 1 if you want to see the failure printouts:
...@@ -46,6 +47,7 @@ __setup("debug_locks_verbose=", setup_debug_locks_verbose); ...@@ -46,6 +47,7 @@ __setup("debug_locks_verbose=", setup_debug_locks_verbose);
#define LOCKTYPE_MUTEX 0x4 #define LOCKTYPE_MUTEX 0x4
#define LOCKTYPE_RWSEM 0x8 #define LOCKTYPE_RWSEM 0x8
#define LOCKTYPE_WW 0x10 #define LOCKTYPE_WW 0x10
#define LOCKTYPE_RTMUTEX 0x20
static struct ww_acquire_ctx t, t2; static struct ww_acquire_ctx t, t2;
static struct ww_mutex o, o2, o3; static struct ww_mutex o, o2, o3;
...@@ -74,6 +76,15 @@ static DECLARE_RWSEM(rwsem_B); ...@@ -74,6 +76,15 @@ static DECLARE_RWSEM(rwsem_B);
static DECLARE_RWSEM(rwsem_C); static DECLARE_RWSEM(rwsem_C);
static DECLARE_RWSEM(rwsem_D); 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 * Locks that we initialize dynamically as well so that
* e.g. X1 and X2 becomes two instances of the same class, * e.g. X1 and X2 becomes two instances of the same class,
...@@ -108,6 +119,17 @@ static DECLARE_RWSEM(rwsem_Y2); ...@@ -108,6 +119,17 @@ static DECLARE_RWSEM(rwsem_Y2);
static DECLARE_RWSEM(rwsem_Z1); static DECLARE_RWSEM(rwsem_Z1);
static DECLARE_RWSEM(rwsem_Z2); 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 * non-inlined runtime initializers, to let separate locks share
* the same lock-class: * the same lock-class:
...@@ -129,6 +151,17 @@ INIT_CLASS_FUNC(Z) ...@@ -129,6 +151,17 @@ INIT_CLASS_FUNC(Z)
static void init_shared_classes(void) 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_X1, &rwlock_X1, &mutex_X1, &rwsem_X1);
init_class_X(&lock_X2, &rwlock_X2, &mutex_X2, &rwsem_X2); init_class_X(&lock_X2, &rwlock_X2, &mutex_X2, &rwsem_X2);
...@@ -193,6 +226,10 @@ static void init_shared_classes(void) ...@@ -193,6 +226,10 @@ static void init_shared_classes(void)
#define MU(x) mutex_unlock(&mutex_##x) #define MU(x) mutex_unlock(&mutex_##x)
#define MI(x) mutex_init(&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 WSL(x) down_write(&rwsem_##x)
#define WSU(x) up_write(&rwsem_##x) #define WSU(x) up_write(&rwsem_##x)
...@@ -264,6 +301,11 @@ GENERATE_TESTCASE(AA_wsem) ...@@ -264,6 +301,11 @@ GENERATE_TESTCASE(AA_wsem)
#include "locking-selftest-rsem.h" #include "locking-selftest-rsem.h"
GENERATE_TESTCASE(AA_rsem) GENERATE_TESTCASE(AA_rsem)
#ifdef CONFIG_RT_MUTEXES
#include "locking-selftest-rtmutex.h"
GENERATE_TESTCASE(AA_rtmutex);
#endif
#undef E #undef E
/* /*
...@@ -345,6 +387,11 @@ GENERATE_TESTCASE(ABBA_wsem) ...@@ -345,6 +387,11 @@ GENERATE_TESTCASE(ABBA_wsem)
#include "locking-selftest-rsem.h" #include "locking-selftest-rsem.h"
GENERATE_TESTCASE(ABBA_rsem) GENERATE_TESTCASE(ABBA_rsem)
#ifdef CONFIG_RT_MUTEXES
#include "locking-selftest-rtmutex.h"
GENERATE_TESTCASE(ABBA_rtmutex);
#endif
#undef E #undef E
/* /*
...@@ -373,6 +420,11 @@ GENERATE_TESTCASE(ABBCCA_wsem) ...@@ -373,6 +420,11 @@ GENERATE_TESTCASE(ABBCCA_wsem)
#include "locking-selftest-rsem.h" #include "locking-selftest-rsem.h"
GENERATE_TESTCASE(ABBCCA_rsem) GENERATE_TESTCASE(ABBCCA_rsem)
#ifdef CONFIG_RT_MUTEXES
#include "locking-selftest-rtmutex.h"
GENERATE_TESTCASE(ABBCCA_rtmutex);
#endif
#undef E #undef E
/* /*
...@@ -401,6 +453,11 @@ GENERATE_TESTCASE(ABCABC_wsem) ...@@ -401,6 +453,11 @@ GENERATE_TESTCASE(ABCABC_wsem)
#include "locking-selftest-rsem.h" #include "locking-selftest-rsem.h"
GENERATE_TESTCASE(ABCABC_rsem) GENERATE_TESTCASE(ABCABC_rsem)
#ifdef CONFIG_RT_MUTEXES
#include "locking-selftest-rtmutex.h"
GENERATE_TESTCASE(ABCABC_rtmutex);
#endif
#undef E #undef E
/* /*
...@@ -430,6 +487,11 @@ GENERATE_TESTCASE(ABBCCDDA_wsem) ...@@ -430,6 +487,11 @@ GENERATE_TESTCASE(ABBCCDDA_wsem)
#include "locking-selftest-rsem.h" #include "locking-selftest-rsem.h"
GENERATE_TESTCASE(ABBCCDDA_rsem) GENERATE_TESTCASE(ABBCCDDA_rsem)
#ifdef CONFIG_RT_MUTEXES
#include "locking-selftest-rtmutex.h"
GENERATE_TESTCASE(ABBCCDDA_rtmutex);
#endif
#undef E #undef E
/* /*
...@@ -458,6 +520,11 @@ GENERATE_TESTCASE(ABCDBDDA_wsem) ...@@ -458,6 +520,11 @@ GENERATE_TESTCASE(ABCDBDDA_wsem)
#include "locking-selftest-rsem.h" #include "locking-selftest-rsem.h"
GENERATE_TESTCASE(ABCDBDDA_rsem) GENERATE_TESTCASE(ABCDBDDA_rsem)
#ifdef CONFIG_RT_MUTEXES
#include "locking-selftest-rtmutex.h"
GENERATE_TESTCASE(ABCDBDDA_rtmutex);
#endif
#undef E #undef E
/* /*
...@@ -486,6 +553,11 @@ GENERATE_TESTCASE(ABCDBCDA_wsem) ...@@ -486,6 +553,11 @@ GENERATE_TESTCASE(ABCDBCDA_wsem)
#include "locking-selftest-rsem.h" #include "locking-selftest-rsem.h"
GENERATE_TESTCASE(ABCDBCDA_rsem) GENERATE_TESTCASE(ABCDBCDA_rsem)
#ifdef CONFIG_RT_MUTEXES
#include "locking-selftest-rtmutex.h"
GENERATE_TESTCASE(ABCDBCDA_rtmutex);
#endif
#undef E #undef E
/* /*
...@@ -513,6 +585,11 @@ GENERATE_TESTCASE(double_unlock_wsem) ...@@ -513,6 +585,11 @@ GENERATE_TESTCASE(double_unlock_wsem)
#include "locking-selftest-rsem.h" #include "locking-selftest-rsem.h"
GENERATE_TESTCASE(double_unlock_rsem) GENERATE_TESTCASE(double_unlock_rsem)
#ifdef CONFIG_RT_MUTEXES
#include "locking-selftest-rtmutex.h"
GENERATE_TESTCASE(double_unlock_rtmutex);
#endif
#undef E #undef E
/* /*
...@@ -539,6 +616,11 @@ GENERATE_TESTCASE(init_held_wsem) ...@@ -539,6 +616,11 @@ GENERATE_TESTCASE(init_held_wsem)
#include "locking-selftest-rsem.h" #include "locking-selftest-rsem.h"
GENERATE_TESTCASE(init_held_rsem) GENERATE_TESTCASE(init_held_rsem)
#ifdef CONFIG_RT_MUTEXES
#include "locking-selftest-rtmutex.h"
GENERATE_TESTCASE(init_held_rtmutex);
#endif
#undef E #undef E
/* /*
...@@ -888,6 +970,9 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft) ...@@ -888,6 +970,9 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft)
# define I_MUTEX(x) lockdep_reset_lock(&mutex_##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_RWSEM(x) lockdep_reset_lock(&rwsem_##x.dep_map)
# define I_WW(x) lockdep_reset_lock(&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 #else
# define I_SPINLOCK(x) # define I_SPINLOCK(x)
# define I_RWLOCK(x) # define I_RWLOCK(x)
...@@ -896,12 +981,23 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft) ...@@ -896,12 +981,23 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft)
# define I_WW(x) # define I_WW(x)
#endif #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) \ #define I1(x) \
do { \ do { \
I_SPINLOCK(x); \ I_SPINLOCK(x); \
I_RWLOCK(x); \ I_RWLOCK(x); \
I_MUTEX(x); \ I_MUTEX(x); \
I_RWSEM(x); \ I_RWSEM(x); \
I_RTMUTEX(x); \
} while (0) } while (0)
#define I2(x) \ #define I2(x) \
...@@ -910,6 +1006,7 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft) ...@@ -910,6 +1006,7 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft)
rwlock_init(&rwlock_##x); \ rwlock_init(&rwlock_##x); \
mutex_init(&mutex_##x); \ mutex_init(&mutex_##x); \
init_rwsem(&rwsem_##x); \ init_rwsem(&rwsem_##x); \
I2_RTMUTEX(x); \
} while (0) } while (0)
static void reset_locks(void) static void reset_locks(void)
...@@ -985,6 +1082,12 @@ static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask) ...@@ -985,6 +1082,12 @@ static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask)
reset_locks(); 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) static inline void print_testname(const char *testname)
{ {
printk("%33s:", testname); printk("%33s:", testname);
...@@ -1022,6 +1125,7 @@ static inline void print_testname(const char *testname) ...@@ -1022,6 +1125,7 @@ static inline void print_testname(const char *testname)
dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \ dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \
dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \ dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \
dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \ dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \
dotest_rt(name##_rtmutex, FAILURE, LOCKTYPE_RTMUTEX); \
pr_cont("\n"); pr_cont("\n");
#define DO_TESTCASE_6_SUCCESS(desc, name) \ #define DO_TESTCASE_6_SUCCESS(desc, name) \
...@@ -1032,6 +1136,7 @@ static inline void print_testname(const char *testname) ...@@ -1032,6 +1136,7 @@ static inline void print_testname(const char *testname)
dotest(name##_mutex, SUCCESS, LOCKTYPE_MUTEX); \ dotest(name##_mutex, SUCCESS, LOCKTYPE_MUTEX); \
dotest(name##_wsem, SUCCESS, LOCKTYPE_RWSEM); \ dotest(name##_wsem, SUCCESS, LOCKTYPE_RWSEM); \
dotest(name##_rsem, SUCCESS, LOCKTYPE_RWSEM); \ dotest(name##_rsem, SUCCESS, LOCKTYPE_RWSEM); \
dotest_rt(name##_rtmutex, SUCCESS, LOCKTYPE_RTMUTEX); \
pr_cont("\n"); pr_cont("\n");
/* /*
...@@ -1045,6 +1150,7 @@ static inline void print_testname(const char *testname) ...@@ -1045,6 +1150,7 @@ static inline void print_testname(const char *testname)
dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \ dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \
dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \ dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \
dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \ dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \
dotest_rt(name##_rtmutex, FAILURE, LOCKTYPE_RTMUTEX); \
pr_cont("\n"); pr_cont("\n");
#define DO_TESTCASE_2I(desc, name, nr) \ #define DO_TESTCASE_2I(desc, name, nr) \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment