Messages in this thread Patch in this message | | | Date | Fri, 3 May 2019 15:10:54 +0200 | From | Peter Zijlstra <> | Subject | Re: [PATCH-tip v7 08/20] locking/rwsem: Implement lock handoff to prevent lock starvation |
| |
On Sun, Apr 28, 2019 at 05:25:45PM -0400, Waiman Long wrote: > +static inline bool rwsem_try_write_lock(long count, struct rw_semaphore *sem, > + enum writer_wait_state wstate) > { > long new; > > + lockdep_assert_held(&sem->wait_lock); > + do { > + bool has_handoff = !!(count & RWSEM_FLAG_HANDOFF); > > + if (has_handoff && wstate == WRITER_NOT_FIRST) > + return false; > > + if (count & RWSEM_LOCK_MASK) { > + if (has_handoff || (wstate != WRITER_HANDOFF)) > + return false; > + new = count | RWSEM_FLAG_HANDOFF; > + } else { > + new = (count | RWSEM_WRITER_LOCKED) & > + ~RWSEM_FLAG_HANDOFF; > > + if (list_is_singular(&sem->wait_list)) > + new &= ~RWSEM_FLAG_WAITERS; > + } > + } while (!atomic_long_try_cmpxchg_acquire(&sem->count, &count, new)); > + > + /* > + * We have either acquired the lock with handoff bit cleared or > + * set the handoff bit. > + */ > + if (new & RWSEM_FLAG_HANDOFF) > + return false; > + > + rwsem_set_owner(sem); > + return true; > }
I've changed that like so.
--- a/kernel/locking/rwsem.c +++ b/kernel/locking/rwsem.c @@ -406,19 +406,23 @@ static inline bool rwsem_try_write_lock( long new; lockdep_assert_held(&sem->wait_lock); + do { bool has_handoff = !!(count & RWSEM_FLAG_HANDOFF); if (has_handoff && wstate == WRITER_NOT_FIRST) return false; + new = count; + if (count & RWSEM_LOCK_MASK) { if (has_handoff || (wstate != WRITER_HANDOFF)) return false; - new = count | RWSEM_FLAG_HANDOFF; + + new |= RWSEM_FLAG_HANDOFF; } else { - new = (count | RWSEM_WRITER_LOCKED) & - ~RWSEM_FLAG_HANDOFF; + new |= RWSEM_WRITER_LOCKED; + new &= ~RWSEM_FLAG_HANDOFF; if (list_is_singular(&sem->wait_list)) new &= ~RWSEM_FLAG_WAITERS;
| |