xref: /freebsd/share/man/man9/locking.9 (revision 4ff78a9ca8224298f95c5f3f99447de03b354ff5)
10929bf8eSJulian Elischer.\" Copyright (c) 2007 Julian Elischer  (julian -  freebsd org )
20929bf8eSJulian Elischer.\" All rights reserved.
30929bf8eSJulian Elischer.\"
40929bf8eSJulian Elischer.\" Redistribution and use in source and binary forms, with or without
50929bf8eSJulian Elischer.\" modification, are permitted provided that the following conditions
60929bf8eSJulian Elischer.\" are met:
70929bf8eSJulian Elischer.\" 1. Redistributions of source code must retain the above copyright
80929bf8eSJulian Elischer.\"    notice, this list of conditions and the following disclaimer.
90929bf8eSJulian Elischer.\" 2. Redistributions in binary form must reproduce the above copyright
100929bf8eSJulian Elischer.\"    notice, this list of conditions and the following disclaimer in the
110929bf8eSJulian Elischer.\"    documentation and/or other materials provided with the distribution.
120929bf8eSJulian Elischer.\"
130929bf8eSJulian Elischer.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
140929bf8eSJulian Elischer.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
150929bf8eSJulian Elischer.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
160929bf8eSJulian Elischer.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
170929bf8eSJulian Elischer.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
180929bf8eSJulian Elischer.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
190929bf8eSJulian Elischer.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
200929bf8eSJulian Elischer.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
210929bf8eSJulian Elischer.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
220929bf8eSJulian Elischer.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
230929bf8eSJulian Elischer.\" SUCH DAMAGE.
240929bf8eSJulian Elischer.\"
250929bf8eSJulian Elischer.\" $FreeBSD$
260929bf8eSJulian Elischer.\"
270929bf8eSJulian Elischer.Dd March 14, 2007
280929bf8eSJulian Elischer.Dt LOCKING 9
290929bf8eSJulian Elischer.Os
300929bf8eSJulian Elischer.Sh NAME
310929bf8eSJulian Elischer.Nm locking ,
320929bf8eSJulian Elischer.Nd kernel synchronization primitives
330929bf8eSJulian Elischer.Sh SYNOPSIS
340929bf8eSJulian ElischerAll sorts of stuff to go here.
350929bf8eSJulian Elischer.Pp
360929bf8eSJulian Elischer.Sh DESCRIPTION
370929bf8eSJulian ElischerThe
380929bf8eSJulian Elischer.Em FreeBSD
390929bf8eSJulian Elischerkernel is written to run across multiple CPUs and as such requires
404ff78a9cSJulian Elischerseveral different synchronization primitives to allow the developers
410929bf8eSJulian Elischerto safely access and manipulate the many data types required.
420929bf8eSJulian Elischer.Pp
430929bf8eSJulian ElischerThese include:
440929bf8eSJulian Elischer.Bl -enum
450929bf8eSJulian Elischer.It
460929bf8eSJulian ElischerSpin Mutexes
470929bf8eSJulian Elischer.It
480929bf8eSJulian ElischerSleep Mutexes
490929bf8eSJulian Elischer.It
500929bf8eSJulian Elischerpool Mutexes
510929bf8eSJulian Elischer.It
520929bf8eSJulian ElischerShared-Exclusive locks
530929bf8eSJulian Elischer.It
540929bf8eSJulian ElischerReader-Writer locks
550929bf8eSJulian Elischer.It
564ff78a9cSJulian ElischerTurnstiles
570929bf8eSJulian Elischer.It
580929bf8eSJulian ElischerSemaphores
590929bf8eSJulian Elischer.It
600929bf8eSJulian ElischerCondition variables
610929bf8eSJulian Elischer.It
620929bf8eSJulian ElischerSleep/wakeup
630929bf8eSJulian Elischer.It
640929bf8eSJulian ElischerGiant
650929bf8eSJulian Elischer.It
660929bf8eSJulian ElischerLockmanager locks
670929bf8eSJulian Elischer.El
680929bf8eSJulian Elischer.Pp
6953882c7cSJulian ElischerThe primitives interact and have a number of rules regarding how
704ff78a9cSJulian Elischerthey can and can not be combined. There are too many for the average
714ff78a9cSJulian Elischerhuman mind and they keep changing.
724ff78a9cSJulian Elischer(if you disagree, please write replacement text)  :-)
730929bf8eSJulian Elischer.Pp
744ff78a9cSJulian ElischerSome of these primitives may be used at the low (interrupt) level and
754ff78a9cSJulian Elischersome may not.
760929bf8eSJulian Elischer.Pp
770929bf8eSJulian ElischerThere are strict ordering requirements and for some of the types this
780929bf8eSJulian Elischeris checked using the
790929bf8eSJulian Elischer.Xr witness 4
800929bf8eSJulian Elischercode.
810929bf8eSJulian Elischer.Pp
820929bf8eSJulian Elischer.Ss SPIN Mutexes
8353882c7cSJulian ElischerMutexes are the basic primitive.
840929bf8eSJulian ElischerYou either hold it or you don't.
854ff78a9cSJulian ElischerIf you don't own it then you just spin, waiting for the holder (on
864ff78a9cSJulian Elischeranother CPU) to release it.
874ff78a9cSJulian ElischerHopefully they are doing something fast.
884ff78a9cSJulian ElischerYou can not do anything that deschedules the thread while you
894ff78a9cSJulian Elischerare holding a SPIN mutex.
900929bf8eSJulian Elischer.Ss Sleep Mutexes
914ff78a9cSJulian ElischerBasically sleep (regular) mutexes will deschedule the thread if the
924ff78a9cSJulian Elischermutex can not be acquired.
934ff78a9cSJulian ElischerAs in spin mutexes, you either get it or you don't.
940929bf8eSJulian ElischerYou may call the
950929bf8eSJulian Elischer.Xr sleep 9
960929bf8eSJulian Elischercall
970929bf8eSJulian Elischer.Fn msleep
980929bf8eSJulian Elischeror the new
990929bf8eSJulian Elischer.Fn mtx_sleep
1000929bf8eSJulian Elischervariant. These will atomically drop the mutex and reacquire it
1010929bf8eSJulian Elischeras part of waking up.
1020929bf8eSJulian Elischer.Ss Pool Mutexes
1034ff78a9cSJulian ElischerA variant of SLEEP mutexes where the allocation of the mutex is handled
1044ff78a9cSJulian Elischermore by the system.
1050929bf8eSJulian Elischer.Ss Sx_locks
1060929bf8eSJulian ElischerShared/exclusive locks are used to protect data that are read far more often
1070929bf8eSJulian Elischerthan they are written.
1080929bf8eSJulian ElischerMutexes are inherently more efficient than shared/exclusive locks, so
1090929bf8eSJulian Elischershared/exclusive locks should be used prudently.
1100929bf8eSJulian ElischerA thread may hold a shared or exclusive lock on an
1110929bf8eSJulian Elischer.Em sx_lock
1120929bf8eSJulian Elischerlock while sleeping.
1130929bf8eSJulian ElischerAs a result, an
11453882c7cSJulian Elischer.Em sx_lock
1150929bf8eSJulian Elischerlock may not be acquired while holding a mutex.
1160929bf8eSJulian ElischerOtherwise, if one thread slept while holding an
11753882c7cSJulian Elischer.Em sx_lock
1180929bf8eSJulian Elischerlock while another thread blocked on the same
11953882c7cSJulian Elischer.Em sx_lock
1200929bf8eSJulian Elischerlock after acquiring a mutex, then the second thread would effectively
1210929bf8eSJulian Elischerend up sleeping while holding a mutex, which is not allowed.
1220929bf8eSJulian Elischer.Ss Rw_locks
1230929bf8eSJulian ElischerReader/writer locks allow shared access to protected data by multiple threads,
1240929bf8eSJulian Elischeror exclusive access by a single thread.
1250929bf8eSJulian ElischerThe threads with shared access are known as
1260929bf8eSJulian Elischer.Em readers
1270929bf8eSJulian Elischersince they only read the protected data.
1280929bf8eSJulian ElischerA thread with exclusive access is known as a
1290929bf8eSJulian Elischer.Em writer
1300929bf8eSJulian Elischersince it can modify protected data.
1310929bf8eSJulian Elischer.Pp
1320929bf8eSJulian ElischerAlthough reader/writer locks look very similar to
1330929bf8eSJulian Elischer.Xr sx 9
1340929bf8eSJulian Elischerlocks, their usage pattern is different.
1350929bf8eSJulian ElischerReader/writer locks can be treated as mutexes (see
1360929bf8eSJulian Elischer.Xr mutex 9 )
1370929bf8eSJulian Elischerwith shared/exclusive semantics.
1380929bf8eSJulian ElischerUnlike
1390929bf8eSJulian Elischer.Xr sx 9 ,
1400929bf8eSJulian Elischeran
1410929bf8eSJulian Elischer.Em rw_lock
1420929bf8eSJulian Elischercan be locked while holding a non-spin mutex, and an
1430929bf8eSJulian Elischer.Em rw_lock
1440929bf8eSJulian Elischercannot be held while sleeping.
1450929bf8eSJulian ElischerThe
1460929bf8eSJulian Elischer.Em rw_lock
1470929bf8eSJulian Elischerlocks have priority propagation like mutexes, but priority
1480929bf8eSJulian Elischercan be propagated only to an exclusive holder.
1490929bf8eSJulian ElischerThis limitation comes from the fact that shared owners
1500929bf8eSJulian Elischerare anonymous.
1510929bf8eSJulian ElischerAnother important property is that shared holders of
1520929bf8eSJulian Elischer.Em rw_lock
1530929bf8eSJulian Elischercan recurse,
1540929bf8eSJulian Elischerbut exclusive locks are not allowed to recurse.
15553882c7cSJulian Elischer.Ss Turnstiles
1560929bf8eSJulian ElischerTurnstiles are used to hold a queue of threads blocked on
1574ff78a9cSJulian Elischernon-sleepable locks.
1584ff78a9cSJulian ElischerSleepable locks use condition variables to implement their queues.
1594ff78a9cSJulian ElischerTurnstiles differ from a sleep queue in that turnstile queue's
1604ff78a9cSJulian Elischerare assigned to a lock held by an owning thread.
1614ff78a9cSJulian ElischerThus, when one thread is enqueued onto a turnstile, it can lend its
1624ff78a9cSJulian Elischerpriority to the owning thread.
1630929bf8eSJulian Elischer.Ss Semaphores
1640929bf8eSJulian Elischer.Ss Condition variables
1654ff78a9cSJulian ElischerCondition variables are used in conjunction with mutexes to wait for
1664ff78a9cSJulian Elischerconditions to occur.
1670929bf8eSJulian ElischerA thread must hold the mutex before calling the
1680929bf8eSJulian Elischer.Fn cv_wait* ,
1690929bf8eSJulian Elischerfunctions.
1700929bf8eSJulian ElischerWhen a thread waits on a condition, the mutex
1710929bf8eSJulian Elischeris atomically released before the thread is blocked, then reacquired
1720929bf8eSJulian Elischerbefore the function call returns.
1730929bf8eSJulian Elischer.Ss Giant
1740929bf8eSJulian ElischerGiant is a special instance of a sleep lock.
1750929bf8eSJulian Elischerit has several special characteristics.
1760929bf8eSJulian Elischer.Ss Sleep/wakeup
1770929bf8eSJulian ElischerThe functions
1780929bf8eSJulian Elischer.Fn tsleep ,
1790929bf8eSJulian Elischer.Fn msleep ,
1800929bf8eSJulian Elischer.Fn msleep_spin ,
1810929bf8eSJulian Elischer.Fn pause ,
1820929bf8eSJulian Elischer.Fn wakeup ,
1830929bf8eSJulian Elischerand
1840929bf8eSJulian Elischer.Fn wakeup_one
1850929bf8eSJulian Elischerhandle event-based thread blocking.
1864ff78a9cSJulian ElischerIf a thread must wait for an external event, it is put to sleep by
1870929bf8eSJulian Elischer.Fn tsleep ,
1880929bf8eSJulian Elischer.Fn msleep ,
1890929bf8eSJulian Elischer.Fn msleep_spin ,
1900929bf8eSJulian Elischeror
1910929bf8eSJulian Elischer.Fn pause .
1920929bf8eSJulian ElischerThreads may also wait using one of the locking primitive sleep routines
1930929bf8eSJulian Elischer.Xr mtx_sleep 9 ,
1940929bf8eSJulian Elischer.Xr rw_sleep 9 ,
1950929bf8eSJulian Elischeror
1960929bf8eSJulian Elischer.Xr sx_sleep 9 .
1970929bf8eSJulian Elischer.Pp
1980929bf8eSJulian ElischerThe parameter
1990929bf8eSJulian Elischer.Fa chan
2000929bf8eSJulian Elischeris an arbitrary address that uniquely identifies the event on which
2010929bf8eSJulian Elischerthe thread is being put to sleep.
2020929bf8eSJulian ElischerAll threads sleeping on a single
2030929bf8eSJulian Elischer.Fa chan
2040929bf8eSJulian Elischerare woken up later by
2050929bf8eSJulian Elischer.Fn wakeup ,
2060929bf8eSJulian Elischeroften called from inside an interrupt routine, to indicate that the
2070929bf8eSJulian Elischerresource the thread was blocking on is available now.
2080929bf8eSJulian Elischer.Pp
2090929bf8eSJulian ElischerSeveral of the sleep functions including
2100929bf8eSJulian Elischer.Fn msleep ,
2110929bf8eSJulian Elischer.Fn msleep_spin ,
2120929bf8eSJulian Elischerand the locking primitive sleep routines specify an additional lock
2130929bf8eSJulian Elischerparameter.
2140929bf8eSJulian ElischerThe lock will be released before sleeping and reacquired
2150929bf8eSJulian Elischerbefore the sleep routine returns.
2160929bf8eSJulian ElischerIf
2170929bf8eSJulian Elischer.Fa priority
2180929bf8eSJulian Elischerincludes the
2190929bf8eSJulian Elischer.Dv PDROP
2204ff78a9cSJulian Elischerflag, then the lock will not be reacquired before returning.
2210929bf8eSJulian ElischerThe lock is used to ensure that a condition can be checked atomically,
2220929bf8eSJulian Elischerand that the current thread can be suspended without missing a
2230929bf8eSJulian Elischerchange to the condition, or an associated wakeup.
2240929bf8eSJulian ElischerIn addition, all of the sleep routines will fully drop the
2250929bf8eSJulian Elischer.Va Giant
2260929bf8eSJulian Elischermutex
2270929bf8eSJulian Elischer(even if recursed)
2280929bf8eSJulian Elischerwhile the thread is suspended and will reacquire the
2290929bf8eSJulian Elischer.Va Giant
2300929bf8eSJulian Elischermutex before the function returns.
2310929bf8eSJulian Elischer.Pp
2320929bf8eSJulian Elischer.Ss lockmanager locks
2330929bf8eSJulian ElischerLargly deprecated. See the
2340929bf8eSJulian Elischer.Xr lock 9
2350929bf8eSJulian Elischerpage for more information.
2360929bf8eSJulian ElischerI don't know what the downsides are but I'm sure someone will fill in this part.
237c2c54c3dSJulian Elischer.Sh Usage tables.
238c2c54c3dSJulian Elischer.Ss Interaction table.
2390929bf8eSJulian ElischerThe following table shows what you can and can not do if you hold
2404ff78a9cSJulian Elischerone of the synchronisation primitives discussed here:
2410929bf8eSJulian Elischer(someone who knows what they are talking about should write this table)
2420929bf8eSJulian Elischer.Bl -column ".Ic xxxxxxxxxxxxxxxxxxxx" ".Xr XXXXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXX" -offset indent
2430929bf8eSJulian Elischer.It Xo
2440929bf8eSJulian Elischer.Em "You have:  You want:" Ta Spin_mtx Ta Slp_mtx Ta sx_lock Ta rw_lock Ta sleep
2450929bf8eSJulian Elischer.Xc
2460929bf8eSJulian Elischer.It Ic SPIN mutex  Ta \&ok Ta \&no Ta \&no Ta \&no Ta \&no-3
2470929bf8eSJulian Elischer.It Ic Sleep mutex Ta \&ok Ta \&ok-1 Ta \&no Ta \&ok Ta \&no-3
24834e1b9e5SJulian Elischer.It Ic sx_lock     Ta \&ok Ta \&no Ta \&ok-2 Ta \&no Ta \&ok-4
24934e1b9e5SJulian Elischer.It Ic rw_lock     Ta \&ok Ta \&ok Ta \&no Ta \&ok-2 Ta \&no-3
2500929bf8eSJulian Elischer.El
2510929bf8eSJulian Elischer.Pp
2520929bf8eSJulian Elischer.Em *1
2534ff78a9cSJulian ElischerRecursion is defined per lock. Lock order is important.
2540929bf8eSJulian Elischer.Pp
2550929bf8eSJulian Elischer.Em *2
2564ff78a9cSJulian Elischerreaders can recurse though writers can not. Lock order is important.
2570929bf8eSJulian Elischer.Pp
2580929bf8eSJulian Elischer.Em *3
2594ff78a9cSJulian ElischerThere are calls atomically release this primitive when going to sleep
2600929bf8eSJulian Elischerand reacquire it on wakeup (e.g.
2610929bf8eSJulian Elischer.Fn mtx_sleep ,
26234e1b9e5SJulian Elischer.Fn rw_sleep
2630929bf8eSJulian Elischerand
2640929bf8eSJulian Elischer.Fn msleep_spin ).
2650929bf8eSJulian Elischer.Pp
2660929bf8eSJulian Elischer.Em *4
26734e1b9e5SJulian ElischerThough one can sleep holding an sx lock, one can also use
2680929bf8eSJulian Elischer.Fn sx_sleep
2694ff78a9cSJulian Elischerwhich atomically release this primitive when going to sleep and
2704ff78a9cSJulian Elischerreacquire it on wakeup.
271c2c54c3dSJulian Elischer.Ss Context mode table.
2724ff78a9cSJulian ElischerThe next table shows what can be used in different contexts.
2734ff78a9cSJulian ElischerAt this time this is a rather easy to remember table.
274c2c54c3dSJulian Elischer.Bl -column ".Ic Xxxxxxxxxxxxxxxxxxxx" ".Xr XXXXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXX" -offset indent
275c2c54c3dSJulian Elischer.It Xo
276c2c54c3dSJulian Elischer.Em "Context:" Ta Spin_mtx Ta Slp_mtx Ta sx_lock Ta rw_lock Ta sleep
277c2c54c3dSJulian Elischer.Xc
278c2c54c3dSJulian Elischer.It interrupt:  Ta \&ok Ta \&no Ta \&no Ta \&no Ta \&no
279c2c54c3dSJulian Elischer.It idle:  Ta \&ok Ta \&no Ta \&no Ta \&no Ta \&no
280c2c54c3dSJulian Elischer.El
281c2c54c3dSJulian Elischer.Xc
2820929bf8eSJulian Elischer.Sh SEE ALSO
2830929bf8eSJulian Elischer.Xr condvar 9 ,
2840929bf8eSJulian Elischer.Xr lock 9
2850929bf8eSJulian Elischer.Xr mtx_pool 9 ,
2860929bf8eSJulian Elischer.Xr rwlock 9 ,
2870929bf8eSJulian Elischer.Xr sema 9 ,
2880929bf8eSJulian Elischer.Xr sleep 9 ,
2890929bf8eSJulian Elischer.Xr sx 9
2900929bf8eSJulian Elischer.Xr LOCK_PROFILING 9 ,
2910929bf8eSJulian Elischer.Xr WITNESS 9 ,
2920929bf8eSJulian Elischer.Sh HISTORY
2930929bf8eSJulian ElischerThese
2940929bf8eSJulian Elischerfunctions appeared in
2950929bf8eSJulian Elischer.Bsx 4.1
2960929bf8eSJulian Elischerthrough
2970929bf8eSJulian Elischer.Fx 7.0
298