[RFC 4/6] dept: Apply Dept to rwlock
From: Byungchul Park
Date: Mon Nov 23 2020 - 06:38:31 EST
Makes Dept able to track dependencies by rwlock.
Signed-off-by: Byungchul Park <byungchul.park@xxxxxxx>
---
include/linux/rwlock.h | 32 ++++++++++++++++++++++++++++++--
include/linux/rwlock_api_smp.h | 18 ++++++++++++++++++
include/linux/rwlock_types.h | 19 ++++++++++++++++---
kernel/locking/spinlock_debug.c | 4 +++-
4 files changed, 67 insertions(+), 6 deletions(-)
diff --git a/include/linux/rwlock.h b/include/linux/rwlock.h
index 3dcd617..f633341 100644
--- a/include/linux/rwlock.h
+++ b/include/linux/rwlock.h
@@ -16,18 +16,46 @@
#ifdef CONFIG_DEBUG_SPINLOCK
extern void __rwlock_init(rwlock_t *lock, const char *name,
- struct lock_class_key *key);
+ struct lock_class_key *key,
+ struct dept_key *dkey);
# define rwlock_init(lock) \
do { \
static struct lock_class_key __key; \
+ static struct dept_key __dkey; \
\
- __rwlock_init((lock), #lock, &__key); \
+ __rwlock_init((lock), #lock, &__key, &__dkey); \
} while (0)
#else
# define rwlock_init(lock) \
do { *(lock) = __RW_LOCK_UNLOCKED(lock); } while (0)
#endif
+#ifdef CONFIG_DEPT
+#define DEPT_EVT_R 1UL
+#define DEPT_EVT_W (1UL << 1)
+#define DEPT_EVT_RW (DEPT_EVT_R | DEPT_EVT_W)
+
+#define dept_rw_init(m, k, s, n) dept_map_init(m, k, s, n, DEPT_TYPE_RW)
+#define dept_rw_reinit(m, k, s, n) dept_map_reinit(m, k, s, n)
+#define dept_rw_nocheck(m) dept_map_nocheck(m)
+#define dept_write_lock(m, e_fn, ip) dept_wait_ecxt_enter(m, DEPT_EVT_RW, DEPT_EVT_W, ip, __func__, __func__, e_fn, 0)
+#define dept_write_trylock(m, e_fn, ip) dept_ecxt_enter(m, DEPT_EVT_W, ip, __func__, e_fn, 0)
+#define dept_write_unlock(m, ip) dept_ecxt_exit(m, ip)
+#define dept_read_lock(m, e_fn, ip) dept_wait_ecxt_enter(m, DEPT_EVT_W, DEPT_EVT_R, ip, __func__, __func__, e_fn, 0)
+#define dept_read_trylock(m, e_fn, ip) dept_ecxt_enter(m, DEPT_EVT_R, ip, __func__, e_fn, 0)
+#define dept_read_unlock(m, ip) dept_ecxt_exit(m, ip)
+#else
+#define dept_rw_init(m, k, s, n) do { (void)(n); (void)(k); } while (0)
+#define dept_rw_reinit(m, k, s, n) do { (void)(n); (void)(k); } while (0)
+#define dept_rw_nocheck(m) do { } while (0)
+#define dept_write_lock(m, e_fn, ip) do { } while (0)
+#define dept_write_trylock(m, e_fn, ip) do { } while (0)
+#define dept_write_unlock(m, ip) do { } while (0)
+#define dept_read_lock(m, e_fn, ip) do { } while (0)
+#define dept_read_trylock(m, e_fn, ip) do { } while (0)
+#define dept_read_unlock(m, ip) do { } while (0)
+#endif
+
#ifdef CONFIG_DEBUG_SPINLOCK
extern void do_raw_read_lock(rwlock_t *lock) __acquires(lock);
#define do_raw_read_lock_flags(lock, flags) do_raw_read_lock(lock)
diff --git a/include/linux/rwlock_api_smp.h b/include/linux/rwlock_api_smp.h
index abfb53a..2003104 100644
--- a/include/linux/rwlock_api_smp.h
+++ b/include/linux/rwlock_api_smp.h
@@ -119,6 +119,7 @@ static inline int __raw_read_trylock(rwlock_t *lock)
preempt_disable();
if (do_raw_read_trylock(lock)) {
rwlock_acquire_read(&lock->dep_map, 0, 1, _RET_IP_);
+ dept_read_trylock(&lock->dmap, "__raw_read_unlock", _RET_IP_);
return 1;
}
preempt_enable();
@@ -130,6 +131,7 @@ static inline int __raw_write_trylock(rwlock_t *lock)
preempt_disable();
if (do_raw_write_trylock(lock)) {
rwlock_acquire(&lock->dep_map, 0, 1, _RET_IP_);
+ dept_write_trylock(&lock->dmap, "__raw_write_unlock", _RET_IP_);
return 1;
}
preempt_enable();
@@ -147,6 +149,7 @@ static inline void __raw_read_lock(rwlock_t *lock)
{
preempt_disable();
rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_);
+ dept_read_lock(&lock->dmap, "__raw_read_unlock", _RET_IP_);
LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock);
}
@@ -157,6 +160,7 @@ static inline unsigned long __raw_read_lock_irqsave(rwlock_t *lock)
local_irq_save(flags);
preempt_disable();
rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_);
+ dept_read_lock(&lock->dmap, "__raw_read_unlock_irqrestore", _RET_IP_);
LOCK_CONTENDED_FLAGS(lock, do_raw_read_trylock, do_raw_read_lock,
do_raw_read_lock_flags, &flags);
return flags;
@@ -167,6 +171,7 @@ static inline void __raw_read_lock_irq(rwlock_t *lock)
local_irq_disable();
preempt_disable();
rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_);
+ dept_read_lock(&lock->dmap, "__raw_read_unlock_irq", _RET_IP_);
LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock);
}
@@ -174,6 +179,7 @@ static inline void __raw_read_lock_bh(rwlock_t *lock)
{
__local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_);
+ dept_read_lock(&lock->dmap, "__raw_read_unlock_bh", _RET_IP_);
LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock);
}
@@ -184,6 +190,7 @@ static inline unsigned long __raw_write_lock_irqsave(rwlock_t *lock)
local_irq_save(flags);
preempt_disable();
rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_);
+ dept_write_lock(&lock->dmap, "__raw_write_unlock_irqrestore", _RET_IP_);
LOCK_CONTENDED_FLAGS(lock, do_raw_write_trylock, do_raw_write_lock,
do_raw_write_lock_flags, &flags);
return flags;
@@ -194,6 +201,7 @@ static inline void __raw_write_lock_irq(rwlock_t *lock)
local_irq_disable();
preempt_disable();
rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_);
+ dept_write_lock(&lock->dmap, "__raw_write_unlock_irq", _RET_IP_);
LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock);
}
@@ -201,6 +209,7 @@ static inline void __raw_write_lock_bh(rwlock_t *lock)
{
__local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_);
+ dept_write_lock(&lock->dmap, "__raw_write_unlock_bh", _RET_IP_);
LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock);
}
@@ -208,6 +217,7 @@ static inline void __raw_write_lock(rwlock_t *lock)
{
preempt_disable();
rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_);
+ dept_write_lock(&lock->dmap, "__raw_write_unlock", _RET_IP_);
LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock);
}
@@ -216,6 +226,7 @@ static inline void __raw_write_lock(rwlock_t *lock)
static inline void __raw_write_unlock(rwlock_t *lock)
{
rwlock_release(&lock->dep_map, _RET_IP_);
+ dept_write_unlock(&lock->dmap, _RET_IP_);
do_raw_write_unlock(lock);
preempt_enable();
}
@@ -223,6 +234,7 @@ static inline void __raw_write_unlock(rwlock_t *lock)
static inline void __raw_read_unlock(rwlock_t *lock)
{
rwlock_release(&lock->dep_map, _RET_IP_);
+ dept_read_unlock(&lock->dmap, _RET_IP_);
do_raw_read_unlock(lock);
preempt_enable();
}
@@ -231,6 +243,7 @@ static inline void __raw_read_unlock(rwlock_t *lock)
__raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
{
rwlock_release(&lock->dep_map, _RET_IP_);
+ dept_read_unlock(&lock->dmap, _RET_IP_);
do_raw_read_unlock(lock);
local_irq_restore(flags);
preempt_enable();
@@ -239,6 +252,7 @@ static inline void __raw_read_unlock(rwlock_t *lock)
static inline void __raw_read_unlock_irq(rwlock_t *lock)
{
rwlock_release(&lock->dep_map, _RET_IP_);
+ dept_read_unlock(&lock->dmap, _RET_IP_);
do_raw_read_unlock(lock);
local_irq_enable();
preempt_enable();
@@ -247,6 +261,7 @@ static inline void __raw_read_unlock_irq(rwlock_t *lock)
static inline void __raw_read_unlock_bh(rwlock_t *lock)
{
rwlock_release(&lock->dep_map, _RET_IP_);
+ dept_read_unlock(&lock->dmap, _RET_IP_);
do_raw_read_unlock(lock);
__local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
}
@@ -255,6 +270,7 @@ static inline void __raw_write_unlock_irqrestore(rwlock_t *lock,
unsigned long flags)
{
rwlock_release(&lock->dep_map, _RET_IP_);
+ dept_write_unlock(&lock->dmap, _RET_IP_);
do_raw_write_unlock(lock);
local_irq_restore(flags);
preempt_enable();
@@ -263,6 +279,7 @@ static inline void __raw_write_unlock_irqrestore(rwlock_t *lock,
static inline void __raw_write_unlock_irq(rwlock_t *lock)
{
rwlock_release(&lock->dep_map, _RET_IP_);
+ dept_write_unlock(&lock->dmap, _RET_IP_);
do_raw_write_unlock(lock);
local_irq_enable();
preempt_enable();
@@ -271,6 +288,7 @@ static inline void __raw_write_unlock_irq(rwlock_t *lock)
static inline void __raw_write_unlock_bh(rwlock_t *lock)
{
rwlock_release(&lock->dep_map, _RET_IP_);
+ dept_write_unlock(&lock->dmap, _RET_IP_);
do_raw_write_unlock(lock);
__local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
}
diff --git a/include/linux/rwlock_types.h b/include/linux/rwlock_types.h
index 3bd03e1..1e79ea7 100644
--- a/include/linux/rwlock_types.h
+++ b/include/linux/rwlock_types.h
@@ -17,6 +17,7 @@
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif
+ struct dept_map dmap;
} rwlock_t;
#define RWLOCK_MAGIC 0xdeaf1eed
@@ -26,22 +27,34 @@
.dep_map = { \
.name = #lockname, \
.wait_type_inner = LD_WAIT_CONFIG, \
- }
+ },
#else
# define RW_DEP_MAP_INIT(lockname)
#endif
+#ifdef CONFIG_DEPT
+# define RW_DMAP_INIT(lockname) \
+ .dmap = { \
+ .name = #lockname, \
+ .type = DEPT_TYPE_RW, \
+ },
+#else
+# define RW_DMAP_INIT(lockname)
+#endif
+
#ifdef CONFIG_DEBUG_SPINLOCK
#define __RW_LOCK_UNLOCKED(lockname) \
(rwlock_t) { .raw_lock = __ARCH_RW_LOCK_UNLOCKED, \
.magic = RWLOCK_MAGIC, \
.owner = SPINLOCK_OWNER_INIT, \
.owner_cpu = -1, \
- RW_DEP_MAP_INIT(lockname) }
+ RW_DEP_MAP_INIT(lockname) \
+ RW_DMAP_INIT(lockname) }
#else
#define __RW_LOCK_UNLOCKED(lockname) \
(rwlock_t) { .raw_lock = __ARCH_RW_LOCK_UNLOCKED, \
- RW_DEP_MAP_INIT(lockname) }
+ RW_DEP_MAP_INIT(lockname) \
+ RW_DMAP_INIT(lockname) }
#endif
#define DEFINE_RWLOCK(x) rwlock_t x = __RW_LOCK_UNLOCKED(x)
diff --git a/kernel/locking/spinlock_debug.c b/kernel/locking/spinlock_debug.c
index 03e6812..f4deecb 100644
--- a/kernel/locking/spinlock_debug.c
+++ b/kernel/locking/spinlock_debug.c
@@ -34,7 +34,8 @@ void __raw_spin_lock_init(raw_spinlock_t *lock, const char *name,
EXPORT_SYMBOL(__raw_spin_lock_init);
void __rwlock_init(rwlock_t *lock, const char *name,
- struct lock_class_key *key)
+ struct lock_class_key *key,
+ struct dept_key *dkey)
{
#ifdef CONFIG_DEBUG_LOCK_ALLOC
/*
@@ -42,6 +43,7 @@ void __rwlock_init(rwlock_t *lock, const char *name,
*/
debug_check_no_locks_freed((void *)lock, sizeof(*lock));
lockdep_init_map_wait(&lock->dep_map, name, key, 0, LD_WAIT_CONFIG);
+ dept_rw_init(&lock->dmap, dkey, 0, name);
#endif
lock->raw_lock = (arch_rwlock_t) __ARCH_RW_LOCK_UNLOCKED;
lock->magic = RWLOCK_MAGIC;
--
1.9.1