Messages in this thread | | | Date | Thu, 13 Oct 2022 09:33:17 -0400 | Subject | Re: [PATCH v2 1/2] locking/rwsem: Prevent non-first waiter from spinning in down_write() slowpath | From | Waiman Long <> |
| |
On 10/13/22 06:02, Peter Zijlstra wrote: > 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)
I understand your desire to make the rwsem handoff process more like what mutex is currently doing. I certainly think it is doable and will put this in my todo list. However, that needs to be done at unlock and wakeup time. I expect that will require moderate amount of code changes which will make it not that suitable for backporting to the stable releases.
I would like to see these simple fixes get merged first and then we can work on a major revamp of the handoff code. What do you think?
Cheers, Longman
| |