On Tue, Apr 16, 2019 at 05:49:37PM +0200, Peter Zijlstra wrote: > See, if you first write that function in the form: > > long new; > > do { > new = count | RWSEM_WRITER_LOCKED; > > if (count & RWSEM_LOCK_MASK) > return false; > > if (list_is_singular(&sem->wait_list)) > new &= ~RWSEM_FLAG_WAITERS; > > } while (atomic_long_try_cmpxchg_acquire(&sem->count, &count, new)); > > rwsem_set_owner(sem); > return true; > > And then add the HANDOFF bits like: > > long new; > > do { > + bool has_handoff = !!(count & RWSEM_FLAG_HANDOFF); > > + new = (count | RWSEM_WRITER_LOCKED) & ~RWSEM_FLAG_HANDOFF; > > if (count & RWSEM_LOCK_MASK) { > + if (has_handoff && wstate != WRITER_HANDOFF) > + return false; > new |= RWSEM_FLAG_HANDOFF; > } > > + if (has_handoff && wstate == WRITER_NOT_FIRST) > + return false; > > if (list_is_singular(&sem->wait_list)) > new &= ~RWSEM_FLAG_WAITERS; > > } while (atomic_long_try_cmpxchg_acquire(&sem->count, &count, new));
obviously that should be ! > > rwsem_set_owner(sem); > return true; > > it almost looks like sensible code.