lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1606131392-22645-4-git-send-email-byungchul.park@lge.com>
Date:   Mon, 23 Nov 2020 20:36:30 +0900
From:   Byungchul Park <byungchul.park@....com>
To:     torvalds@...ux-foundation.org, peterz@...radead.org,
        mingo@...hat.com, will@...nel.org
Cc:     linux-kernel@...r.kernel.org, tglx@...utronix.de,
        rostedt@...dmis.org, joel@...lfernandes.org,
        alexander.levin@...rosoft.com, daniel.vetter@...ll.ch,
        chris@...is-wilson.co.uk, duyuyang@...il.com,
        johannes.berg@...el.com, tj@...nel.org, tytso@....edu,
        willy@...radead.org, david@...morbit.com, amir73il@...il.com,
        bfields@...ldses.org, gregkh@...uxfoundation.org,
        kernel-team@....com
Subject: [RFC 4/6] dept: Apply Dept to rwlock

Makes Dept able to track dependencies by rwlock.

Signed-off-by: Byungchul Park <byungchul.park@....com>
---
 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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