public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] security/apparmor: Replace homebrew use of write_can_lock with lockdep
@ 2017-10-03 14:32 Will Deacon
  2017-10-03 14:32 ` [PATCH 2/2] locking: Remove {read,write}_can_lock Will Deacon
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Will Deacon @ 2017-10-03 14:32 UTC (permalink / raw)
  To: linux-kernel; +Cc: john.johansen, paulmck, Will Deacon, Peter Zijlstra

The lockdep subsystem provides a robust way to assert that a lock is
held, so use that instead of write_can_lock, which can give incorrect
results for qrwlocks.

Cc: John Johansen <john.johansen@canonical.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
 security/apparmor/include/lib.h | 11 -----------
 security/apparmor/label.c       |  8 ++++----
 2 files changed, 4 insertions(+), 15 deletions(-)

diff --git a/security/apparmor/include/lib.h b/security/apparmor/include/lib.h
index 436b3a722357..f546707a2bbb 100644
--- a/security/apparmor/include/lib.h
+++ b/security/apparmor/include/lib.h
@@ -19,17 +19,6 @@
 
 #include "match.h"
 
-/* Provide our own test for whether a write lock is held for asserts
- * this is because on none SMP systems write_can_lock will always
- * resolve to true, which is what you want for code making decisions
- * based on it, but wrong for asserts checking that the lock is held
- */
-#ifdef CONFIG_SMP
-#define write_is_locked(X) !write_can_lock(X)
-#else
-#define write_is_locked(X) (1)
-#endif /* CONFIG_SMP */
-
 /*
  * DEBUG remains global (no per profile flag) since it is mostly used in sysctl
  * which is not related to profile accesses.
diff --git a/security/apparmor/label.c b/security/apparmor/label.c
index c5b99b954580..ad28e03a6f30 100644
--- a/security/apparmor/label.c
+++ b/security/apparmor/label.c
@@ -80,7 +80,7 @@ void __aa_proxy_redirect(struct aa_label *orig, struct aa_label *new)
 
 	AA_BUG(!orig);
 	AA_BUG(!new);
-	AA_BUG(!write_is_locked(&labels_set(orig)->lock));
+	lockdep_assert_held_exclusive(&labels_set(orig)->lock);
 
 	tmp = rcu_dereference_protected(orig->proxy->label,
 					&labels_ns(orig)->lock);
@@ -571,7 +571,7 @@ static bool __label_remove(struct aa_label *label, struct aa_label *new)
 
 	AA_BUG(!ls);
 	AA_BUG(!label);
-	AA_BUG(!write_is_locked(&ls->lock));
+	lockdep_assert_held_exclusive(&ls->lock);
 
 	if (new)
 		__aa_proxy_redirect(label, new);
@@ -608,7 +608,7 @@ static bool __label_replace(struct aa_label *old, struct aa_label *new)
 	AA_BUG(!ls);
 	AA_BUG(!old);
 	AA_BUG(!new);
-	AA_BUG(!write_is_locked(&ls->lock));
+	lockdep_assert_held_exclusive(&ls->lock);
 	AA_BUG(new->flags & FLAG_IN_TREE);
 
 	if (!label_is_stale(old))
@@ -645,7 +645,7 @@ static struct aa_label *__label_insert(struct aa_labelset *ls,
 	AA_BUG(!ls);
 	AA_BUG(!label);
 	AA_BUG(labels_set(label) != ls);
-	AA_BUG(!write_is_locked(&ls->lock));
+	lockdep_assert_held_exclusive(&ls->lock);
 	AA_BUG(label->flags & FLAG_IN_TREE);
 
 	/* Figure out where to put new node */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] locking: Remove {read,write}_can_lock
  2017-10-03 14:32 [PATCH 1/2] security/apparmor: Replace homebrew use of write_can_lock with lockdep Will Deacon
@ 2017-10-03 14:32 ` Will Deacon
  2017-10-03 15:07 ` [PATCH 1/2] security/apparmor: Replace homebrew use of write_can_lock with lockdep Peter Zijlstra
  2017-10-03 15:33 ` John Johansen
  2 siblings, 0 replies; 5+ messages in thread
From: Will Deacon @ 2017-10-03 14:32 UTC (permalink / raw)
  To: linux-kernel; +Cc: john.johansen, paulmck, Will Deacon, Peter Zijlstra

read_can_lock has no users in tree, and the last remaining user of
write_can_lock (apparmor) is moved over to lockdep by the previous path.

