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

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
Loading
Loading
Loading
Loading
+18 −6
Original line number Diff line number Diff line
@@ -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,6 +117,16 @@ 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.
@@ -126,5 +137,6 @@ static inline void queued_write_unlock(struct qrwlock *lock)
#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 */
+7 −0
Original line number Diff line number Diff line
@@ -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 */