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