Remove the unused macros, since they don't work in a concurrent environment
and can give incorrect results for qrwlock.

Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
 arch/alpha/include/asm/spinlock.h        | 10 ----------
 arch/arc/include/asm/spinlock.h          |  3 ---
 arch/arm/include/asm/spinlock.h          |  6 ------
 arch/blackfin/include/asm/spinlock.h     | 10 ----------
 arch/hexagon/include/asm/spinlock.h      | 10 ----------
 arch/ia64/include/asm/spinlock.h         |  3 ---
 arch/m32r/include/asm/spinlock.h         | 12 ------------
 arch/metag/include/asm/spinlock_lnkget.h | 30 ------------------------------
 arch/metag/include/asm/spinlock_lock1.h  | 20 --------------------
 arch/mn10300/include/asm/spinlock.h      | 12 ------------
 arch/parisc/include/asm/spinlock.h       | 18 ------------------
 arch/powerpc/include/asm/spinlock.h      |  3 ---
 arch/s390/include/asm/spinlock.h         | 12 ------------
 arch/sh/include/asm/spinlock-cas.h       | 12 ------------
 arch/sh/include/asm/spinlock-llsc.h      | 12 ------------
 arch/sparc/include/asm/spinlock_32.h     |  3 ---
 arch/tile/include/asm/spinlock_32.h      | 16 ----------------
 arch/tile/include/asm/spinlock_64.h      | 18 ------------------
 arch/xtensa/include/asm/spinlock.h       |  2 --
 include/asm-generic/qrwlock.h            | 20 --------------------
 include/linux/rwlock.h                   |  3 ---
 include/linux/spinlock_up.h              |  3 ---
 kernel/locking/spinlock.c                |  2 --
 23 files changed, 240 deletions(-)

diff --git a/arch/alpha/include/asm/spinlock.h b/arch/alpha/include/asm/spinlock.h
index 718ac0b64adf..7bff6316b8bb 100644
--- a/arch/alpha/include/asm/spinlock.h
+++ b/arch/alpha/include/asm/spinlock.h
@@ -54,16 +54,6 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)
 
 /***********************************************************/
 
-static inline int arch_read_can_lock(arch_rwlock_t *lock)
-{
-	return (lock->lock & 1) == 0;
-}
-
-static inline int arch_write_can_lock(arch_rwlock_t *lock)
-{
-	return lock->lock == 0;
-}
-
 static inline void arch_read_lock(arch_rwlock_t *lock)
 {
 	long regx;
diff --git a/arch/arc/include/asm/spinlock.h b/arch/arc/include/asm/spinlock.h
index 47efc8451b70..ce9bfcf1d870 100644
--- a/arch/arc/include/asm/spinlock.h
+++ b/arch/arc/include/asm/spinlock.h
@@ -410,9 +410,6 @@ static inline void arch_write_unlock(arch_rwlock_t *rw)
 
 #endif
 
-#define arch_read_can_lock(x)	((x)->counter > 0)
-#define arch_write_can_lock(x)	((x)->counter == __ARCH_RW_LOCK_UNLOCKED__)
-
 #define arch_read_lock_flags(lock, flags)	arch_read_lock(lock)
 #define arch_write_lock_flags(lock, flags)	arch_write_lock(lock)
 
diff --git a/arch/arm/include/asm/spinlock.h b/arch/arm/include/asm/spinlock.h
index c030143c18c6..f5223260c73e 100644
--- a/arch/arm/include/asm/spinlock.h
+++ b/arch/arm/include/asm/spinlock.h
@@ -193,9 +193,6 @@ static inline void arch_write_unlock(arch_rwlock_t *rw)
 	dsb_sev();
 }
 
-/* write_can_lock - would write_trylock() succeed? */
-#define arch_write_can_lock(x)		(ACCESS_ONCE((x)->lock) == 0)
-
 /*
  * Read locks are a bit more hairy:
  *  - Exclusively load the lock value.
@@ -273,9 +270,6 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
 	}
 }
 
-/* read_can_lock - would read_trylock() succeed? */
-#define arch_read_can_lock(x)		(ACCESS_ONCE((x)->lock) < 0x80000000)
-
 #define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
 #define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
 
diff --git a/arch/blackfin/include/asm/spinlock.h b/arch/blackfin/include/asm/spinlock.h
index f6431439d15d..607ef98c0f6c 100644
--- a/arch/blackfin/include/asm/spinlock.h
+++ b/arch/blackfin/include/asm/spinlock.h
@@ -48,16 +48,6 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
 	__raw_spin_unlock_asm(&lock->lock);
 }
 
