Re: [PATCH v4 07/16] locking/rwsem: Implement lock handoff to prevent lock starvation

From: Peter Zijlstra
Date: Tue Apr 16 2019 - 12:15:35 EST


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.