From: Peter Zijlstra <peterz@infradead.org>
To: Will Deacon <will@kernel.org>
Cc: Jan Stancek <jstancek@redhat.com>,
Waiman Long <longman@redhat.com>,
linux-kernel@vger.kernel.org, dbueso@suse.de, mingo@redhat.com,
jade.alglave@arm.com, paulmck@linux.vnet.ibm.com
Subject: Re: [PATCH v2] locking/rwsem: add acquire barrier to read_slowpath exit when queue is empty
Date: Thu, 18 Jul 2019 14:23:13 +0200 [thread overview]
Message-ID: <20190718122313.GO3402@hirez.programming.kicks-ass.net> (raw)
In-Reply-To: <20190718114547.v4c7ucsp6k4i6o3b@willie-the-truck>
On Thu, Jul 18, 2019 at 12:45:47PM +0100, Will Deacon wrote:
> On Thu, Jul 18, 2019 at 12:58:12PM +0200, Peter Zijlstra wrote:
> > On Thu, Jul 18, 2019 at 10:26:41AM +0100, Will Deacon wrote:
> >
> > > /*
> > > * We need to ensure ACQUIRE semantics when reading sem->count so that
> > > * we pair with the RELEASE store performed by an unlocking/downgrading
> > > * writer.
> > > *
> > > * P0 (writer) P1 (reader)
> > > *
> > > * down_write(sem);
> > > * <write shared data>
> > > * downgrade_write(sem);
> > > * -> fetch_add_release(&sem->count)
> > > *
> > > * down_read_slowpath(sem);
> > > * -> atomic_read(&sem->count)
> > > * <ctrl dep>
> > > * smp_acquire__after_ctrl_dep()
> > > * <read shared data>
> > > */
> >
> > So I'm thinking all this is excessive; the simple rule is: lock acquire
> > should imply ACQUIRE, we all know why.
>
> Fair enough, I just thought this was worth highlighting because you can't
> reply on the wait_lock to give you ACQUIRE ordering.
Right, not in this case, because sem->count is not fully serialized by
it, whereas below the wait-queue is.
> > ---
> > diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c
> > index 37524a47f002..9eb630904a17 100644
> > --- a/kernel/locking/rwsem.c
> > +++ b/kernel/locking/rwsem.c
> > @@ -1000,6 +1000,7 @@ rwsem_down_read_slowpath(struct rw_semaphore *sem, int state)
> > atomic_long_add(-RWSEM_READER_BIAS, &sem->count);
> > adjustment = 0;
> > if (rwsem_optimistic_spin(sem, false)) {
> > + /* rwsem_optimistic_spin() implies ACQUIRE through rwsem_*trylock() */
>
> I couldn't figure out if this was dependent on the return value or not,
I went with the fact that the only way to return true is if taken
becomes true; and that only happens through
rwsem_try_{read,write}_lock_unqueued(), and both imply ACQUIRE on
success.
> and looking at osq_lock() I also couldn't see the ACQUIRE barrier when we're
> spinning on node->locked. Hmm.
Yes, osq is not a full lock and does not imply these barriers. This came
up somewhere, did we forget to write a comment on that? Lemme go look.
> > /*
> > * Wake up other readers in the wait list if the front
> > * waiter is a reader.
> > @@ -1014,6 +1015,7 @@ rwsem_down_read_slowpath(struct rw_semaphore *sem, int state)
> > }
> > return sem;
> > } else if (rwsem_reader_phase_trylock(sem, waiter.last_rowner)) {
> > + /* rwsem_reader_phase_trylock() implies ACQUIRE */
>
> Can we add "on success" to the end of this, please?
Good point.
> > return sem;
> > }
> >
> > @@ -1032,6 +1034,8 @@ rwsem_down_read_slowpath(struct rw_semaphore *sem, int state)
> > */
> > if (adjustment && !(atomic_long_read(&sem->count) &
> > (RWSEM_WRITER_MASK | RWSEM_FLAG_HANDOFF))) {
> > + /* Provide lock ACQUIRE */
> > + smp_acquire__after_ctrl_dep();
> > raw_spin_unlock_irq(&sem->wait_lock);
> > rwsem_set_reader_owned(sem);
> > lockevent_inc(rwsem_rlock_fast);
> > @@ -1065,15 +1069,25 @@ rwsem_down_read_slowpath(struct rw_semaphore *sem, int state)
> > wake_up_q(&wake_q);
> >
> > /* wait to be given the lock */
> > - while (true) {
> > + for (;;) {
> > set_current_state(state);
> > - if (!waiter.task)
> > + if (!smp_load_acquire(&waiter.task)) {
> > + /*
> > + * Matches rwsem_mark_wake()'s smp_store_release() and ensures
> > + * we're ordered against its sem->count operations.
> > + */
> > break;
> > + }
>
> Ack. Also, grepping for 'waiter.task' reveals a similar usage in
> drivers/tty/tty_ldsem.c if you're feeling brave enough.
*sigh* of course, for every bug there needs to be a second copy
somewhere.
I'll go look there too. Thanks!
next prev parent reply other threads:[~2019-07-18 12:23 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-07-16 16:04 [PATCH] locking/rwsem: use read_acquire in read_slowpath exit when queue is empty Jan Stancek
2019-07-16 16:53 ` Waiman Long
2019-07-16 18:34 ` Jan Stancek
2019-07-16 18:58 ` Peter Zijlstra
2019-07-16 19:09 ` Waiman Long
2019-07-17 12:02 ` [PATCH v2] locking/rwsem: add acquire barrier to " Jan Stancek
2019-07-17 13:13 ` Will Deacon
2019-07-17 14:19 ` Waiman Long
2019-07-17 19:22 ` Jan Stancek
2019-07-17 19:39 ` Waiman Long
2019-07-18 8:51 ` [PATCH v3] " Jan Stancek
2019-07-25 16:00 ` [tip:locking/core] locking/rwsem: Add missing ACQUIRE " tip-bot for Jan Stancek
2019-07-18 9:26 ` [PATCH v2] locking/rwsem: add acquire barrier " Will Deacon
2019-07-18 10:50 ` Jan Stancek
2019-07-18 11:04 ` Peter Zijlstra
2019-07-18 11:09 ` Peter Zijlstra
2019-07-18 11:36 ` Jan Stancek
2019-07-18 12:12 ` Paul E. McKenney
2019-07-18 10:58 ` Peter Zijlstra
2019-07-18 11:45 ` Will Deacon
2019-07-18 12:23 ` Peter Zijlstra [this message]
2019-07-17 15:33 ` Waiman Long
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=20190718122313.GO3402@hirez.programming.kicks-ass.net \
--to=peterz@infradead.org \
--cc=dbueso@suse.de \
--cc=jade.alglave@arm.com \
--cc=jstancek@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=longman@redhat.com \
--cc=mingo@redhat.com \
--cc=paulmck@linux.vnet.ibm.com \
--cc=will@kernel.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.