-static inline int arch_read_can_lock(arch_rwlock_t *rw)
-{
-	return __raw_uncached_fetch_asm(&rw->lock) > 0;
-}
-
-static inline int arch_write_can_lock(arch_rwlock_t *rw)
-{
-	return __raw_uncached_fetch_asm(&rw->lock) == RW_LOCK_BIAS;
-}
-
 static inline void arch_read_lock(arch_rwlock_t *rw)
 {
 	__raw_read_lock_asm(&rw->lock);
diff --git a/arch/hexagon/include/asm/spinlock.h b/arch/hexagon/include/asm/spinlock.h
index 53a8d5885887..9f9414b9c303 100644
--- a/arch/hexagon/include/asm/spinlock.h
+++ b/arch/hexagon/include/asm/spinlock.h
@@ -86,16 +86,6 @@ static inline int arch_read_trylock(arch_rwlock_t *lock)
 	return temp;
 }
 
-static inline int arch_read_can_lock(arch_rwlock_t *rwlock)
-{
-	return rwlock->lock == 0;
-}
-
-static inline int arch_write_can_lock(arch_rwlock_t *rwlock)
-{
-	return rwlock->lock == 0;
-}
-
 /*  Stuffs a -1 in the lock value?  */
 static inline void arch_write_lock(arch_rwlock_t *lock)
 {
diff --git a/arch/ia64/include/asm/spinlock.h b/arch/ia64/include/asm/spinlock.h
index df2c121164b8..c728dda59bd2 100644
--- a/arch/ia64/include/asm/spinlock.h
+++ b/arch/ia64/include/asm/spinlock.h
@@ -127,9 +127,6 @@ static __always_inline void arch_spin_lock_flags(arch_spinlock_t *lock,
 	arch_spin_lock(lock);
 }
 
-#define arch_read_can_lock(rw)		(*(volatile int *)(rw) >= 0)
-#define arch_write_can_lock(rw)	(*(volatile int *)(rw) == 0)
-
 #ifdef ASM_SUPPORTED
 
 static __always_inline void
diff --git a/arch/m32r/include/asm/spinlock.h b/arch/m32r/include/asm/spinlock.h
index a56825592b90..002601371b2f 100644
--- a/arch/m32r/include/asm/spinlock.h
+++ b/arch/m32r/include/asm/spinlock.h
@@ -137,18 +137,6 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
  * semaphore.h for details.  -ben
  */
 
-/**
- * read_can_lock - would read_trylock() succeed?
- * @lock: the rwlock in question.
- */
-#define arch_read_can_lock(x) ((int)(x)->lock > 0)
-
-/**
- * write_can_lock - would write_trylock() succeed?
- * @lock: the rwlock in question.
- */
-#define arch_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS)
-
 static inline void arch_read_lock(arch_rwlock_t *rw)
 {
 	unsigned long tmp0, tmp1;
diff --git a/arch/metag/include/asm/spinlock_lnkget.h b/arch/metag/include/asm/spinlock_lnkget.h
index ad8436feed8d..6a932a952d53 100644
--- a/arch/metag/include/asm/spinlock_lnkget.h
+++ b/arch/metag/include/asm/spinlock_lnkget.h
@@ -136,21 +136,6 @@ static inline void arch_write_unlock(arch_rwlock_t *rw)
 		      : "memory");
 }
 
-/* write_can_lock - would write_trylock() succeed? */
-static inline int arch_write_can_lock(arch_rwlock_t *rw)
-{
-	int ret;
-
-	asm volatile ("LNKGETD	%0, [%1]\n"
-		      "CMP	%0, #0\n"
-		      "MOV	%0, #1\n"
-		      "XORNZ     %0, %0, %0\n"
-		      : "=&d" (ret)
-		      : "da" (&rw->lock)
-		      : "cc");
-	return ret;
-}
-
 /*
  * Read locks are a bit more hairy:
  *  - Exclusively load the lock value.
@@ -224,21 +209,6 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
 	return tmp;
 }
 
-/* read_can_lock - would read_trylock() succeed? */
-static inline int arch_read_can_lock(arch_rwlock_t *rw)
-{
-	int tmp;
-
-	asm volatile ("LNKGETD	%0, [%1]\n"
-		      "CMP	%0, %2\n"
-		      "MOV	%0, #1\n"
-		      "XORZ	%0, %0, %0\n"
-		      : "=&d" (tmp)
-		      : "da" (&rw->lock), "bd" (0x80000000)
-		      : "cc");
-	return tmp;
-}
-
 #define	arch_read_lock_flags(lock, flags) arch_read_lock(lock)
 #define	arch_write_lock_flags(lock, flags) arch_write_lock(lock)
 
