On 5/3/19 9:10 AM, Peter Zijlstra wrote:
> 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;

Will the apply the changes in the next version.

Thanks,
Longman

Reply via email to