1.\" 2.\" Copyright (C) 2002 Chad David <davidc@acns.ab.ca>. All rights reserved. 3.\" 4.\" Redistribution and use in source and binary forms, with or without 5.\" modification, are permitted provided that the following conditions 6.\" are met: 7.\" 1. Redistributions of source code must retain the above copyright 8.\" notice(s), this list of conditions and the following disclaimer as 9.\" the first lines of this file unmodified other than the possible 10.\" addition of one or more copyright notices. 11.\" 2. Redistributions in binary form must reproduce the above copyright 12.\" notice(s), this list of conditions and the following disclaimer in the 13.\" documentation and/or other materials provided with the distribution. 14.\" 15.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY 16.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18.\" DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY 19.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22.\" CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 25.\" DAMAGE. 26.\" 27.Dd May 18, 2024 28.Dt LOCK 9 29.Os 30.Sh NAME 31.Nm lockinit , 32.Nm lockdestroy , 33.Nm lockmgr , 34.Nm lockmgr_args , 35.Nm lockmgr_args_rw , 36.Nm lockmgr_disown , 37.Nm lockmgr_printinfo , 38.Nm lockmgr_recursed , 39.Nm lockmgr_rw , 40.Nm lockstatus , 41.Nm lockmgr_assert 42.Nd "lockmgr family of functions" 43.Sh SYNOPSIS 44.In sys/types.h 45.In sys/lock.h 46.In sys/lockmgr.h 47.Ft void 48.Fn lockinit "struct lock *lkp" "int prio" "const char *wmesg" "int timo" "int flags" 49.Ft void 50.Fn lockdestroy "struct lock *lkp" 51.Ft int 52.Fn lockmgr "struct lock *lkp" "u_int flags" "struct mtx *ilk" 53.Ft int 54.Fn lockmgr_args "struct lock *lkp" "u_int flags" "struct mtx *ilk" "const char *wmesg" "int prio" "int timo" 55.Ft int 56.Fn lockmgr_args_rw "struct lock *lkp" "u_int flags" "struct rwlock *ilk" "const char *wmesg" "int prio" "int timo" 57.Ft void 58.Fn lockmgr_disown "struct lock *lkp" 59.Ft void 60.Fn lockmgr_printinfo "const struct lock *lkp" 61.Ft int 62.Fn lockmgr_recursed "const struct lock *lkp" 63.Ft int 64.Fn lockmgr_rw "struct lock *lkp" "u_int flags" "struct rwlock *ilk" 65.Ft int 66.Fn lockstatus "const struct lock *lkp" 67.Pp 68.Cd "options INVARIANTS" 69.Cd "options INVARIANT_SUPPORT" 70.Ft void 71.Fn lockmgr_assert "const struct lock *lkp" "int what" 72.Sh DESCRIPTION 73The 74.Fn lockinit 75function is used to initialize a lock. 76It must be called before any operation can be performed on a lock. 77Its arguments are: 78.Bl -tag -width ".Fa wmesg" 79.It Fa lkp 80A pointer to the lock to initialize. 81.It Fa prio 82The priority passed to 83.Xr sleep 9 . 84.It Fa wmesg 85The lock message. 86This is used for both debugging output and 87.Xr sleep 9 . 88.It Fa timo 89The timeout value passed to 90.Xr sleep 9 . 91.It Fa flags 92The flags the lock is to be initialized with: 93.Bl -tag -width ".Dv LK_CANRECURSE" 94.It Dv LK_CANRECURSE 95Allow recursive exclusive locks. 96.It Dv LK_NOPROFILE 97Disable lock profiling for this lock. 98.It Dv LK_NOSHARE 99Allow exclusive locks only. 100.It Dv LK_NOWITNESS 101Instruct 102.Xr witness 4 103to ignore this lock. 104.It Dv LK_NODUP 105.Xr witness 4 106should log messages about duplicate locks being acquired. 107.It Dv LK_QUIET 108Disable 109.Xr ktr 4 110logging for this lock. 111.El 112.El 113.Pp 114The 115.Fn lockdestroy 116function is used to destroy a lock, and while it is called in a number of 117places in the kernel, it currently does nothing. 118.Pp 119The 120.Fn lockmgr 121and 122.Fn lockmgr_rw 123functions handle general locking functionality within the kernel, including 124support for shared and exclusive locks, and recursion. 125.Fn lockmgr 126and 127.Fn lockmgr_rw 128are also able to upgrade and downgrade locks. 129.Pp 130Their arguments are: 131.Bl -tag -width ".Fa flags" 132.It Fa lkp 133A pointer to the lock to manipulate. 134.It Fa flags 135Flags indicating what action is to be taken. 136.Bl -tag -width ".Dv LK_NODDLKTREAT" 137.It Dv LK_SHARED 138Acquire a shared lock. 139If an exclusive lock is currently held, 140.Dv EDEADLK 141will be returned. 142.It Dv LK_EXCLUSIVE 143Acquire an exclusive lock. 144If an exclusive lock is already held, and 145.Dv LK_CANRECURSE 146is not set, the system will 147.Xr panic 9 . 148.It Dv LK_DOWNGRADE 149Downgrade exclusive lock to a shared lock. 150Downgrading a shared lock is not permitted. 151If an exclusive lock has been recursed, the system will 152.Xr panic 9 . 153.It Dv LK_UPGRADE 154Upgrade a shared lock to an exclusive lock. 155If this call fails, the shared lock is lost, even if the 156.Dv LK_NOWAIT 157flag is specified. 158During the upgrade, the shared lock could 159be temporarily dropped. 160Attempts to upgrade an exclusive lock will cause a 161.Xr panic 9 . 162.It Dv LK_TRYUPGRADE 163Try to upgrade a shared lock to an exclusive lock. 164The failure to upgrade does not result in the dropping 165of the shared lock ownership. 166.It Dv LK_RELEASE 167Release the lock. 168Releasing a lock that is not held can cause a 169.Xr panic 9 . 170.It Dv LK_DRAIN 171Wait for all activity on the lock to end, then mark it decommissioned. 172This is used before freeing a lock that is part of a piece of memory that is 173about to be freed. 174(As documented in 175.In sys/lockmgr.h . ) 176.It Dv LK_SLEEPFAIL 177Fail if operation has slept. 178.It Dv LK_NOWAIT 179Do not allow the call to sleep. 180This can be used to test the lock. 181.It Dv LK_TIMELOCK 182Use 183.Fa timo 184during a sleep; otherwise, 0 is used. 185.It Dv LK_NOWITNESS 186Skip the 187.Xr witness 4 188checks for this instance. 189.It Dv LK_CANRECURSE 190Allow recursion on an exclusive lock. 191For every lock there must be a release. 192.It Dv LK_INTERLOCK 193Unlock the interlock (which should be locked already). 194.It Dv LK_NODDLKTREAT 195Normally, 196.Fn lockmgr 197postpones serving further shared requests for shared-locked lock if there is 198exclusive waiter, to avoid exclusive lock starvation. 199But, if the thread requesting the shared lock already owns a shared lockmgr 200lock, the request is granted even in presence of the parallel exclusive lock 201request, which is done to avoid deadlocks with recursive shared acquisition. 202.Pp 203The 204.Dv LK_NODDLKTREAT 205flag can only be used by code which requests shared non-recursive lock. 206The flag allows exclusive requests to preempt the current shared request 207even if the current thread owns shared locks. 208This is safe since shared lock is guaranteed to not recurse, and is used 209when thread is known to held unrelated shared locks, to not cause 210unnecessary starvation. 211An example is 212.Dv vp 213locking in VFS 214.Xr lookup 9 , 215when 216.Dv dvp 217is already locked. 218.El 219.It Fa ilk 220An interlock mutex for controlling group access to the lock. 221If 222.Dv LK_INTERLOCK 223is specified, 224.Fn lockmgr 225and 226.Fn lockmgr_rw 227assume 228.Fa ilk 229is currently owned and not recursed, and will return it unlocked. 230See 231.Xr mtx_assert 9 . 232.El 233.Pp 234The 235.Fn lockmgr_args 236and 237.Fn lockmgr_args_rw 238function work like 239.Fn lockmgr 240and 241.Fn lockmgr_rw 242but accepting a 243.Fa wmesg , 244.Fa timo 245and 246.Fa prio 247on a per-instance basis. 248The specified values will override the default 249ones, but this can still be used passing, respectively, 250.Dv LK_WMESG_DEFAULT , 251.Dv LK_PRIO_DEFAULT 252and 253.Dv LK_TIMO_DEFAULT . 254.Pp 255The 256.Fn lockmgr_disown 257function switches the owner from the current thread to be 258.Dv LK_KERNPROC , 259if the lock is already held. 260.Pp 261The 262.Fn lockmgr_printinfo 263function prints debugging information about the lock. 264It is used primarily by 265.Xr VOP_PRINT 9 266functions. 267.Pp 268The 269.Fn lockmgr_recursed 270function returns true if the lock is recursed, 0 271otherwise. 272.Pp 273The 274.Fn lockstatus 275function returns the status of the lock in relation to the current thread. 276.Pp 277When compiled with 278.Cd "options INVARIANTS" 279and 280.Cd "options INVARIANT_SUPPORT" , 281the 282.Fn lockmgr_assert 283function tests 284.Fa lkp 285for the assertions specified in 286.Fa what , 287and panics if they are not met. 288One of the following assertions must be specified: 289.Bl -tag -width ".Dv KA_UNLOCKED" 290.It Dv KA_LOCKED 291Assert that the current thread has either a shared or an exclusive lock on the 292.Vt lkp 293lock pointed to by the first argument. 294.It Dv KA_SLOCKED 295Assert that the current thread has a shared lock on the 296.Vt lkp 297lock pointed to by the first argument. 298.It Dv KA_XLOCKED 299Assert that the current thread has an exclusive lock on the 300.Vt lkp 301lock pointed to by the first argument. 302.It Dv KA_UNLOCKED 303Assert that the current thread has no lock on the 304.Vt lkp 305lock pointed to by the first argument. 306.El 307.Pp 308In addition, one of the following optional assertions can be used with 309either an 310.Dv KA_LOCKED , 311.Dv KA_SLOCKED , 312or 313.Dv KA_XLOCKED 314assertion: 315.Bl -tag -width ".Dv KA_NOTRECURSED" 316.It Dv KA_RECURSED 317Assert that the current thread has a recursed lock on 318.Fa lkp . 319.It Dv KA_NOTRECURSED 320Assert that the current thread does not have a recursed lock on 321.Fa lkp . 322.El 323.Sh RETURN VALUES 324The 325.Fn lockmgr 326and 327.Fn lockmgr_rw 328functions return 0 on success and non-zero on failure. 329.Pp 330The 331.Fn lockstatus 332function returns: 333.Bl -tag -width ".Dv LK_EXCLUSIVE" 334.It Dv LK_EXCLUSIVE 335An exclusive lock is held by the current thread. 336.It Dv LK_EXCLOTHER 337An exclusive lock is held by someone other than the current thread. 338.It Dv LK_SHARED 339A shared lock is held. 340.It Li 0 341The lock is not held by anyone. 342.El 343.Sh ERRORS 344.Fn lockmgr 345and 346.Fn lockmgr_rw 347fail if: 348.Bl -tag -width Er 349.It Bq Er EBUSY 350.Dv LK_FORCEUPGRADE 351was requested and another thread had already requested a lock upgrade. 352.It Bq Er EBUSY 353.Dv LK_NOWAIT 354was set, and a sleep would have been required, or 355.Dv LK_TRYUPGRADE 356operation was not able to upgrade the lock. 357.It Bq Er ENOLCK 358.Dv LK_SLEEPFAIL 359was set and 360.Fn lockmgr 361or 362.Fn lockmgr_rw 363did sleep. 364.It Bq Er EINTR 365.Dv PCATCH 366was set in the lock priority, and a signal was delivered during a sleep. 367Note the 368.Er ERESTART 369error below. 370.It Bq Er ERESTART 371.Dv PCATCH 372was set in the lock priority, a signal was delivered during a sleep, 373and the system call is to be restarted. 374.It Bq Er EWOULDBLOCK 375a non-zero timeout was given, and the timeout expired. 376.El 377.Sh LOCKS 378If 379.Dv LK_INTERLOCK 380is passed in the 381.Fa flags 382argument to 383.Fn lockmgr 384or 385.Fn lockmgr_rw , 386the 387.Fa ilk 388must be held prior to calling 389.Fn lockmgr 390or 391.Fn lockmgr_rw , 392and will be returned unlocked. 393.Pp 394Upgrade attempts that fail result in the loss of the lock that 395is currently held. 396Also, it is invalid to upgrade an 397exclusive lock, and a 398.Xr panic 9 399will be the result of trying. 400.Sh SEE ALSO 401.Xr condvar 9 , 402.Xr locking 9 , 403.Xr mtx_assert 9 , 404.Xr mutex 9 , 405.Xr panic 9 , 406.Xr rwlock 9 , 407.Xr sleep 9 , 408.Xr sx 9 , 409.Xr VOP_PRINT 9 410.Sh AUTHORS 411This manual page was written by 412.An Chad David Aq Mt davidc@acns.ab.ca . 413