diff --git a/arch/metag/include/asm/spinlock_lock1.h b/arch/metag/include/asm/spinlock_lock1.h
index c630444cffe9..8ae12bfc8ad8 100644
--- a/arch/metag/include/asm/spinlock_lock1.h
+++ b/arch/metag/include/asm/spinlock_lock1.h
@@ -104,16 +104,6 @@ static inline void arch_write_unlock(arch_rwlock_t *rw)
 	rw->lock = 0;
 }
 
-/* write_can_lock - would write_trylock() succeed? */
-static inline int arch_write_can_lock(arch_rwlock_t *rw)
-{
-	unsigned int ret;
-
-	barrier();
-	ret = rw->lock;
-	return (ret == 0);
-}
-
 /*
  * Read locks are a bit more hairy:
  *  - Exclusively load the lock value.
@@ -171,14 +161,4 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
 	return (ret < 0x80000000);
 }
 
-/* read_can_lock - would read_trylock() succeed? */
-static inline int arch_read_can_lock(arch_rwlock_t *rw)
-{
-	unsigned int ret;
-
-	barrier();
-	ret = rw->lock;
-	return (ret < 0x80000000);
-}
-
 #endif /* __ASM_SPINLOCK_LOCK1_H */
diff --git a/arch/mn10300/include/asm/spinlock.h b/arch/mn10300/include/asm/spinlock.h
index fe413b41df6c..54f75dac8094 100644
--- a/arch/mn10300/include/asm/spinlock.h
+++ b/arch/mn10300/include/asm/spinlock.h
@@ -98,18 +98,6 @@ static inline void arch_spin_lock_flags(arch_spinlock_t *lock,
  * read-locks.
  */
 
-/**
- * read_can_lock - would read_trylock() succeed?
- * @lock: the rwlock in question.
- */
-#define arch_read_can_lock(x) ((int)(x)->lock > 0)
-
-/**
- * write_can_lock - would write_trylock() succeed?
- * @lock: the rwlock in question.
- */
-#define arch_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS)
-
 /*
  * On mn10300, we implement read-write locks as a 32-bit counter
  * with the high bit (sign) being the "contended" bit.
diff --git a/arch/parisc/include/asm/spinlock.h b/arch/parisc/include/asm/spinlock.h
index 55bfe4affca3..136e1c9bb8a9 100644
--- a/arch/parisc/include/asm/spinlock.h
+++ b/arch/parisc/include/asm/spinlock.h
@@ -168,24 +168,6 @@ static __inline__ int arch_write_trylock(arch_rwlock_t *rw)
 	return result;
 }
 
-/*
- * read_can_lock - would read_trylock() succeed?
- * @lock: the rwlock in question.
- */
-static __inline__ int arch_read_can_lock(arch_rwlock_t *rw)
-{
-	return rw->counter >= 0;
-}
-
-/*
- * write_can_lock - would write_trylock() succeed?
- * @lock: the rwlock in question.
- */
-static __inline__ int arch_write_can_lock(arch_rwlock_t *rw)
-{
-	return !rw->counter;
-}
-
 #define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
 #define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
 
diff --git a/arch/powerpc/include/asm/spinlock.h b/arch/powerpc/include/asm/spinlock.h
index edbe571bcc54..d83f4f755ad8 100644
--- a/arch/powerpc/include/asm/spinlock.h
+++ b/arch/powerpc/include/asm/spinlock.h
@@ -181,9 +181,6 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
  * read-locks.
  */
 
-#define arch_read_can_lock(rw)		((rw)->lock >= 0)
-#define arch_write_can_lock(rw)	(!(rw)->lock)
-
 #ifdef CONFIG_PPC64
 #define __DO_SIGN_EXTEND	"extsw	%0,%0\n"
 #define WRLOCK_TOKEN		LOCK_TOKEN	/* it's negative */
diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h
index 8182b521c42f..dc9c58ed9e4c 100644
--- a/arch/s390/include/asm/spinlock.h
+++ b/arch/s390/include/asm/spinlock.h
@@ -110,18 +110,6 @@ static inline void arch_spin_unlock(arch_spinlock_t *lp)
  * read-locks.
  */
 
-/**
- * read_can_lock - would read_trylock() succeed?
- * @lock: the rwlock in question.
- */
-#define arch_read_can_lock(x) ((int)(x)->lock >= 0)
-
-/**
- * write_can_lock - would write_trylock() succeed?
- * @lock: the rwlock in question.
- */
-#define arch_write_can_lock(x) ((x)->lock == 0)
-
 extern int _raw_read_trylock_retry(arch_rwlock_t *lp);
 extern int _raw_write_trylock_retry(arch_rwlock_t *lp);
 
diff --git a/arch/sh/include/asm/spinlock-cas.h b/arch/sh/include/asm/spinlock-cas.h
index 5ed7dbbd94ff..315467834521 100644
--- a/arch/sh/include/asm/spinlock-cas.h
+++ b/arch/sh/include/asm/spinlock-cas.h
@@ -53,18 +53,6 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)
  * read-locks.
  */
 
