On Mon, May 20, 2019 at 04:59:13PM -0400, Waiman Long wrote: > +static inline void rwsem_set_nonspinnable(struct rw_semaphore *sem) > +{ > + long owner = atomic_long_read(&sem->owner); > + > + while (owner & RWSEM_READER_OWNED) { > + if (owner & RWSEM_NONSPINNABLE) > + break; > + owner = atomic_long_cmpxchg(&sem->owner, owner, > + owner | RWSEM_NONSPINNABLE); > + } > +}
--- a/kernel/locking/rwsem.c +++ b/kernel/locking/rwsem.c @@ -206,12 +206,13 @@ static inline void rwsem_set_nonspinnabl { long owner = atomic_long_read(&sem->owner); - while (owner & RWSEM_READER_OWNED) { + do { + if (!(owner & RWSEM_READER_OWNED)) + break; if (owner & RWSEM_NONSPINNABLE) break; - owner = atomic_long_cmpxchg(&sem->owner, owner, - owner | RWSEM_NONSPINNABLE); - } + } while (!atomic_long_try_cmpxchg(&sem->owner, &owner, + owner | RWSEM_NONSPINNABLE)); } /*