1.\" $NetBSD: lock.9,v 1.10 2001/09/04 03:05:54 wiz 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 <sys/lock.h> 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_lock_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 80.Pp 81The 82.Nm 83functions provide synchronisation in the kernel by preventing multiple 84threads from simultaneously executing critical sections of code 85accessing shared data. A number of different locks are available: 86.Pp 87.Bl -tag -width compact 88.It struct simplelock 89Provides a simple spinning mutex. A processor will busy-wait while 90trying to acquire a simplelock. The simplelock operations are 91implemented with machine-dependent locking primitives. 92.Pp 93Simplelocks are usually used only by the high-level lock manager and 94to protect short, critical sections of code. Simplelocks are the only 95locks that can be be used inside an interrupt handler. For a 96simplelock to be used in an interrupt handler, care must be taken to 97disable the interrupt, acquire the lock, do any processing, release 98the simplelock and re-enable the interrupt. This procedure is 99necessary to avoid deadlock between the interrupt handler and other 100threads executing on the same processor. 101.It struct lock 102Provides a high-level lock supporting sleeping/spinning until the lock 103can be acquired. The lock manager supplies both exclusive-access and 104shared-access locks, with recursive exclusive-access locks within a 105single thread. It also allows upgrading a shared-access lock to an 106exclusive-access lock, as well as downgrading an exclusive-access lock 107to a shared-access lock. 108.El 109.Pp 110If the kernel option LOCKDEBUG is enabled, additional facilities 111are provided to record additional lock information. These facilities are 112provided to assist in determining deadlock occurrences. 113.Sh FUNCTIONS 114The functions which operate on simplelocks are: 115.Pp 116.Bl -tag -width compact 117.It Fn simple_lock_init "slock" 118The simplelock 119.Fa slock 120is initialised to the unlocked state. A statically allocated simplelock 121also can be initialised with the macro SIMPLELOCK_INITIALIZER. The 122effect is the same as the dynamic initialisation by a call to 123simple_lock_init. For example, 124.Pp 125struct simplelock slock = SIMPLELOCK_INITIALIZER; 126.It Fn simple_lock "slock" 127The simplelock 128.Fa slock 129is locked. If the simplelock is held then execution will 130spin until the simplelock is acquired. Care must be taken that the 131calling thread does not already hold the simplelock. In this case, the 132simplelock can never be acquired. If kernel option LOCKDEBUG is enabled, 133a "locking against myself" panic will occur. 134.It Fn simple_lock_try "slock" 135Try to acquire the simplelock 136.Fa slock 137without spinning. If the simplelock is held by another thread 138then the return value is 0. If the simplelock was acquired 139successfully then the return value is 1. 140.It Fn simple_lock_unlock "slock" 141The simplelock 142.Fa slock 143is unlocked. The simplelock must be locked and the calling thread must 144be the one that last acquired the simplelock. If the calling 145thread does not hold the simplelock, the simplelock will be released 146but the kernel behaviour is undefined. 147.It Fn simple_lock_freecheck "start" "end" 148Check that all simplelocks in the address range 149.Fa start 150to 151.Fa end 152are not held. If a simplelock within the range is found, the kernel 153enters the debugger. This function is available only with kernel 154option LOCKDEBUG. It provides a mechanism for basic simplelock 155consistency checks. 156.It Fn simple_lock_dump "void" 157Dump the state of all simplelocks in the kernel. This function is 158available only with kernel option LOCKDEBUG. 159.El 160.Pp 161The functions which operate on locks are: 162.Pp 163.Bl -tag -width compact 164.It Fn lockinit "lock" "prio" "wmesg" "timo" "flags" 165The lock 166.Fa lock 167is initialised according to the parameters provided. Arguments are as 168follows: 169.Bl -tag -width compact 170.It Fa lock 171The lock. 172.It Fa prio 173The thread priority when it is woken up after sleeping on the lock. 174.It Fa wmesg 175A sleep message used when a thread goes to sleep waiting for the lock, so 176that the exact reason it is sleeping can easily be identified. 177.It Fa timo 178The maximum sleep time. Used by 179.Xr tsleep 9 . 180.It Fa flags 181Flags to specify the lock behaviour permanently over the lifetime of 182the lock. Valid lock flags are: 183.Bl -tag -width compact 184.It LK_NOWAIT 185Threads should not sleep when attempting to acquire the lock. 186.It LK_SLEEPFAIL 187Threads should sleep, then return failure when acquiring the lock. 188.It LK_CANRECURSE 189Threads can acquire the lock recursively. 190.El 191.El 192.It Fn lockmgr "lock" "flags" "slock" 193Set, change or release a lock according to the parameters provided. 194Arguments are as follows: 195.Bl -tag -width compact 196.It Fa lock 197The lock. 198.It Fa slock 199Simplelock interlock. The simplelock 200.Fa slock 201is set by the caller. When the lock 202.Fa lock 203is acquired, the simplelock is released. 204.It Fa flags 205Flags to specify the lock request type. In addition to the flags 206specified above, the following flags are valid: 207.Bl -tag -width compact 208.It LK_SHARED 209Get one of many possible shared-access locks. If a thread holding an 210exclusive-access lock requests a shared-access lock, the 211exclusive-access lock is downgraded to a shared-access lock. 212.It LK_EXCLUSIVE 213Stop further shared-access locks, when they are cleared, grant a 214pending upgrade if it exists, then grant an exclusive-access lock. 215Only one exclusive-access lock may exist at a time, except that a 216thread holding an exclusive-access lock may get additional 217exclusive-access locks if it explicitly sets the LK_CANRECURSE flag in 218the lock request, or if the LK_CANRECURSE flag was set when the lock 219was initialised. 220.It LK_UPGRADE 221The thread must hold a shared-access lock that it wants to have 222upgraded to an exclusive-access lock. Other threads may get exclusive 223access to the protected resource between the time that the upgrade is 224requested and the time that it is granted. 225.It LK_EXCLUPGRADE 226The thread must hold a shared-access lock that it wants to have 227upgraded to an exclusive-access lock. If the request succeeds, no 228other threads will have acquired exclusive access to the protected 229resource between the time that the upgrade is requested and the time 230that it is granted. However, if another thread has already requested 231an upgrade, the request will fail. 232.It LK_DOWNGRADE 233The thread must hold an exclusive-access lock that it wants to have 234downgraded to a shared-access lock. If the thread holds multiple 235(recursive) exclusive-access locks, they will all be downgraded to 236shared-access locks. 237.It LK_RELEASE 238Release one instance of a lock. 239.It LK_DRAIN 240Wait for all activity on the lock to end, then mark it decommissioned. 241This feature is used before freeing a lock that is part of a piece of 242memory that is about to be freed. 243.It LK_REENABLE 244Lock is to be re-enabled after drain. The LK_REENABLE flag may be set 245only at the release of a lock obtained by a drain. 246.It LK_SETRECURSE 247Other locks while we have it OK. 248.It LK_RECURSEFAIL 249Attempt at recursive lock fails. 250.It LK_SPIN 251Lock spins instead of sleeping. 252.El 253.El 254.It Fn lockstatus "lock" 255Determine the status of lock 256.Fa lock . 257Returns LK_EXCLUSIVE or LK_SHARED for exclusive-access and 258shared-access locks respectively. 259.It Fn lockmgr_printinfo "lock" 260Print out information about state of lock 261.Fa lock . 262.It Fn spinlockinit "lock" "wmesg" "flags" 263The lock 264.Fa lock 265is initialised as a spinlock according to the parameters provided. 266Arguments are as follows: 267.Bl -tag -width compact 268.It Fa lock 269The lock. 270.It Fa wmesg 271This is a simple name for lock. 272.It Fa flags 273Flags to specify the lock behaviour. Valid lock flags are the same as 274outlined above. 275.El 276.It Fn spinlockmgr "lock" "flags" "slock" 277Set, change or release a lock according to the parameters provided. 278Arguments are as follows: 279.Bl -tag -width compact 280.It Fa lock 281The spin lock. 282.It Fa flags 283Flags to specify the lock request type. Valid lock flags are the same 284as outlined above. 285.It Fa slock 286Simplelock interlock. The simplelock 287.Fa slock 288is set by the caller. When the lock 289.Fa lock 290is acquired, the simplelock is released. 291.El 292.El 293.Sh RETURN VALUES 294Successfully acquired locks return 0. A failed lock attempt always 295returns a non-zero error value. No lock is held after an error 296return (in particular, a failed LK_UPGRADE or LK_FORCEUPGRADE will 297have released its shared-access lock). Locks will always succeed 298unless one of the following is true: 299.Bl -tag -width Er 300.It Bq Er EBUSY 301LK_FORCEUPGRADE is requested and some other thread has already 302requested a lock upgrade or LK_NOWAIT is set and a sleep would 303be required. 304.It Bq Er ENOLCK 305LK_SLEEPFAIL is set and a sleep was done. 306.It Bq Er EINTR 307PCATCH is set in lock priority and a signal arrives to interrupt 308a system call. 309.It Bq Er ERESTART 310PCATCH is set in lock priority and a signal arrives so that 311the system call is restarted. 312.It Bq Er EWOULDBLOCK 313Non-null lock timeout and timeout expires. 314.El 315.Sh CODE REFERENCES 316This section describes places within the 317.Nx 318source tree where actual code implementing or utilising the locking 319framework can be found. All pathnames are relative to 320.Pa /usr/src . 321.Pp 322The locking framework itself is implemented within the file 323.Pa sys/kern/kern_lock.c . 324Data structures and function prototypes for the framework are located 325in 326.Pa sys/sys/lock.h . 327Machine-dependent simplelock primitives are implemented within the 328file 329.Pa sys/arch/<arch>/include/lock.h . 330.Sh SEE ALSO 331.Xr pmap 9 , 332.Xr spl 9 , 333.Xr tsleep 9 , 334.Xr uvm 9 335.Sh HISTORY 336The kernel locking API first appeared in 337.Bx 4.4 -lite2 . 338