]> git.baikalelectronics.ru Git - kernel.git/commitdiff
locking/rwlocks: Add contention detection for rwlocks
authorBen Gardon <bgardon@google.com>
Tue, 2 Feb 2021 18:57:12 +0000 (10:57 -0800)
committerPaolo Bonzini <pbonzini@redhat.com>
Thu, 4 Feb 2021 10:27:42 +0000 (05:27 -0500)
rwlocks do not currently have any facility to detect contention
like spinlocks do. In order to allow users of rwlocks to better manage
latency, add contention detection for queued rwlocks.

CC: Ingo Molnar <mingo@redhat.com>
CC: Will Deacon <will@kernel.org>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Acked-by: Davidlohr Bueso <dbueso@suse.de>
Acked-by: Waiman Long <longman@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Ben Gardon <bgardon@google.com>
Message-Id: <20210202185734.1680553-7-bgardon@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
include/asm-generic/qrwlock.h
include/linux/rwlock.h

index 84ce841ce735545c064a0aa34880760a8c89c3e3..0020d3b820a7b60fe7c0515804126f50892ecc03 100644 (file)
@@ -14,6 +14,7 @@
 #include <asm/processor.h>
 
 #include <asm-generic/qrwlock_types.h>
+#include <asm-generic/qspinlock.h>
 
 /*
  * Writer states & reader shift and bias.
@@ -116,15 +117,26 @@ static inline void queued_write_unlock(struct qrwlock *lock)
        smp_store_release(&lock->wlocked, 0);
 }
 
+/**
+ * queued_rwlock_is_contended - check if the lock is contended
+ * @lock : Pointer to queue rwlock structure
+ * Return: 1 if lock contended, 0 otherwise
+ */
+static inline int queued_rwlock_is_contended(struct qrwlock *lock)
+{
+       return arch_spin_is_locked(&lock->wait_lock);
+}
+
 /*
  * Remapping rwlock architecture specific functions to the corresponding
  * queue rwlock functions.
  */
-#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)
-#define arch_write_trylock(l)  queued_write_trylock(l)
-#define arch_read_unlock(l)    queued_read_unlock(l)
-#define arch_write_unlock(l)   queued_write_unlock(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)
+#define arch_write_trylock(l)          queued_write_trylock(l)
+#define arch_read_unlock(l)            queued_read_unlock(l)
+#define arch_write_unlock(l)           queued_write_unlock(l)
+#define arch_rwlock_is_contended(l)    queued_rwlock_is_contended(l)
 
 #endif /* __ASM_GENERIC_QRWLOCK_H */
index 3dcd617e65ae902316399b0717f0dc0e834b355c..7ce9a51ae5c046dbb536fbf36d1b50f9685eab67 100644 (file)
@@ -128,4 +128,11 @@ do {                                                               \
        1 : ({ local_irq_restore(flags); 0; }); \
 })
 
+#ifdef arch_rwlock_is_contended
+#define rwlock_is_contended(lock) \
+        arch_rwlock_is_contended(&(lock)->raw_lock)
+#else
+#define rwlock_is_contended(lock)      ((void)(lock), 0)
+#endif /* arch_rwlock_is_contended */
+
 #endif /* __LINUX_RWLOCK_H */