-/**
- * read_can_lock - would read_trylock() succeed?
- * @lock: the rwlock in question.
- */
-#define arch_read_can_lock(x)	((x)->lock > 0)
-
-/**
- * write_can_lock - would write_trylock() succeed?
- * @lock: the rwlock in question.
- */
-#define arch_write_can_lock(x)	((x)->lock == RW_LOCK_BIAS)
-
 static inline void arch_read_lock(arch_rwlock_t *rw)
 {
 	unsigned old;
diff --git a/arch/sh/include/asm/spinlock-llsc.h b/arch/sh/include/asm/spinlock-llsc.h
index f77263aae760..06be4a55f3c4 100644
--- a/arch/sh/include/asm/spinlock-llsc.h
+++ b/arch/sh/include/asm/spinlock-llsc.h
@@ -89,18 +89,6 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)
  * read-locks.
  */
 
-/**
- * read_can_lock - would read_trylock() succeed?
- * @lock: the rwlock in question.
- */
-#define arch_read_can_lock(x)	((x)->lock > 0)
-
-/**
- * write_can_lock - would write_trylock() succeed?
- * @lock: the rwlock in question.
- */
-#define arch_write_can_lock(x)	((x)->lock == RW_LOCK_BIAS)
-
 static inline void arch_read_lock(arch_rwlock_t *rw)
 {
 	unsigned long tmp;
diff --git a/arch/sparc/include/asm/spinlock_32.h b/arch/sparc/include/asm/spinlock_32.h
index 67345b2dc408..76986b8f7dad 100644
--- a/arch/sparc/include/asm/spinlock_32.h
+++ b/arch/sparc/include/asm/spinlock_32.h
@@ -190,9 +190,6 @@ static inline int __arch_read_trylock(arch_rwlock_t *rw)
 #define arch_read_relax(lock)	cpu_relax()
 #define arch_write_relax(lock)	cpu_relax()
 
-#define arch_read_can_lock(rw) (!((rw)->lock & 0xff))
-#define arch_write_can_lock(rw) (!(rw)->lock)
-
 #endif /* !(__ASSEMBLY__) */
 
 #endif /* __SPARC_SPINLOCK_H */
diff --git a/arch/tile/include/asm/spinlock_32.h b/arch/tile/include/asm/spinlock_32.h
index cba8ba9b8da6..91d05f21cba9 100644
--- a/arch/tile/include/asm/spinlock_32.h
+++ b/arch/tile/include/asm/spinlock_32.h
@@ -80,22 +80,6 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
 #define _RD_COUNT_WIDTH 8
 
 /**
- * arch_read_can_lock() - would read_trylock() succeed?
- */
-static inline int arch_read_can_lock(arch_rwlock_t *rwlock)
-{
-	return (rwlock->lock << _RD_COUNT_WIDTH) == 0;
-}
-
-/**
- * arch_write_can_lock() - would write_trylock() succeed?
- */
-static inline int arch_write_can_lock(arch_rwlock_t *rwlock)
-{
-	return rwlock->lock == 0;
-}
-
-/**
  * arch_read_lock() - acquire a read lock.
  */
 void arch_read_lock(arch_rwlock_t *rwlock);
diff --git a/arch/tile/include/asm/spinlock_64.h b/arch/tile/include/asm/spinlock_64.h
index 9a2c2d605752..c802f48badf4 100644
--- a/arch/tile/include/asm/spinlock_64.h
+++ b/arch/tile/include/asm/spinlock_64.h
@@ -93,24 +93,6 @@ static inline int arch_write_val_locked(int val)
 	return val < 0;  /* Optimize "val & __WRITE_LOCK_BIT". */
 }
 
-/**
- * read_can_lock - would read_trylock() succeed?
- * @lock: the rwlock in question.
- */
-static inline int arch_read_can_lock(arch_rwlock_t *rw)
-{
-	return !arch_write_val_locked(rw->lock);
-}
-
-/**
- * write_can_lock - would write_trylock() succeed?
- * @lock: the rwlock in question.
- */
-static inline int arch_write_can_lock(arch_rwlock_t *rw)
-{
-	return rw->lock == 0;
-}
-
 extern void __read_lock_failed(arch_rwlock_t *rw);
 
 static inline void arch_read_lock(arch_rwlock_t *rw)
