On Wed, Apr 10, 2019 at 10:25:16PM -0400, Waiman Long wrote:
> On 04/10/2019 02:44 PM, Peter Zijlstra wrote:

> > However there is another site that fiddles with the HANDOFF bit, namely
> > __rwsem_down_write_failed_common(), and that does:
> >
> > +                               atomic_long_or(RWSEM_FLAG_HANDOFF, 
> > &sem->count);
> >
> > _OUTSIDE_ of ->wait_lock, which would yield:
> >
> >   CPU0                                      CPU1
> >
> >   oldcount = atomic_long_fetch_add(adjustment, &sem->count)
> >
> >                                     atomic_long_or(HANDOFF)
> >
> >   if (!(oldcount & HANDOFF))
> >     adjustment -= HANDOFF;
> >
> >   atomic_long_sub(adjustment)
> >
> > *whoops*, incremented HANDOFF on HANDOFF.
> >
> >
> > And there's not a comment in sight that would elucidate if this is
> > possible or not.
> >
> 
> A writer can only set the handoff bit if it is the first waiter in the
> queue. If it is the first waiter, a racing __rwsem_mark_wake() will see
> that the first waiter is a writer and so won't go into the reader path.
> I know I something don't spell out all the conditions that may look
> obvious to me but not to others. I will elaborate more in comments.

Aah, indeed.


Reply via email to