Re: [PATCH-tip v2 02/12] locking/rwsem: Implement lock handoff to prevent lock starvation

From: Peter Zijlstra
Date: Thu Apr 11 2019 - 03:16:42 EST


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.