diff --git a/arch/xtensa/include/asm/spinlock.h b/arch/xtensa/include/asm/spinlock.h
index 3bb49681ee24..d005af51e2e1 100644
--- a/arch/xtensa/include/asm/spinlock.h
+++ b/arch/xtensa/include/asm/spinlock.h
@@ -97,8 +97,6 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
  *  0x80000000  one writer owns the rwlock, no other writers, no readers
  */
 
-#define arch_write_can_lock(x)  ((x)->lock == 0)
-
 static inline void arch_write_lock(arch_rwlock_t *rw)
 {
 	unsigned long tmp;
diff --git a/include/asm-generic/qrwlock.h b/include/asm-generic/qrwlock.h
index 7d026bf27713..50925327b0a8 100644
--- a/include/asm-generic/qrwlock.h
+++ b/include/asm-generic/qrwlock.h
@@ -53,24 +53,6 @@ extern void queued_read_lock_slowpath(struct qrwlock *lock, u32 cnts);
 extern void queued_write_lock_slowpath(struct qrwlock *lock);
 
 /**
- * queued_read_can_lock- would read_trylock() succeed?
- * @lock: Pointer to queue rwlock structure
- */
-static inline int queued_read_can_lock(struct qrwlock *lock)
-{
-	return !(atomic_read(&lock->cnts) & _QW_WMASK);
-}
-
-/**
- * queued_write_can_lock- would write_trylock() succeed?
- * @lock: Pointer to queue rwlock structure
- */
-static inline int queued_write_can_lock(struct qrwlock *lock)
-{
-	return !atomic_read(&lock->cnts);
-}
-
-/**
  * queued_read_trylock - try to acquire read lock of a queue rwlock
  * @lock : Pointer to queue rwlock structure
  * Return: 1 if lock acquired, 0 if failed
@@ -169,8 +151,6 @@ static inline void queued_write_unlock(struct qrwlock *lock)
  * Remapping rwlock architecture specific functions to the corresponding
  * queue rwlock functions.
  */
-#define arch_read_can_lock(l)	queued_read_can_lock(l)
-#define arch_write_can_lock(l)	queued_write_can_lock(l)
 #define arch_read_lock(l)	queued_read_lock(l)
 #define arch_write_lock(l)	queued_write_lock(l)
 #define arch_read_trylock(l)	queued_read_trylock(l)
diff --git a/include/linux/rwlock.h b/include/linux/rwlock.h
index bc2994ed66e1..766c5ca5cbd1 100644
--- a/include/linux/rwlock.h
+++ b/include/linux/rwlock.h
@@ -50,9 +50,6 @@ do {								\
 # define do_raw_write_unlock(rwlock)	do {arch_write_unlock(&(rwlock)->raw_lock); __release(lock); } while (0)
 #endif
 
-#define read_can_lock(rwlock)		arch_read_can_lock(&(rwlock)->raw_lock)
-#define write_can_lock(rwlock)		arch_write_can_lock(&(rwlock)->raw_lock)
-
 /*
  * Define the various rw_lock methods.  Note we define these
  * regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The various
diff --git a/include/linux/spinlock_up.h b/include/linux/spinlock_up.h
index 612fb530af41..901cf8f44388 100644
--- a/include/linux/spinlock_up.h
+++ b/include/linux/spinlock_up.h
@@ -77,7 +77,4 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
 
 #define arch_spin_is_contended(lock)	(((void)(lock), 0))
 
-#define arch_read_can_lock(lock)	(((void)(lock), 1))
-#define arch_write_can_lock(lock)	(((void)(lock), 1))
-
 #endif /* __LINUX_SPINLOCK_UP_H */
diff --git a/kernel/locking/spinlock.c b/kernel/locking/spinlock.c
index 4b082b5cac9e..42ee9d0a1ea4 100644
--- a/kernel/locking/spinlock.c
+++ b/kernel/locking/spinlock.c
@@ -32,8 +32,6 @@
  * include/linux/spinlock_api_smp.h
  */
 #else
-#define raw_read_can_lock(l)	read_can_lock(l)
-#define raw_write_can_lock(l)	write_can_lock(l)
 
 /*
  * Some architectures can relax in favour of the CPU owning the lock.
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] security/apparmor: Replace homebrew use of write_can_lock with lockdep
  2017-10-03 14:32 [PATCH 1/2] security/apparmor: Replace homebrew use of write_can_lock with lockdep Will Deacon
  2017-10-03 14:32 ` [PATCH 2/2] locking: Remove {read,write}_can_lock Will Deacon
@ 2017-10-03 15:07 ` Peter Zijlstra
  2017-10-03 16:58   ` Will Deacon
  2017-10-03 15:33 ` John Johansen
  2 siblings, 1 reply; 5+ messages in thread
From: Peter Zijlstra @ 2017-10-03 15:07 UTC (permalink / raw)
  To: Will Deacon; +Cc: linux-kernel, john.johansen, paulmck

On Tue, Oct 03, 2017 at 03:32:45PM +0100, Will Deacon wrote:
> The lockdep subsystem provides a robust way to assert that a lock is
> held, so use that instead of write_can_lock, which can give incorrect
> results for qrwlocks.
> 
> Cc: John Johansen <john.johansen@canonical.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Signed-off-by: Will Deacon <will.deacon@arm.com>

Thanks Will, good to be able to finally remove that API.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] security/apparmor: Replace homebrew use of write_can_lock with lockdep
  2017-10-03 14:32 [PATCH 1/2] security/apparmor: Replace homebrew use of write_can_lock with lockdep Will Deacon
  2017-10-03 14:32 ` [PATCH 2/2] locking: Remove {read,write}_can_lock Will Deacon
  2017-10-03 15:07 ` [PATCH 1/2] security/apparmor: Replace homebrew use of write_can_lock with lockdep Peter Zijlstra
@ 2017-10-03 15:33 ` John Johansen
  2 siblings, 0 replies; 5+ messages in thread
From: John Johansen @ 2017-10-03 15:33 UTC (permalink / raw)
  To: Will Deacon, linux-kernel; +Cc: paulmck, Peter Zijlstra

On 10/03/2017 07:32 AM, Will Deacon wrote:
> The lockdep subsystem provides a robust way to assert that a lock is
> held, so use that instead of write_can_lock, which can give incorrect
> results for qrwlocks.
> 
> Cc: John Johansen <john.johansen@canonical.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Signed-off-by: Will Deacon <will.deacon@arm.com>

oh nice,

Acked-by: John Johansen <john.johansen@canonical.com>



> ---
>  security/apparmor/include/lib.h | 11 -----------
>  security/apparmor/label.c       |  8 ++++----
>  2 files changed, 4 insertions(+), 15 deletions(-)
> 
> diff --git a/security/apparmor/include/lib.h b/security/apparmor/include/lib.h
> index 436b3a722357..f546707a2bbb 100644
> --- a/security/apparmor/include/lib.h
> +++ b/security/apparmor/include/lib.h
> @@ -19,17 +19,6 @@
>  
>  #include "match.h"
>  
> -/* Provide our own test for whether a write lock is held for asserts
> - * this is because on none SMP systems write_can_lock will always
> - * resolve to true, which is what you want for code making decisions
> - * based on it, but wrong for asserts checking that the lock is held
> - */
> -#ifdef CONFIG_SMP
> -#define write_is_locked(X) !write_can_lock(X)
> -#else
> -#define write_is_locked(X) (1)
> -#endif /* CONFIG_SMP */
> -
>  /*
>   * DEBUG remains global (no per profile flag) since it is mostly used in sysctl
>   * which is not related to profile accesses.
> diff --git a/security/apparmor/label.c b/security/apparmor/label.c
> index c5b99b954580..ad28e03a6f30 100644
> --- a/security/apparmor/label.c
> +++ b/security/apparmor/label.c
> @@ -80,7 +80,7 @@ void __aa_proxy_redirect(struct aa_label *orig, struct aa_label *new)
>  
>  	AA_BUG(!orig);
>  	AA_BUG(!new);
> -	AA_BUG(!write_is_locked(&labels_set(orig)->lock));
> +	lockdep_assert_held_exclusive(&labels_set(orig)->lock);
>  
>  	tmp = rcu_dereference_protected(orig->proxy->label,
>  					&labels_ns(orig)->lock);
> @@ -571,7 +571,7 @@ static bool __label_remove(struct aa_label *label, struct aa_label *new)
>  
>  	AA_BUG(!ls);
>  	AA_BUG(!label);
> -	AA_BUG(!write_is_locked(&ls->lock));
> +	lockdep_assert_held_exclusive(&ls->lock);
>  
>  	if (new)
>  		__aa_proxy_redirect(label, new);
> @@ -608,7 +608,7 @@ static bool __label_replace(struct aa_label *old, struct aa_label *new)
>  	AA_BUG(!ls);
>  	AA_BUG(!old);
>  	AA_BUG(!new);
> -	AA_BUG(!write_is_locked(&ls->lock));
> +	lockdep_assert_held_exclusive(&ls->lock);
>  	AA_BUG(new->flags & FLAG_IN_TREE);
>  
>  	if (!label_is_stale(old))
> @@ -645,7 +645,7 @@ static struct aa_label *__label_insert(struct aa_labelset *ls,
>  	AA_BUG(!ls);
>  	AA_BUG(!label);
>  	AA_BUG(labels_set(label) != ls);
> -	AA_BUG(!write_is_locked(&ls->lock));
> +	lockdep_assert_held_exclusive(&ls->lock);
>  	AA_BUG(label->flags & FLAG_IN_TREE);
>  
>  	/* Figure out where to put new node */
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] security/apparmor: Replace homebrew use of write_can_lock with lockdep
  2017-10-03 15:07 ` [PATCH 1/2] security/apparmor: Replace homebrew use of write_can_lock with lockdep Peter Zijlstra
@ 2017-10-03 16:58   ` Will Deacon
  0 siblings, 0 replies; 5+ messages in thread
From: Will Deacon @ 2017-10-03 16:58 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: linux-kernel, john.johansen, paulmck

On Tue, Oct 03, 2017 at 05:07:09PM +0200, Peter Zijlstra wrote:
> On Tue, Oct 03, 2017 at 03:32:45PM +0100, Will Deacon wrote:
> > The lockdep subsystem provides a robust way to assert that a lock is
> > held, so use that instead of write_can_lock, which can give incorrect
> > results for qrwlocks.
> > 
> > Cc: John Johansen <john.johansen@canonical.com>
> > Cc: Peter Zijlstra <peterz@infradead.org>
> > Signed-off-by: Will Deacon <will.deacon@arm.com>
> 
> Thanks Will, good to be able to finally remove that API.

Yup, but my grep-fu missed these guys in kernel/locking/spinlock.c:

	while (!raw_##op##_can_lock(lock) && (lock)->break_lock

so diff below to catch those and remove spin_can_lock too.

Let me spin a v2...

Will

--->8

diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index 69e079c5ff98..1e3e48041800 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -278,12 +278,6 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock)
 	1 : ({ local_irq_restore(flags); 0; }); \
 })
 
