Commit 79e90238 authored by Juri Lelli's avatar Juri Lelli Committed by Ingo Molnar
Browse files

Documentation/locking/mutex-design: Update to reflect latest changes



Commit 3ca0ff57 ("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: default avatarJuri Lelli <juri.lelli@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-doc@vger.kernel.org
Link: http://lkml.kernel.org/r/20180209160114.19980-1-juri.lelli@redhat.com


[ Small readability tweaks to the text. ]
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent f1517df8
Loading
Loading
Loading
Loading
+17 −32
Original line number Original line Diff line number Diff line
@@ -21,37 +21,23 @@ Implementation
--------------
--------------


Mutexes are represented by 'struct mutex', defined in include/linux/mutex.h
Mutexes are represented by 'struct mutex', defined in include/linux/mutex.h
and implemented in kernel/locking/mutex.c. These locks use a three
and implemented in kernel/locking/mutex.c. These locks use an atomic variable
state atomic counter (->count) to represent the different possible
(->owner) to keep track of the lock state during its lifetime.  Field owner
transitions that can occur during the lifetime of a lock:
actually contains 'struct task_struct *' to the current lock owner and it is

therefore NULL if not currently owned. Since task_struct pointers are aligned
	  1: unlocked
at at least L1_CACHE_BYTES, low bits (3) are used to store extra state (e.g.,
	  0: locked, no waiters
if waiter list is non-empty).  In its most basic form it also includes a
   negative: locked, with potential waiters
wait-queue and a spinlock that serializes access to it. Furthermore,

CONFIG_MUTEX_SPIN_ON_OWNER=y systems use a spinner MCS lock (->osq), described
In its most basic form it also includes a wait-queue and a spinlock
below in (ii).
that serializes access to it. CONFIG_SMP systems can also include
a pointer to the lock task owner (->owner) as well as a spinner MCS
lock (->osq), both described below in (ii).


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


(i) fastpath: tries to atomically acquire the lock by decrementing the
(i) fastpath: tries to atomically acquire the lock by cmpxchg()ing the owner with
    counter. If it was already taken by another task it goes to the next
    the current task. This only works in the uncontended case (cmpxchg() checks
    possible path. This logic is architecture specific. On x86-64, the
    against 0UL, so all 3 state bits above have to be 0). If the lock is
    locking fastpath is 2 instructions:
    contended it goes to the next possible path.

    0000000000000e10 <mutex_lock>:
    e21:   f0 ff 0b                lock decl (%rbx)
    e24:   79 08                   jns    e2e <mutex_lock+0x1e>

   the unlocking fastpath is equally tight:

    0000000000000bc0 <mutex_unlock>:
    bc8:   f0 ff 07                lock incl (%rdi)
    bcb:   7f 0a                   jg     bd7 <mutex_unlock+0x17>



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


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


When to use mutexes
When to use mutexes
-------------------
-------------------