diff options
| author | Will Deacon <[email protected]> | 2017-10-12 12:20:51 +0000 |
|---|---|---|
| committer | Ingo Molnar <[email protected]> | 2017-10-25 08:57:25 +0000 |
| commit | d133166146333e1f13fc81c0e6c43c8d99290a8a (patch) | |
| tree | 538bbeeec8c861d98478704af79ee42dfbb95dea /lib/dynamic_queue_limits.c | |
| parent | locking/qrwlock, arm64: Move rwlock implementation over to qrwlocks (diff) | |
| download | kernel-d133166146333e1f13fc81c0e6c43c8d99290a8a.tar.gz kernel-d133166146333e1f13fc81c0e6c43c8d99290a8a.zip | |
locking/qrwlock: Prevent slowpath writers getting held up by fastpath
When a prospective writer takes the qrwlock locking slowpath due to the
lock being held, it attempts to cmpxchg the wmode field from 0 to
_QW_WAITING so that concurrent lockers also take the slowpath and queue
on the spinlock accordingly, allowing the lockers to drain.
Unfortunately, this isn't fair, because a fastpath writer that comes in
after the lock is made available but before the _QW_WAITING flag is set
can effectively jump the queue. If there is a steady stream of prospective
writers, then the waiter will be held off indefinitely.
This patch restores fairness by separating _QW_WAITING and _QW_LOCKED
into two distinct fields: _QW_LOCKED continues to occupy the bottom byte
of the lockword so that it can be cleared unconditionally when unlocking,
but _QW_WAITING now occupies what used to be the bottom bit of the reader
count. This then forces the slow-path for concurrent lockers.
Tested-by: Waiman Long <[email protected]>
Tested-by: Jeremy Linton <[email protected]>
Tested-by: Adam Wallis <[email protected]>
Tested-by: Jan Glauber <[email protected]>
Signed-off-by: Will Deacon <[email protected]>
Acked-by: Peter Zijlstra <[email protected]>
Cc: Boqun Feng <[email protected]>
Cc: [email protected]
Cc: Linus Torvalds <[email protected]>
Cc: Paul E. McKenney <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
Diffstat (limited to 'lib/dynamic_queue_limits.c')
0 files changed, 0 insertions, 0 deletions
