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