1.\" $NetBSD: lock.9,v 1.13 2002/02/13 08:18:44 ross Exp $ 2.\" 3.\" Copyright (c) 2000 The NetBSD Foundation, Inc. 4.\" All rights reserved. 5.\" 6.\" Redistribution and use in source and binary forms, with or without 7.\" modification, are permitted provided that the following conditions 8.\" are met: 9.\" 1. Redistributions of source code must retain the above copyright 10.\" notice, this list of conditions and the following disclaimer. 11.\" 2. Redistributions in binary form must reproduce the above copyright 12.\" notice, this list of conditions and the following disclaimer in the 13.\" documentation and/or other materials provided with the distribution. 14.\" 3. All advertising materials mentioning features or use of this software 15.\" must display the following acknowledgement: 16.\" This product includes software developed by the NetBSD 17.\" Foundation, Inc. and its contributors. 18.\" 4. Neither the name of The NetBSD Foundation nor the names of its 19.\" contributors may be used to endorse or promote products derived 20.\" from this software without specific prior written permission. 21.\" 22.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 23.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 25.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 26.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32.\" POSSIBILITY OF SUCH DAMAGE. 33.\" 34.Dd June 23, 2000 35.Dt LOCK 9 36.Os 37.Sh NAME 38.Nm lock , 39.Nm simple_lock_init , 40.Nm simple_lock , 41.Nm simple_lock_try , 42.Nm simple_unlock , 43.Nm simple_lock_freecheck , 44.Nm simple_lock_dump , 45.Nm lockinit , 46.Nm lockmgr , 47.Nm lockstatus , 48.Nm lockmgr_printinfo , 49.Nm spinlockinit , 50.Nm spinlockmgr 51.Nd kernel lock functions 52.Sh SYNOPSIS 53.Fd #include \*[Lt]sys/lock.h\*[Gt] 54.Ft void 55.Fn simple_lock_init "struct simplelock *slock" 56.Ft void 57.Fn simple_lock "struct simplelock *slock" 58.Ft int 59.Fn simple_lock_try "struct simplelock *slock" 60.Ft void 61.Fn simple_unlock "struct simplelock *slock" 62.Ft void 63.Fn simple_lock_freecheck "void *start" "void *end" 64.Ft void 65.Fn simple_lock_dump "void" 66.Ft void 67.Fn lockinit "struct lock *lock" "int prio" "const char *wmesg" \ 68"int timo" "int flags" 69.Ft int 70.Fn lockmgr "struct lock *lock" "u_int flags" "struct simplelock *slock" 71.Ft int 72.Fn lockstatus "struct lock *lock" 73.Ft void 74.Fn lockmgr_printinfo "struct lock *lock" 75.Ft void 76.Fn spinlockinit "struct lock *lock" "const char *wmesg" "int flags" 77.Ft int 78.Fn spinlockmgr "struct lock *lock" "u_int flags" "struct simplelock *slock" 79.Sh DESCRIPTION 80The 81.Nm 82functions provide synchronisation in the kernel by preventing multiple 83threads from simultaneously executing critical sections of code 84accessing shared data. A number of different locks are available: 85.Pp 86.Bl -tag -width compact 87.It struct simplelock 88Provides a simple spinning mutex. A processor will busy-wait while 89trying to acquire a simplelock. The simplelock operations are 90implemented with machine-dependent locking primitives. 91.Pp 92Simplelocks are usually used only by the high-level lock manager and 93to protect short, critical sections of code. Simplelocks are the only 94locks that can be be used inside an interrupt handler. For a 95simplelock to be used in an interrupt handler, care must be taken to 96disable the interrupt, acquire the lock, do any processing, release 97the simplelock and re-enable the interrupt. This procedure is 98necessary to avoid deadlock between the interrupt handler and other 99threads executing on the same processor. 100.It struct lock 101Provides a high-level lock supporting sleeping/spinning until the lock 102can be acquired. The lock manager supplies both exclusive-access and 103shared-access locks, with recursive exclusive-access locks within a 104single thread. It also allows upgrading a shared-access lock to an 105exclusive-access lock, as well as downgrading an exclusive-access lock 106to a shared-access lock. 107.El 108.Pp 109If the kernel option LOCKDEBUG is enabled, additional facilities 110are provided to record additional lock information. These facilities are 111provided to assist in determining deadlock occurrences. 112.Sh FUNCTIONS 113The functions which operate on simplelocks are: 114.Pp 115.Bl -tag -width compact 116.It Fn simple_lock_init "slock" 117The simplelock 118.Fa slock 119is initialised to the unlocked state. A statically allocated simplelock 120also can be initialised with the macro SIMPLELOCK_INITIALIZER. The 121effect is the same as the dynamic initialisation by a call to 122simple_lock_init. For example, 123.Pp 124struct simplelock slock = SIMPLELOCK_INITIALIZER; 125.It Fn simple_lock "slock" 126The simplelock 127.Fa slock 128is locked. If the simplelock is held then execution will 129spin until the simplelock is acquired. Care must be taken that the 130calling thread does not already hold the simplelock. In this case, the 131simplelock can never be acquired. If kernel option LOCKDEBUG is enabled, 132a "locking against myself" panic will occur. 133.It Fn simple_lock_try "slock" 134Try to acquire the simplelock 135.Fa slock 136without spinning. If the simplelock is held by another thread 137then the return value is 0. If the simplelock was acquired 138successfully then the return value is 1. 139.It Fn simple_lock_unlock "slock" 140The simplelock 141.Fa slock 142is unlocked. The simplelock must be locked and the calling thread must 143be the one that last acquired the simplelock. If the calling 144thread does not hold the simplelock, the simplelock will be released 145but the kernel behaviour is undefined. 146.It Fn simple_lock_freecheck "start" "end" 147Check that all simplelocks in the address range 148.Fa start 149to 150.Fa end 151are not held. If a simplelock within the range is found, the kernel 152enters the debugger. This function is available only with kernel 153option LOCKDEBUG. It provides a mechanism for basic simplelock 154consistency checks. 155.It Fn simple_lock_dump "void" 156Dump the state of all simplelocks in the kernel. This function is 157available only with kernel option LOCKDEBUG. 158.El 159.Pp 160The functions which operate on locks are: 161.Pp 162.Bl -tag -width compact 163.It Fn lockinit "lock" "prio" "wmesg" "timo" "flags" 164The lock 165.Fa lock 166is initialised according to the parameters provided. Arguments are as 167follows: 168.Bl -tag -width compact 169.It Fa lock 170The lock. 171.It Fa prio 172The thread priority when it is woken up after sleeping on the lock. 173.It Fa wmesg 174A sleep message used when a thread goes to sleep waiting for the lock, so 175that the exact reason it is sleeping can easily be identified. 176.It Fa timo 177The maximum sleep time. Used by 178.Xr tsleep 9 . 179.It Fa flags 180Flags to specify the lock behaviour permanently over the lifetime of 181the lock. Valid lock flags are: 182.Bl -tag -width compact 183.It LK_NOWAIT 184Threads should not sleep when attempting to acquire the lock. 185.It LK_SLEEPFAIL 186Threads should sleep, then return failure when acquiring the lock. 187.It LK_CANRECURSE 188Threads can acquire the lock recursively. 189.El 190.El 191.It Fn lockmgr "lock" "flags" "slock" 192Set, change or release a lock according to the parameters provided. 193Arguments are as follows: 194.Bl -tag -width compact 195.It Fa lock 196The lock. 197.It Fa slock 198Simplelock interlock. If the flag LK_INTERLOCK is set in 199.Fa flags , 200.Fa slock 201is a simplelock held by the caller. When the lock 202.Fa lock 203is acquired, the simplelock is released. If the flag LK_INTERLOCK is 204not set, 205.Fa slock 206is ignored. 207.It Fa flags 208Flags to specify the lock request type. In addition to the flags 209specified above, the following flags are valid: 210.Bl -tag -width compact 211.It LK_SHARED 212Get one of many possible shared-access locks. If a thread holding an 213exclusive-access lock requests a shared-access lock, the 214exclusive-access lock is downgraded to a shared-access lock. 215.It LK_EXCLUSIVE 216Stop further shared-access locks, when they are cleared, grant a 217pending upgrade if it exists, then grant an exclusive-access lock. 218Only one exclusive-access lock may exist at a time, except that a 219thread holding an exclusive-access lock may get additional 220exclusive-access locks if it explicitly sets the LK_CANRECURSE flag in 221the lock request, or if the LK_CANRECURSE flag was set when the lock 222was initialised. 223.It LK_UPGRADE 224The thread must hold a shared-access lock that it wants to have 225upgraded to an exclusive-access lock. Other threads may get exclusive 226access to the protected resource between the time that the upgrade is 227requested and the time that it is granted. 228.It LK_EXCLUPGRADE 229The thread must hold a shared-access lock that it wants to have 230upgraded to an exclusive-access lock. If the request succeeds, no 231other threads will have acquired exclusive access to the protected 232resource between the time that the upgrade is requested and the time 233that it is granted. However, if another thread has already requested 234an upgrade, the request will fail. 235.It LK_DOWNGRADE 236The thread must hold an exclusive-access lock that it wants to have 237downgraded to a shared-access lock. If the thread holds multiple 238(recursive) exclusive-access locks, they will all be downgraded to 239shared-access locks. 240.It LK_RELEASE 241Release one instance of a lock. 242.It LK_DRAIN 243Wait for all activity on the lock to end, then mark it decommissioned. 244This feature is used before freeing a lock that is part of a piece of 245memory that is about to be freed. 246.It LK_REENABLE 247Lock is to be re-enabled after drain. The LK_REENABLE flag may be set 248only at the release of a lock obtained by a drain. 249.It LK_SETRECURSE 250Other locks while we have it OK. 251.It LK_RECURSEFAIL 252Attempt at recursive lock fails. 253.It LK_SPIN 254Lock spins instead of sleeping. 255.It LK_INTERLOCK 256Unlock the simplelock 257.Fa slock 258when the lock is acquired. 259.El 260.El 261.It Fn lockstatus "lock" 262Determine the status of lock 263.Fa lock . 264Returns LK_EXCLUSIVE or LK_SHARED for exclusive-access and 265shared-access locks respectively. 266.It Fn lockmgr_printinfo "lock" 267Print out information about state of lock 268.Fa lock . 269.It Fn spinlockinit "lock" "wmesg" "flags" 270The lock 271.Fa lock 272is initialised as a spinlock according to the parameters provided. 273Arguments are as follows: 274.Bl -tag -width compact 275.It Fa lock 276The lock. 277.It Fa wmesg 278This is a simple name for lock. 279.It Fa flags 280Flags to specify the lock behaviour. Valid lock flags are the same as 281outlined above. 282.El 283.It Fn spinlockmgr "lock" "flags" "slock" 284Set, change or release a lock according to the parameters provided. 285Arguments are as follows: 286.Bl -tag -width compact 287.It Fa lock 288The spin lock. 289.It Fa flags 290Flags to specify the lock request type. Valid lock flags are the same 291as outlined above. 292.It Fa slock 293Simplelock interlock. The simplelock 294.Fa slock 295is set by the caller. When the lock 296.Fa lock 297is acquired, the simplelock is released. 298.El 299.El 300.Sh RETURN VALUES 301Successfully acquired locks return 0. A failed lock attempt always 302returns a non-zero error value. No lock is held after an error 303return (in particular, a failed LK_UPGRADE or LK_FORCEUPGRADE will 304have released its shared-access lock). Locks will always succeed 305unless one of the following is true: 306.Bl -tag -width Er 307.It Bq Er EBUSY 308LK_FORCEUPGRADE is requested and some other thread has already 309requested a lock upgrade or LK_NOWAIT is set and a sleep would 310be required. 311.It Bq Er ENOLCK 312LK_SLEEPFAIL is set and a sleep was done. 313.It Bq Er EINTR 314PCATCH is set in lock priority and a signal arrives to interrupt 315a system call. 316.It Bq Er ERESTART 317PCATCH is set in lock priority and a signal arrives so that 318the system call is restarted. 319.It Bq Er EWOULDBLOCK 320Non-null lock timeout and timeout expires. 321.El 322.Sh CODE REFERENCES 323This section describes places within the 324.Nx 325source tree where actual code implementing or utilising the locking 326framework can be found. All pathnames are relative to 327.Pa /usr/src . 328.Pp 329The locking framework itself is implemented within the file 330.Pa sys/kern/kern_lock.c . 331Data structures and function prototypes for the framework are located 332in 333.Pa sys/sys/lock.h . 334Machine-dependent simplelock primitives are implemented within the 335file 336.Pa sys/arch/\*[Lt]arch\*[Gt]/include/lock.h . 337.Sh SEE ALSO 338.Xr pmap 9 , 339.Xr spl 9 , 340.Xr tsleep 9 , 341.Xr uvm 9 342.Sh HISTORY 343The kernel locking API first appeared in 344.Bx 4.4 -lite2 . 345