From: will.deacon@arm.com (Will Deacon)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 5/6] kernel/locking: Prevent slowpath writers getting held up by fastpath
Date: Thu, 5 Oct 2017 15:42:57 +0100 [thread overview]
Message-ID: <20171005144256.GF11088@arm.com> (raw)
In-Reply-To: <20171005135618.yufhaklq5cefaiyn@hirez.programming.kicks-ass.net>
HI Peter,
Thanks for having a look.
On Thu, Oct 05, 2017 at 03:56:18PM +0200, Peter Zijlstra wrote:
> On Thu, Oct 05, 2017 at 01:54:56PM +0100, Will Deacon wrote:
> > When a prospective writer takes the qrwlock locking slowpath due to the
> > lock being held, it attempts to cmpxchg the wmode field from 0 to
> > _QW_WAITING so that concurrent lockers also take the slowpath and queue
> > on the spinlock accordingly, allowing the lockers to drain.
> >
> > Unfortunately, this isn't fair, because a fastpath writer that comes in
> > after the lock is made available but before the _QW_WAITING flag is set
> > can effectively jump the queue. If there is a steady stream of prospective
> > writers, then the waiter will be held off indefinitely.
> >
> > This patch restores fairness by separating _QW_WAITING and _QW_LOCKED
> > into two bits in the wmode byte and having the waiter set _QW_WAITING
> > unconditionally. This then forces the slow-path for concurrent lockers,
> > but requires that a writer unlock operation performs an
> > atomic_sub_release instead of a store_release so that the waiting status
> > is preserved.
>
> > diff --git a/include/asm-generic/qrwlock.h b/include/asm-generic/qrwlock.h
> > index 02c0a768e6b0..8b7edef500e5 100644
> > --- a/include/asm-generic/qrwlock.h
> > +++ b/include/asm-generic/qrwlock.h
> > @@ -41,7 +41,7 @@
> > * +----+----+----+----+
> > */
> > #define _QW_WAITING 1 /* A writer is waiting */
> > -#define _QW_LOCKED 0xff /* A writer holds the lock */
> > +#define _QW_LOCKED 2 /* A writer holds the lock */
> > #define _QW_WMASK 0xff /* Writer mask */
> > #define _QR_SHIFT 8 /* Reader count shift */
> > #define _QR_BIAS (1U << _QR_SHIFT)
> > @@ -134,7 +134,7 @@ static inline void queued_read_unlock(struct qrwlock *lock)
> > */
> > static inline void queued_write_unlock(struct qrwlock *lock)
> > {
> > - smp_store_release(&lock->wmode, 0);
> > + (void)atomic_sub_return_release(_QW_LOCKED, &lock->cnts);
> > }
>
> That is a fairly painful hit on x86. Changes a regular store into an
> "LOCK XADD" +20 cycles right there.
Yeah, I mentioned that in the cover letter which is also why it's at the end
of the series ;) However, it's worth noting that this is the same as the
reader unlock path and, as it stands, there's a real risk of writer
starvation with the current code which isn't great for a queued lock.
> Can't we steal one of the reader bits for waiting?
I considered this at LPC and somehow convinced myself it didn't work, but
actually all it's really doing is making the _QW_LOCKED bit a byte, so it
should work fine.
I'll work that into v2.
Will
WARNING: multiple messages have this Message-ID (diff)
From: Will Deacon <will.deacon@arm.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Jeremy.Linton@arm.com,
mingo@redhat.com, longman@redhat.com, boqun.feng@gmail.com,
paulmck@linux.vnet.ibm.com
Subject: Re: [PATCH 5/6] kernel/locking: Prevent slowpath writers getting held up by fastpath
Date: Thu, 5 Oct 2017 15:42:57 +0100 [thread overview]
Message-ID: <20171005144256.GF11088@arm.com> (raw)
In-Reply-To: <20171005135618.yufhaklq5cefaiyn@hirez.programming.kicks-ass.net>
HI Peter,
Thanks for having a look.
On Thu, Oct 05, 2017 at 03:56:18PM +0200, Peter Zijlstra wrote:
> On Thu, Oct 05, 2017 at 01:54:56PM +0100, Will Deacon wrote:
> > When a prospective writer takes the qrwlock locking slowpath due to the
> > lock being held, it attempts to cmpxchg the wmode field from 0 to
> > _QW_WAITING so that concurrent lockers also take the slowpath and queue
> > on the spinlock accordingly, allowing the lockers to drain.
> >
> > Unfortunately, this isn't fair, because a fastpath writer that comes in
> > after the lock is made available but before the _QW_WAITING flag is set
> > can effectively jump the queue. If there is a steady stream of prospective
> > writers, then the waiter will be held off indefinitely.
> >
> > This patch restores fairness by separating _QW_WAITING and _QW_LOCKED
> > into two bits in the wmode byte and having the waiter set _QW_WAITING
> > unconditionally. This then forces the slow-path for concurrent lockers,
> > but requires that a writer unlock operation performs an
> > atomic_sub_release instead of a store_release so that the waiting status
> > is preserved.
>
> > diff --git a/include/asm-generic/qrwlock.h b/include/asm-generic/qrwlock.h
> > index 02c0a768e6b0..8b7edef500e5 100644
> > --- a/include/asm-generic/qrwlock.h
> > +++ b/include/asm-generic/qrwlock.h
> > @@ -41,7 +41,7 @@
> > * +----+----+----+----+
> > */
> > #define _QW_WAITING 1 /* A writer is waiting */
> > -#define _QW_LOCKED 0xff /* A writer holds the lock */
> > +#define _QW_LOCKED 2 /* A writer holds the lock */
> > #define _QW_WMASK 0xff /* Writer mask */
> > #define _QR_SHIFT 8 /* Reader count shift */
> > #define _QR_BIAS (1U << _QR_SHIFT)
> > @@ -134,7 +134,7 @@ static inline void queued_read_unlock(struct qrwlock *lock)
> > */
> > static inline void queued_write_unlock(struct qrwlock *lock)
> > {
> > - smp_store_release(&lock->wmode, 0);
> > + (void)atomic_sub_return_release(_QW_LOCKED, &lock->cnts);
> > }
>
> That is a fairly painful hit on x86. Changes a regular store into an
> "LOCK XADD" +20 cycles right there.
Yeah, I mentioned that in the cover letter which is also why it's at the end
of the series ;) However, it's worth noting that this is the same as the
reader unlock path and, as it stands, there's a real risk of writer
starvation with the current code which isn't great for a queued lock.
> Can't we steal one of the reader bits for waiting?
I considered this at LPC and somehow convinced myself it didn't work, but
actually all it's really doing is making the _QW_LOCKED bit a byte, so it
should work fine.
I'll work that into v2.
Will
next prev parent reply other threads:[~2017-10-05 14:42 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-05 12:54 [PATCH 0/6] Switch arm64 over to qrwlock Will Deacon
2017-10-05 12:54 ` Will Deacon
2017-10-05 12:54 ` [PATCH 1/6] kernel/locking: Use struct qrwlock instead of struct __qrwlock Will Deacon
2017-10-05 12:54 ` Will Deacon
2017-10-05 12:54 ` [PATCH 2/6] locking/atomic: Add atomic_cond_read_acquire Will Deacon
2017-10-05 12:54 ` Will Deacon
2017-10-05 12:54 ` [PATCH 3/6] kernel/locking: Use atomic_cond_read_acquire when spinning in qrwlock Will Deacon
2017-10-05 12:54 ` Will Deacon
2017-10-05 12:54 ` [PATCH 4/6] arm64: locking: Move rwlock implementation over to qrwlocks Will Deacon
2017-10-05 12:54 ` Will Deacon
2017-10-05 12:54 ` [PATCH 5/6] kernel/locking: Prevent slowpath writers getting held up by fastpath Will Deacon
2017-10-05 12:54 ` Will Deacon
2017-10-05 13:56 ` Peter Zijlstra
2017-10-05 13:56 ` Peter Zijlstra
2017-10-05 14:37 ` Waiman Long
2017-10-05 14:37 ` Waiman Long
2017-10-05 14:42 ` Will Deacon [this message]
2017-10-05 14:42 ` Will Deacon
2017-10-05 12:54 ` [PATCH 6/6] kernel/locking: Remove unused union members from struct qrwlock Will Deacon
2017-10-05 12:54 ` Will Deacon
2017-10-05 22:12 ` [PATCH 0/6] Switch arm64 over to qrwlock Jeremy Linton
2017-10-05 22:12 ` Jeremy Linton
2017-10-06 8:39 ` Will Deacon
2017-10-06 8:39 ` Will Deacon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20171005144256.GF11088@arm.com \
--to=will.deacon@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.