summaryrefslogtreecommitdiffstats
path: root/Documentation/locking
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2018-06-15 04:17:38 -0400
committerThomas Hellstrom <thellstrom@vmware.com>2018-07-03 03:44:36 -0400
commit08295b3b5beec9aac0f7a9db86f0fc3792039da3 (patch)
tree6226474d5fdaba0bf04aa8bf6542a89722547990 /Documentation/locking
parent55f036ca7e74b85e34958af3d22121c656796413 (diff)
locking: Implement an algorithm choice for Wound-Wait mutexes
The current Wound-Wait mutex algorithm is actually not Wound-Wait but Wait-Die. Implement also Wound-Wait as a per-ww-class choice. Wound-Wait is, contrary to Wait-Die a preemptive algorithm and is known to generate fewer backoffs. Testing reveals that this is true if the number of simultaneous contending transactions is small. As the number of simultaneous contending threads increases, Wait-Wound becomes inferior to Wait-Die in terms of elapsed time. Possibly due to the larger number of held locks of sleeping transactions. Update documentation and callers. Timings using git://people.freedesktop.org/~thomash/ww_mutex_test tag patch-18-06-15 Each thread runs 100000 batches of lock / unlock 800 ww mutexes randomly chosen out of 100000. Four core Intel x86_64: Algorithm #threads Rollbacks time Wound-Wait 4 ~100 ~17s. Wait-Die 4 ~150000 ~19s. Wound-Wait 16 ~360000 ~109s. Wait-Die 16 ~450000 ~82s. Cc: Ingo Molnar <mingo@redhat.com> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Gustavo Padovan <gustavo@padovan.org> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Sean Paul <seanpaul@chromium.org> Cc: David Airlie <airlied@linux.ie> Cc: Davidlohr Bueso <dave@stgolabs.net> Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> Cc: Josh Triplett <josh@joshtriplett.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Kate Stewart <kstewart@linuxfoundation.org> Cc: Philippe Ombredanne <pombredanne@nexb.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: linux-doc@vger.kernel.org Cc: linux-media@vger.kernel.org Cc: linaro-mm-sig@lists.linaro.org Co-authored-by: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'Documentation/locking')
-rw-r--r--Documentation/locking/ww-mutex-design.txt57
1 files changed, 46 insertions, 11 deletions
diff --git a/Documentation/locking/ww-mutex-design.txt b/Documentation/locking/ww-mutex-design.txt
index 2fd7f2a2af21..f0ed7c30e695 100644
--- a/Documentation/locking/ww-mutex-design.txt
+++ b/Documentation/locking/ww-mutex-design.txt
@@ -1,4 +1,4 @@
1Wait/Wound Deadlock-Proof Mutex Design 1Wound/Wait Deadlock-Proof Mutex Design
2====================================== 2======================================
3 3
4Please read mutex-design.txt first, as it applies to wait/wound mutexes too. 4Please read mutex-design.txt first, as it applies to wait/wound mutexes too.
@@ -32,10 +32,26 @@ the oldest task) wins, and the one with the higher reservation id (i.e. the
32younger task) unlocks all of the buffers that it has already locked, and then 32younger task) unlocks all of the buffers that it has already locked, and then
33tries again. 33tries again.
34 34
35In the RDBMS literature this deadlock handling approach is called wait/die: 35In the RDBMS literature, a reservation ticket is associated with a transaction.
36The older tasks waits until it can acquire the contended lock. The younger tasks 36and the deadlock handling approach is called Wait-Die. The name is based on
37needs to back off and drop all the locks it is currently holding, i.e. the 37the actions of a locking thread when it encounters an already locked mutex.
38younger task dies. 38If the transaction holding the lock is younger, the locking transaction waits.
39If the transaction holding the lock is older, the locking transaction backs off
40and dies. Hence Wait-Die.
41There is also another algorithm called Wound-Wait:
42If the transaction holding the lock is younger, the locking transaction
43wounds the transaction holding the lock, requesting it to die.
44If the transaction holding the lock is older, it waits for the other
45transaction. Hence Wound-Wait.
46The two algorithms are both fair in that a transaction will eventually succeed.
47However, the Wound-Wait algorithm is typically stated to generate fewer backoffs
48compared to Wait-Die, but is, on the other hand, associated with more work than
49Wait-Die when recovering from a backoff. Wound-Wait is also a preemptive
50algorithm in that transactions are wounded by other transactions, and that
51requires a reliable way to pick up up the wounded condition and preempt the
52running transaction. Note that this is not the same as process preemption. A
53Wound-Wait transaction is considered preempted when it dies (returning
54-EDEADLK) following a wound.
39 55
40Concepts 56Concepts
41-------- 57--------
@@ -47,10 +63,12 @@ Acquire context: To ensure eventual forward progress it is important the a task
47trying to acquire locks doesn't grab a new reservation id, but keeps the one it 63trying to acquire locks doesn't grab a new reservation id, but keeps the one it
48acquired when starting the lock acquisition. This ticket is stored in the 64acquired when starting the lock acquisition. This ticket is stored in the
49acquire context. Furthermore the acquire context keeps track of debugging state 65acquire context. Furthermore the acquire context keeps track of debugging state
50to catch w/w mutex interface abuse. 66to catch w/w mutex interface abuse. An acquire context is representing a
67transaction.
51 68
52W/w class: In contrast to normal mutexes the lock class needs to be explicit for 69W/w class: In contrast to normal mutexes the lock class needs to be explicit for
53w/w mutexes, since it is required to initialize the acquire context. 70w/w mutexes, since it is required to initialize the acquire context. The lock
71class also specifies what algorithm to use, Wound-Wait or Wait-Die.
54 72
55Furthermore there are three different class of w/w lock acquire functions: 73Furthermore there are three different class of w/w lock acquire functions:
56 74
@@ -90,6 +108,12 @@ provided.
90Usage 108Usage
91----- 109-----
92 110
111The algorithm (Wait-Die vs Wound-Wait) is chosen by using either
112DEFINE_WW_CLASS() (Wound-Wait) or DEFINE_WD_CLASS() (Wait-Die)
113As a rough rule of thumb, use Wound-Wait iff you
114expect the number of simultaneous competing transactions to be typically small,
115and you want to reduce the number of rollbacks.
116
93Three different ways to acquire locks within the same w/w class. Common 117Three different ways to acquire locks within the same w/w class. Common
94definitions for methods #1 and #2: 118definitions for methods #1 and #2:
95 119
@@ -312,12 +336,23 @@ Design:
312 We maintain the following invariants for the wait list: 336 We maintain the following invariants for the wait list:
313 (1) Waiters with an acquire context are sorted by stamp order; waiters 337 (1) Waiters with an acquire context are sorted by stamp order; waiters
314 without an acquire context are interspersed in FIFO order. 338 without an acquire context are interspersed in FIFO order.
315 (2) Among waiters with contexts, only the first one can have other locks 339 (2) For Wait-Die, among waiters with contexts, only the first one can have
316 acquired already (ctx->acquired > 0). Note that this waiter may come 340 other locks acquired already (ctx->acquired > 0). Note that this waiter
317 after other waiters without contexts in the list. 341 may come after other waiters without contexts in the list.
342
343 The Wound-Wait preemption is implemented with a lazy-preemption scheme:
344 The wounded status of the transaction is checked only when there is
345 contention for a new lock and hence a true chance of deadlock. In that
346 situation, if the transaction is wounded, it backs off, clears the
347 wounded status and retries. A great benefit of implementing preemption in
348 this way is that the wounded transaction can identify a contending lock to
349 wait for before restarting the transaction. Just blindly restarting the
350 transaction would likely make the transaction end up in a situation where
351 it would have to back off again.
318 352
319 In general, not much contention is expected. The locks are typically used to 353 In general, not much contention is expected. The locks are typically used to
320 serialize access to resources for devices. 354 serialize access to resources for devices, and optimization focus should
355 therefore be directed towards the uncontended cases.
321 356
322Lockdep: 357Lockdep:
323 Special care has been taken to warn for as many cases of api abuse 358 Special care has been taken to warn for as many cases of api abuse