All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: Andrea Parri <parri.andrea@gmail.com>
Cc: Waiman Long <longman@redhat.com>,
	Prateek Sood <prsood@codeaurora.org>,
	mingo@redhat.com, sramana@codeaurora.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] rwsem: fix missed wakeup due to reordering of load
Date: Thu, 10 Aug 2017 12:41:22 +0200	[thread overview]
Message-ID: <20170810104122.mhxpayi7hvjcyuoy@hirez.programming.kicks-ass.net> (raw)
In-Reply-To: <20170810083255.GA3913@andrea>

On Thu, Aug 10, 2017 at 10:32:56AM +0200, Andrea Parri wrote:
> On Thu, Jul 27, 2017 at 11:48:53AM -0400, Waiman Long wrote:
> > On 07/26/2017 04:17 PM, Prateek Sood wrote:
> > > If a spinner is present, there is a chance that the load of
> > > rwsem_has_spinner() in rwsem_wake() can be reordered with
> > > respect to decrement of rwsem count in __up_write() leading
> > > to wakeup being missed.
> > >
> > >  spinning writer                  up_write caller
> > >  ---------------                  -----------------------
> > >  [S] osq_unlock()                 [L] osq
> > >   spin_lock(wait_lock)
> > >   sem->count=0xFFFFFFFF00000001
> > >             +0xFFFFFFFF00000000
> > >   count=sem->count
> > >   MB
> > >                                    sem->count=0xFFFFFFFE00000001
> > >                                              -0xFFFFFFFF00000001
> > >                                    spin_trylock(wait_lock)
> > >                                    return
> > >  rwsem_try_write_lock(count)
> > >  spin_unlock(wait_lock)
> > >  schedule()
> > >
> > > Reordering of atomic_long_sub_return_release() in __up_write()
> > > and rwsem_has_spinner() in rwsem_wake() can cause missing of
> > > wakeup in up_write() context. In spinning writer, sem->count
> > > and local variable count is 0XFFFFFFFE00000001. It would result
> > > in rwsem_try_write_lock() failing to acquire rwsem and spinning
> > > writer going to sleep in rwsem_down_write_failed().
> > >
> > > The smp_rmb() will make sure that the spinner state is
> > > consulted after sem->count is updated in up_write context.
> > >
> > > Signed-off-by: Prateek Sood <prsood@codeaurora.org>
> > 
> > Did you actually observe that the reordering happens?
> > 
> > I am not sure if some architectures can actually speculatively execute
> > instruction ahead of a branch and then ahead into a function call. I
> > know it can happen if the function call is inlined, but rwsem_wake()
> > will not be inlined into __up_read() or __up_write().
> 
> Branches/control dependencies targeting a read do not necessarily preserve
> program order; this is for example the case for PowerPC and ARM.
> 
> I'd not expect more than a compiler barrier from a function call (in fact,
> not even that if the function happens to be inlined).

Indeed. Reads can be speculated by deep out-of-order CPUs no problem.
That's what branch predictors are for.

> > Even if that is the case, I am not sure if smp_rmb() alone is enough to
> > guarantee the ordering as I think it will depend on how the
> > atomic_long_sub_return_release() is implmented.
> 
> AFAICT, the pattern under discussion is MP with:
> 
>   - a store-release to osq->tail(unlock) followed by a store to sem->count,
>     separated by a MB (from atomic_long_add_return()) on CPU0;
> 
>   - a load of sem->count (for atomic_long_sub_return_release()) followed by

Which is a regular load, as 'release' only need apply to the store.

>     a load of osq->tail (rwsem_has_spinner()) on CPU1.
> 
> Thus a RMW between the two loads suffices to forbid the weak behaviour.

Agreed.

  reply	other threads:[~2017-08-10 10:41 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-26 20:17 [PATCH] rwsem: fix missed wakeup due to reordering of load Prateek Sood
2017-07-27 15:48 ` Waiman Long
2017-07-27 16:59   ` Peter Zijlstra
2017-08-10  8:32   ` Andrea Parri
2017-08-10 10:41     ` Peter Zijlstra [this message]
2017-08-10 10:44 ` Peter Zijlstra
2017-08-23 11:28 Prateek Sood
2017-08-24 11:29 ` Peter Zijlstra
2017-08-24 12:33   ` Peter Zijlstra
2017-08-24 12:52     ` Peter Zijlstra
2017-09-07 14:08       ` Prateek Sood
2017-09-07 14:30 Prateek Sood
2017-09-19 14:05 ` Andrea Parri
2017-09-20 14:52 ` Davidlohr Bueso
2017-09-20 21:17   ` Andrea Parri
2017-09-27 21:20     ` Davidlohr Bueso
2017-09-26 18:37 ` Prateek Sood

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=20170810104122.mhxpayi7hvjcyuoy@hirez.programming.kicks-ass.net \
    --to=peterz@infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=longman@redhat.com \
    --cc=mingo@redhat.com \
    --cc=parri.andrea@gmail.com \
    --cc=prsood@codeaurora.org \
    --cc=sramana@codeaurora.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.