blob: 1dfe62c3641d5d9087388c0255f2a9775b520faa [file] [log] [blame]
Ingo Molnarf3f54ff2006-01-09 15:59:20 -08001Generic Mutex Subsystem
2
3started by Ingo Molnar <mingo@redhat.com>
4
5 "Why on earth do we need a new mutex subsystem, and what's wrong
6 with semaphores?"
7
8firstly, there's nothing wrong with semaphores. But if the simpler
9mutex semantics are sufficient for your code, then there are a couple
10of advantages of mutexes:
11
Randy Dunlapef5dc122010-09-02 15:48:16 -070012 - 'struct mutex' is smaller on most architectures: E.g. on x86,
Ingo Molnarf3f54ff2006-01-09 15:59:20 -080013 'struct semaphore' is 20 bytes, 'struct mutex' is 16 bytes.
14 A smaller structure size means less RAM footprint, and better
15 CPU-cache utilization.
16
17 - tighter code. On x86 i get the following .text sizes when
18 switching all mutex-alike semaphores in the kernel to the mutex
19 subsystem:
20
21 text data bss dec hex filename
22 3280380 868188 396860 4545428 455b94 vmlinux-semaphore
23 3255329 865296 396732 4517357 44eded vmlinux-mutex
24
25 that's 25051 bytes of code saved, or a 0.76% win - off the hottest
26 codepaths of the kernel. (The .data savings are 2892 bytes, or 0.33%)
27 Smaller code means better icache footprint, which is one of the
28 major optimization goals in the Linux kernel currently.
29
30 - the mutex subsystem is slightly faster and has better scalability for
31 contended workloads. On an 8-way x86 system, running a mutex-based
32 kernel and testing creat+unlink+close (of separate, per-task files)
33 in /tmp with 16 parallel tasks, the average number of ops/sec is:
34
35 Semaphores: Mutexes:
36
37 $ ./test-mutex V 16 10 $ ./test-mutex V 16 10
38 8 CPUs, running 16 tasks. 8 CPUs, running 16 tasks.
39 checking VFS performance. checking VFS performance.
40 avg loops/sec: 34713 avg loops/sec: 84153
41 CPU utilization: 63% CPU utilization: 22%
42
43 i.e. in this workload, the mutex based kernel was 2.4 times faster
44 than the semaphore based kernel, _and_ it also had 2.8 times less CPU
45 utilization. (In terms of 'ops per CPU cycle', the semaphore kernel
46 performed 551 ops/sec per 1% of CPU time used, while the mutex kernel
47 performed 3825 ops/sec per 1% of CPU time used - it was 6.9 times
48 more efficient.)
49
50 the scalability difference is visible even on a 2-way P4 HT box:
51
52 Semaphores: Mutexes:
53
54 $ ./test-mutex V 16 10 $ ./test-mutex V 16 10
55 4 CPUs, running 16 tasks. 8 CPUs, running 16 tasks.
56 checking VFS performance. checking VFS performance.
57 avg loops/sec: 127659 avg loops/sec: 181082
58 CPU utilization: 100% CPU utilization: 34%
59
60 (the straight performance advantage of mutexes is 41%, the per-cycle
61 efficiency of mutexes is 4.1 times better.)
62
63 - there are no fastpath tradeoffs, the mutex fastpath is just as tight
64 as the semaphore fastpath. On x86, the locking fastpath is 2
65 instructions:
66
67 c0377ccb <mutex_lock>:
68 c0377ccb: f0 ff 08 lock decl (%eax)
Denys Vlasenko75ddb0e2010-02-20 01:03:48 +010069 c0377cce: 78 0e js c0377cde <.text..lock.mutex>
Ingo Molnarf3f54ff2006-01-09 15:59:20 -080070 c0377cd0: c3 ret
71
72 the unlocking fastpath is equally tight:
73
74 c0377cd1 <mutex_unlock>:
75 c0377cd1: f0 ff 00 lock incl (%eax)
Denys Vlasenko75ddb0e2010-02-20 01:03:48 +010076 c0377cd4: 7e 0f jle c0377ce5 <.text..lock.mutex+0x7>
Ingo Molnarf3f54ff2006-01-09 15:59:20 -080077 c0377cd6: c3 ret
78
79 - 'struct mutex' semantics are well-defined and are enforced if
80 CONFIG_DEBUG_MUTEXES is turned on. Semaphores on the other hand have
81 virtually no debugging code or instrumentation. The mutex subsystem
82 checks and enforces the following rules:
83
84 * - only one task can hold the mutex at a time
85 * - only the owner can unlock the mutex
86 * - multiple unlocks are not permitted
87 * - recursive locking is not permitted
88 * - a mutex object must be initialized via the API
89 * - a mutex object must not be initialized via memset or copying
90 * - task may not exit with mutex held
91 * - memory areas where held locks reside must not be freed
92 * - held mutexes must not be reinitialized
Matti Linnanvuorif20fda42007-10-16 23:29:41 -070093 * - mutexes may not be used in hardware or software interrupt
94 * contexts such as tasklets and timers
Ingo Molnarf3f54ff2006-01-09 15:59:20 -080095
96 furthermore, there are also convenience features in the debugging
97 code:
98
99 * - uses symbolic names of mutexes, whenever they are printed in debug output
100 * - point-of-acquire tracking, symbolic lookup of function names
101 * - list of all locks held in the system, printout of them
102 * - owner tracking
103 * - detects self-recursing locks and prints out all relevant info
104 * - detects multi-task circular deadlocks and prints out all affected
105 * locks and tasks (and only those tasks)
106
107Disadvantages
108-------------
109
110The stricter mutex API means you cannot use mutexes the same way you
111can use semaphores: e.g. they cannot be used from an interrupt context,
112nor can they be unlocked from a different context that which acquired
113it. [ I'm not aware of any other (e.g. performance) disadvantages from
114using mutexes at the moment, please let me know if you find any. ]
115
116Implementation of mutexes
117-------------------------
118
Peter Zijlstra67a6de42013-11-08 08:26:39 +0100119'struct mutex' is the new mutex type, defined in include/linux/mutex.h and
120implemented in kernel/locking/mutex.c. It is a counter-based mutex with a
121spinlock and a wait-list. The counter has 3 states: 1 for "unlocked", 0 for
122"locked" and negative numbers (usually -1) for "locked, potential waiters
123queued".
Ingo Molnarf3f54ff2006-01-09 15:59:20 -0800124
125the APIs of 'struct mutex' have been streamlined:
126
127 DEFINE_MUTEX(name);
128
129 mutex_init(mutex);
130
131 void mutex_lock(struct mutex *lock);
132 int mutex_lock_interruptible(struct mutex *lock);
133 int mutex_trylock(struct mutex *lock);
134 void mutex_unlock(struct mutex *lock);
135 int mutex_is_locked(struct mutex *lock);
Robert P. J. Day343b9012007-10-20 00:15:26 +0200136 void mutex_lock_nested(struct mutex *lock, unsigned int subclass);
137 int mutex_lock_interruptible_nested(struct mutex *lock,
138 unsigned int subclass);
Randy Dunlapef5dc122010-09-02 15:48:16 -0700139 int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock);