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