Messages in this thread | | | Date | Thu, 13 Oct 2022 12:02:09 +0200 | From | Peter Zijlstra <> | Subject | Re: [PATCH v2 1/2] locking/rwsem: Prevent non-first waiter from spinning in down_write() slowpath |
| |
On Wed, Oct 12, 2022 at 09:33:32AM -0400, Waiman Long wrote: > A non-first waiter can potentially spin in the for loop of > rwsem_down_write_slowpath() without sleeping but fail to acquire the > lock even if the rwsem is free if the following sequence happens: > > Non-first waiter First waiter Lock holder > ---------------- ------------ ----------- > Acquire wait_lock > rwsem_try_write_lock(): > Set handoff bit if RT or > wait too long > Set waiter->handoff_set > Release wait_lock > Acquire wait_lock > Inherit waiter->handoff_set > Release wait_lock > Clear owner > Release lock > if (waiter.handoff_set) { > rwsem_spin_on_owner((); > if (OWNER_NULL) > goto trylock_again; > } > trylock_again: > Acquire wait_lock > rwsem_try_write_lock(): > if (first->handoff_set && (waiter != first)) > return false; > Release wait_lock > > It is especially problematic if the non-first waiter is an RT task and > it is running on the same CPU as the first waiter as this can lead to > live lock. >
So why not do a better handoff? Specifically, have the owner set owner to first-waiter instead of NULL ? (like the normal mutex code)
| |