-/**
- * raw_spin_can_lock - would raw_spin_trylock() succeed?
- * @lock: the spinlock in question.
- */
-#define raw_spin_can_lock(lock)	(!raw_spin_is_locked(lock))
-
 /* Include rwlock functions */
 #include <linux/rwlock.h>
 
@@ -396,11 +390,6 @@ static __always_inline int spin_is_contended(spinlock_t *lock)
 	return raw_spin_is_contended(&lock->rlock);
 }
 
-static __always_inline int spin_can_lock(spinlock_t *lock)
-{
-	return raw_spin_can_lock(&lock->rlock);
-}
-
 #define assert_spin_locked(lock)	assert_raw_spin_locked(&(lock)->rlock)
 
 /*
diff --git a/kernel/locking/spinlock.c b/kernel/locking/spinlock.c
index 42ee9d0a1ea4..8fd48b5552a7 100644
--- a/kernel/locking/spinlock.c
+++ b/kernel/locking/spinlock.c
@@ -66,7 +66,7 @@ void __lockfunc __raw_##op##_lock(locktype##_t *lock)			\
 									\
 		if (!(lock)->break_lock)				\
 			(lock)->break_lock = 1;				\
-		while (!raw_##op##_can_lock(lock) && (lock)->break_lock)\
+		while ((lock)->break_lock)				\
 			arch_##op##_relax(&lock->raw_lock);		\
 	}								\
 	(lock)->break_lock = 0;						\
@@ -86,7 +86,7 @@ unsigned long __lockfunc __raw_##op##_lock_irqsave(locktype##_t *lock)	\
 									\
 		if (!(lock)->break_lock)				\
 			(lock)->break_lock = 1;				\
-		while (!raw_##op##_can_lock(lock) && (lock)->break_lock)\
+		while ((lock)->break_lock)				\
 			arch_##op##_relax(&lock->raw_lock);		\
 	}								\
 	(lock)->break_lock = 0;						\

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-10-03 16:58 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-10-03 14:32 [PATCH 1/2] security/apparmor: Replace homebrew use of write_can_lock with lockdep Will Deacon
2017-10-03 14:32 ` [PATCH 2/2] locking: Remove {read,write}_can_lock Will Deacon
2017-10-03 15:07 ` [PATCH 1/2] security/apparmor: Replace homebrew use of write_can_lock with lockdep Peter Zijlstra
2017-10-03 16:58   ` Will Deacon
2017-10-03 15:33 ` John Johansen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox