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.