1mutex(9F) Kernel Functions for Drivers mutex(9F)
2
3
4
6 mutex, mutex_enter, mutex_exit, mutex_init, mutex_destroy, mutex_owned,
7 mutex_tryenter - mutual exclusion lock routines
8
10 #include <sys/ksynch.h>
11
12 void mutex_init(kmutex_t *mp, char *name, kmutex_type_t type,
13 void *arg);
14
15
16 void mutex_destroy(kmutex_t *mp);
17
18
19 void mutex_enter(kmutex_t *mp);
20
21
22 void mutex_exit(kmutex_t *mp);
23
24
25 int mutex_owned(kmutex_t *mp);
26
27
28 int mutex_tryenter(kmutex_t *mp);
29
30
32 Solaris DDI specific (Solaris DDI).
33
35 mp Pointer to a kernel mutex lock (kmutex_t).
36
37
38 name Descriptive string. This is obsolete and should be NULL. (Non-
39 NULL strings are legal, but they are a waste of kernel memory.)
40
41
42 type Type of mutex lock.
43
44
45 arg Type-specific argument for initialization routine.
46
47
49 A mutex enforces a policy of mutual exclusion. Only one thread at a
50 time may hold a particular mutex. Threads trying to lock a held mutex
51 will block until the mutex is unlocked.
52
53
54 Mutexes are strictly bracketing and may not be recursively locked,
55 meaning that mutexes should be exited in the opposite order they were
56 entered, and cannot be reentered before exiting.
57
58
59 mutex_init() initializes a mutex. It is an error to initialize a mutex
60 more than once. The type argument should be set to MUTEX_DRIVER.
61
62
63 arg provides type-specific information for a given variant type of
64 mutex. When mutex_init() is called for driver mutexes, if the mutex is
65 used by the interrupt handler, the arg should be the interrupt priority
66 returned from ddi_intr_get_pri(9F) or ddi_intr_get_softint_pri(9F).
67 Note that arg should be the value of the interrupt priority cast by
68 calling the DDI_INTR_PRI macro. If the mutex is never used inside an
69 interrupt handler, the argument should be NULL.
70
71
72 mutex_enter() is used to acquire a mutex. If the mutex is already held,
73 then the caller blocks. After returning, the calling thread is the
74 owner of the mutex. If the mutex is already held by the calling thread,
75 a panic ensues.
76
77
78 mutex_owned() should only be used in ASSERT() and may be enforced by
79 not being defined unless the preprocessor symbol DEBUG is defined. Its
80 return value is non-zero if the current thread (or, if that cannot be
81 determined, at least some thread) holds the mutex pointed to by mp.
82
83
84 mutex_tryenter() is very similar to mutex_enter() except that it
85 doesn't block when the mutex is already held. mutex_tryenter() returns
86 non-zero when it acquired the mutex and 0 when the mutex is already
87 held.
88
89
90 mutex_exit() releases a mutex and will unblock another thread if any
91 are blocked on the mutex.
92
93
94 mutex_destroy() releases any resources that might have been allocated
95 by mutex_init(). mutex_destroy() must be called before freeing the mem‐
96 ory containing the mutex, and should be called with the mutex unheld
97 (not owned by any thread). The caller must be sure that no other thread
98 attempts to use the mutex.
99
101 mutex_tryenter() returns a non-zero value on success and zero on fail‐
102 ure.
103
104
105 mutex_owned() returns a non-zero value if the calling thread currently
106 holds the mutex pointed to by mp, or when that cannot be determined, if
107 any thread holds the mutex. Otherwise mutex_owned() returns zero.
108
110 These functions can be called from user, kernel, or high-level inter‐
111 rupt context, except for mutex_init() and mutex_destroy(), which can be
112 called from user or kernel context only.
113
115 Example 1 Initializing a Mutex
116
117
118 A driver might do this to initialize a mutex that is part of its unit
119 structure and used in its interrupt routine:
120
121
122 ddi_intr_get_pri(hdlp, &pri);
123 mutex_init(&un->un_lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri));
124 ddi_intr_add_handler(hdlp, xxintr, (caddr_t)un, NULL);
125
126
127 Example 2 Calling a Routine with a Lock
128
129
130 A routine that expects to be called with a certain lock held might have
131 the following ASSERT:
132
133
134 xxstart(struct xxunit *un)
135 {
136 ASSERT(mutex_owned(&un->un_lock));
137 ...
138
139
141 lockstat(1M), Intro(9F), condvar(9F), ddi_intr_alloc(9F),
142 ddi_intr_add_handler(9F), ddi_intr_get_pri(9F), ddi_intr_get_soft‐
143 int_pri(9F), rwlock(9F), semaphore(9F)
144
145
146 Writing Device Drivers
147
149 Compiling with _LOCKTEST or _MPSTATS defined has no effect. To gather
150 lock statistics, see lockstat(1M).
151
152
153 The address of a kmutex_t lock must be aligned on an 8-byte boundary
154 for 64-bit kernels, or a 4-byte boundary for 32-bit kernels. Violation
155 of this requirement will result in undefined behavior, including, but
156 not limited to, failure of mutual exclusion or a system panic.
157
158
159 To write scalable, responsive drivers that do not hang, panic or dead‐
160 lock the system, follow these guidelines:
161 Never return from a driver entry point with a mutex held.
162 Never hold a mutex when calling a service that may block, for example
163 kmem_alloc(9F) with KM_SLEEP or delay(9F).
164 Always acquire mutexes in a consistent order. If a critical section
165 acquires mutex A followed by B, and elsewhere in the driver mutex B
166 is acquired before A, the driver can deadlock with one thread holding
167 A and waiting for B and another thread holding B while waiting for A.
168 Always use a mutex to enforce exclusive access to data, not instruc‐
169 tion paths.
170 Acquiring a lock in user context that is also acquired in interrupt
171 context means that, as long as that lock is held, the driver instance
172 holding the lock is subject to all the rules and limitations of
173 interrupt context.
174 In most cases, a mutex can and should be acquired and released within
175 the same function.
176 Liberal use of debugging aids like ASSERT(mutex_owned(&mutex)) can
177 help find callers of a function which should be holding a mutex but
178 are not. This means you need to test your driver compiled with DEBUG.
179 Do not use a mutex to set driver state. However, you should use a
180 mutex to protect driver state data.
181 Use per-instance and automatic data where possible to reduce the
182 amount of shared data. Per-instance data can be protected by a per-
183 instance lock to improve scalability and reduce contention with mul‐
184 tiple hardware instances.
185 Avoid global data and global mutexes whenever possible.
186
187
188
189
190SunOS 5.11 21 May 2008 mutex(9F)