Skip to content

Commit 79e9023

Browse files
jlelliIngo Molnar
authored andcommitted
Documentation/locking/mutex-design: Update to reflect latest changes
Commit 3ca0ff5 ("locking/mutex: Rework mutex::owner") reworked the basic mutex implementation to deal with several problems. Documentation was however left unchanged and became stale. Update mutex-design.txt to reflect changes introduced by the above commit. Signed-off-by: Juri Lelli <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Davidlohr Bueso <[email protected]> Cc: Jonathan Corbet <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Paul E. McKenney <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: [email protected] Link: http://lkml.kernel.org/r/[email protected] [ Small readability tweaks to the text. ] Signed-off-by: Ingo Molnar <[email protected]>
1 parent f1517df commit 79e9023

File tree

1 file changed

+17
-32
lines changed

1 file changed

+17
-32
lines changed

Documentation/locking/mutex-design.txt

Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -21,37 +21,23 @@ Implementation
2121
--------------
2222

2323
Mutexes are represented by 'struct mutex', defined in include/linux/mutex.h
24-
and implemented in kernel/locking/mutex.c. These locks use a three
25-
state atomic counter (->count) to represent the different possible
26-
transitions that can occur during the lifetime of a lock:
27-
28-
1: unlocked
29-
0: locked, no waiters
30-
negative: locked, with potential waiters
31-
32-
In its most basic form it also includes a wait-queue and a spinlock
33-
that serializes access to it. CONFIG_SMP systems can also include
34-
a pointer to the lock task owner (->owner) as well as a spinner MCS
35-
lock (->osq), both described below in (ii).
24+
and implemented in kernel/locking/mutex.c. These locks use an atomic variable
25+
(->owner) to keep track of the lock state during its lifetime. Field owner
26+
actually contains 'struct task_struct *' to the current lock owner and it is
27+
therefore NULL if not currently owned. Since task_struct pointers are aligned
28+
at at least L1_CACHE_BYTES, low bits (3) are used to store extra state (e.g.,
29+
if waiter list is non-empty). In its most basic form it also includes a
30+
wait-queue and a spinlock that serializes access to it. Furthermore,
31+
CONFIG_MUTEX_SPIN_ON_OWNER=y systems use a spinner MCS lock (->osq), described
32+
below in (ii).
3633

3734
When acquiring a mutex, there are three possible paths that can be
3835
taken, depending on the state of the lock:
3936

40-
(i) fastpath: tries to atomically acquire the lock by decrementing the
41-
counter. If it was already taken by another task it goes to the next
42-
possible path. This logic is architecture specific. On x86-64, the
43-
locking fastpath is 2 instructions:
44-
45-
0000000000000e10 <mutex_lock>:
46-
e21: f0 ff 0b lock decl (%rbx)
47-
e24: 79 08 jns e2e <mutex_lock+0x1e>
48-
49-
the unlocking fastpath is equally tight:
50-
51-
0000000000000bc0 <mutex_unlock>:
52-
bc8: f0 ff 07 lock incl (%rdi)
53-
bcb: 7f 0a jg bd7 <mutex_unlock+0x17>
54-
37+
(i) fastpath: tries to atomically acquire the lock by cmpxchg()ing the owner with
38+
the current task. This only works in the uncontended case (cmpxchg() checks
39+
against 0UL, so all 3 state bits above have to be 0). If the lock is
40+
contended it goes to the next possible path.
5541

5642
(ii) midpath: aka optimistic spinning, tries to spin for acquisition
5743
while the lock owner is running and there are no other tasks ready
@@ -143,11 +129,10 @@ Test if the mutex is taken:
143129
Disadvantages
144130
-------------
145131

146-
Unlike its original design and purpose, 'struct mutex' is larger than
147-
most locks in the kernel. E.g: on x86-64 it is 40 bytes, almost twice
148-
as large as 'struct semaphore' (24 bytes) and tied, along with rwsems,
149-
for the largest lock in the kernel. Larger structure sizes mean more
150-
CPU cache and memory footprint.
132+
Unlike its original design and purpose, 'struct mutex' is among the largest
133+
locks in the kernel. E.g: on x86-64 it is 32 bytes, where 'struct semaphore'
134+
is 24 bytes and rw_semaphore is 40 bytes. Larger structure sizes mean more CPU
135+
cache and memory footprint.
151136

152137
When to use mutexes
153138
-------------------

0 commit comments

Comments
 (0)