Messages in this thread | | | Subject | Re: [PATCH v2 06/28] locking/rwlocks: Add contention detection for rwlocks | From | Waiman Long <> | Date | Tue, 9 Feb 2021 22:32:28 -0500 |
| |
On 2/2/21 1:57 PM, Ben Gardon wrote: > 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> > --- > include/asm-generic/qrwlock.h | 24 ++++++++++++++++++------ > include/linux/rwlock.h | 7 +++++++ > 2 files changed, 25 insertions(+), 6 deletions(-) > > diff --git a/include/asm-generic/qrwlock.h b/include/asm-generic/qrwlock.h > index 84ce841ce735..0020d3b820a7 100644 > --- a/include/asm-generic/qrwlock.h > +++ b/include/asm-generic/qrwlock.h > @@ -14,6 +14,7 @@ > #include <asm/processor.h> > > #include <asm-generic/qrwlock_types.h> > +#include <asm-generic/qspinlock.h>
As said in another thread, qspinlock and qrwlock can be independently enabled for an architecture. So we shouldn't include qspinlock.h here. Instead, just include the regular linux/spinlock.h file to make sure that arch_spin_is_locked() is available.
> > /* > * 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 */ > diff --git a/include/linux/rwlock.h b/include/linux/rwlock.h > index 3dcd617e65ae..7ce9a51ae5c0 100644 > --- a/include/linux/rwlock.h > +++ b/include/linux/rwlock.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 */
Cheers, Longman
| |