Commit 26128cb6 authored by Ben Gardon's avatar Ben Gardon Committed by Paolo Bonzini

locking/rwlocks: Add contention detection for rwlocks

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: default avatarPeter Zijlstra <peterz@infradead.org>
Acked-by: default avatarDavidlohr Bueso <dbueso@suse.de>
Acked-by: default avatarWaiman Long <longman@redhat.com>
Acked-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarBen Gardon <bgardon@google.com>
Message-Id: <20210202185734.1680553-7-bgardon@google.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 7cca2d0b
......@@ -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 */
......@@ -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 */
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