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 June 21, 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_disowned , 38.Nm lockmgr_lock_flags , 39.Nm lockmgr_printinfo , 40.Nm lockmgr_recursed , 41.Nm lockmgr_rw , 42.Nm lockmgr_slock , 43.Nm lockmgr_unlock , 44.Nm lockmgr_xlock , 45.Nm lockstatus , 46.Nm lockmgr_assert 47.Nd "lockmgr family of functions" 48.Sh SYNOPSIS 49.In sys/types.h 50.In sys/lock.h 51.In sys/lockmgr.h 52.Ft void 53.Fn lockinit "struct lock *lkp" "int prio" "const char *wmesg" "int timo" "int flags" 54.Ft void 55.Fn lockdestroy "struct lock *lkp" 56.Ft int 57.Fn lockmgr "struct lock *lkp" "u_int flags" "struct mtx *ilk" 58.Ft int 59.Fn lockmgr_args "struct lock *lkp" "u_int flags" "struct mtx *ilk" "const char *wmesg" "int prio" "int timo" 60.Ft int 61.Fn lockmgr_args_rw "struct lock *lkp" "u_int flags" "struct rwlock *ilk" "const char *wmesg" "int prio" "int timo" 62.Ft void 63.Fn lockmgr_disown "struct lock *lkp" 64.Ft int 65.Fn lockmgr_disowned "const struct lock *lkp" 66.Ft int 67.Fn lockmgr_lock_flags "struct lock *lkp" "u_int flags" "struct lock_object *ilk" "const char *file" "int line" 68.Ft void 69.Fn lockmgr_printinfo "const struct lock *lkp" 70.Ft int 71.Fn lockmgr_recursed "const struct lock *lkp" 72.Ft int 73.Fn lockmgr_rw "struct lock *lkp" "u_int flags" "struct rwlock *ilk" 74.Ft int 75.Fn lockmgr_slock "struct lock *lkp" "u_int flags" "const char *file" "int line" 76.Ft int 77.Fn lockmgr_unlock "struct lock *lkp" 78.Ft int 79.Fn lockmgr_xlock "struct lock *lkp" "u_int flags" "const char *file" "int line" 80.Ft int 81.Fn lockstatus "const struct lock *lkp" 82.Pp 83.Cd "options INVARIANTS" 84.Cd "options INVARIANT_SUPPORT" 85.Ft void 86.Fn lockmgr_assert "const struct lock *lkp" "int what" 87.Sh DESCRIPTION 88The 89.Fn lockinit 90function is used to initialize a lock. 91It must be called before any operation can be performed on a lock. 92Its arguments are: 93.Bl -tag -width ".Fa wmesg" 94.It Fa lkp 95A pointer to the lock to initialize. 96.It Fa prio 97The priority passed to 98.Xr sleep 9 . 99.It Fa wmesg 100The lock message. 101This is used for both debugging output and 102.Xr sleep 9 . 103.It Fa timo 104The timeout value passed to 105.Xr sleep 9 . 106.It Fa flags 107The flags the lock is to be initialized with: 108.Bl -tag -width ".Dv LK_CANRECURSE" 109.It Dv LK_CANRECURSE 110Allow recursive exclusive locks. 111.It Dv LK_NOPROFILE 112Disable lock profiling for this lock. 113.It Dv LK_NOSHARE 114Allow exclusive locks only. 115.It Dv LK_NOWITNESS 116Instruct 117.Xr witness 4 118to ignore this lock. 119.It Dv LK_NODUP 120.Xr witness 4 121should log messages about duplicate locks being acquired. 122.It Dv LK_QUIET 123Disable 124.Xr ktr 4 125logging for this lock. 126.El 127.El 128.Pp 129The 130.Fn lockdestroy 131function is used to destroy a lock, and while it is called in a number of 132places in the kernel, it currently does nothing. 133.Pp 134The 135.Fn lockmgr 136and 137.Fn lockmgr_rw 138functions handle general locking functionality within the kernel, including 139support for shared and exclusive locks, and recursion. 140.Fn lockmgr 141and 142.Fn lockmgr_rw 143are also able to upgrade and downgrade locks. 144.Pp 145Their arguments are: 146.Bl -tag -width ".Fa flags" 147.It Fa lkp 148A pointer to the lock to manipulate. 149.It Fa flags 150Flags indicating what action is to be taken. 151.Bl -tag -width ".Dv LK_NODDLKTREAT" 152.It Dv LK_SHARED 153Acquire a shared lock. 154If an exclusive lock is currently held, 155.Dv EDEADLK 156will be returned. 157.It Dv LK_EXCLUSIVE 158Acquire an exclusive lock. 159If an exclusive lock is already held, and 160.Dv LK_CANRECURSE 161is not set, the system will 162.Xr panic 9 . 163.It Dv LK_DOWNGRADE 164Downgrade exclusive lock to a shared lock. 165Downgrading a shared lock is not permitted. 166If an exclusive lock has been recursed, the system will 167.Xr panic 9 . 168.It Dv LK_UPGRADE 169Upgrade a shared lock to an exclusive lock. 170If this call fails, the shared lock is lost, even if the 171.Dv LK_NOWAIT 172flag is specified. 173During the upgrade, the shared lock could 174be temporarily dropped. 175Attempts to upgrade an exclusive lock will cause a 176.Xr panic 9 . 177.It Dv LK_TRYUPGRADE 178Try to upgrade a shared lock to an exclusive lock. 179The failure to upgrade does not result in the dropping 180of the shared lock ownership. 181.It Dv LK_RELEASE 182Release the lock. 183Releasing a lock that is not held can cause a 184.Xr panic 9 . 185.It Dv LK_DRAIN 186Wait for all activity on the lock to end, then mark it decommissioned. 187This is used before freeing a lock that is part of a piece of memory that is 188about to be freed. 189(As documented in 190.In sys/lockmgr.h . ) 191.It Dv LK_SLEEPFAIL 192Fail if operation has slept. 193.It Dv LK_NOWAIT 194Do not allow the call to sleep. 195This can be used to test the lock. 196.It Dv LK_TIMELOCK 197Use 198.Fa timo 199during a sleep; otherwise, 0 is used. 200.It Dv LK_NOWITNESS 201Skip the 202.Xr witness 4 203checks for this instance. 204.It Dv LK_CANRECURSE 205Allow recursion on an exclusive lock. 206For every lock there must be a release. 207.It Dv LK_INTERLOCK 208Unlock the interlock (which should be locked already). 209.It Dv LK_NODDLKTREAT 210Normally, 211.Fn lockmgr 212postpones serving further shared requests for shared-locked lock if there is 213exclusive waiter, to avoid exclusive lock starvation. 214But, if the thread requesting the shared lock already owns a shared lockmgr 215lock, the request is granted even in presence of the parallel exclusive lock 216request, which is done to avoid deadlocks with recursive shared acquisition. 217.Pp 218The 219.Dv LK_NODDLKTREAT 220flag can only be used by code which requests shared non-recursive lock. 221The flag allows exclusive requests to preempt the current shared request 222even if the current thread owns shared locks. 223This is safe since shared lock is guaranteed to not recurse, and is used 224when thread is known to held unrelated shared locks, to not cause 225unnecessary starvation. 226An example is 227.Dv vp 228locking in VFS 229.Xr lookup 9 , 230when 231.Dv dvp 232is already locked. 233.El 234.It Fa ilk 235An interlock mutex for controlling group access to the lock. 236If 237.Dv LK_INTERLOCK 238is specified, 239.Fn lockmgr 240and 241.Fn lockmgr_rw 242assume 243.Fa ilk 244is currently owned and not recursed, and will return it unlocked. 245See 246.Xr mtx_assert 9 . 247.El 248.Pp 249The 250.Fn lockmgr_args 251and 252.Fn lockmgr_args_rw 253function work like 254.Fn lockmgr 255and 256.Fn lockmgr_rw 257but accepting a 258.Fa wmesg , 259.Fa timo 260and 261.Fa prio 262on a per-instance basis. 263The specified values will override the default 264ones, but this can still be used passing, respectively, 265.Dv LK_WMESG_DEFAULT , 266.Dv LK_PRIO_DEFAULT 267and 268.Dv LK_TIMO_DEFAULT . 269.Pp 270The 271.Fn lockmgr_lock_flags 272function works like 273.Fn lockmgr 274but accepts explicit 275.Fa file 276and 277.Fa line 278arguments for lock tracing. 279.Pp 280The 281.Fn lockmgr_slock , 282.Fn lockmgr_xlock , 283and 284.Fn lockmgr_unlock 285functions are lightweight entry points that function like 286.Fn lockmgr 287for the 288.Dv LK_SHARED , 289.Dv LK_EXCLUSIVE , 290and 291.Dv LK_RELEASE 292operations respectively. 293They provide functionality similar to 294.Xr sx 9 295locks in that none of the additional 296.Xr lockmgr 9 297features are supported. 298Specifically, these functions do not support unlocking interlocks, the 299.Dv LK_SLEEPFAIL 300flag, or locks with shared locking disabled via 301.Dv LK_NOSHARE . 302They also accept explicit 303.Fa file 304and 305.Fa line 306arguments for lock tracing. 307.Pp 308The 309.Fn lockmgr_disown 310function switches the owner from the current thread to be 311.Dv LK_KERNPROC , 312if the lock is already held. 313.Pp 314The 315.Fn lockmgr_disowned 316function returns true or false according to whether the lock is held by 317.Dv LK_KERNPROC . 318.Pp 319The 320.Fn lockmgr_printinfo 321function prints debugging information about the lock. 322It is used primarily by 323.Xr VOP_PRINT 9 324functions. 325.Pp 326The 327.Fn lockmgr_recursed 328function returns true if the lock is recursed, 0 329otherwise. 330.Pp 331The 332.Fn lockstatus 333function returns the status of the lock in relation to the current thread. 334.Pp 335When compiled with 336.Cd "options INVARIANTS" 337and 338.Cd "options INVARIANT_SUPPORT" , 339the 340.Fn lockmgr_assert 341function tests 342.Fa lkp 343for the assertions specified in 344.Fa what , 345and panics if they are not met. 346One of the following assertions must be specified: 347.Bl -tag -width ".Dv KA_UNLOCKED" 348.It Dv KA_LOCKED 349Assert that the current thread has either a shared or an exclusive lock on the 350.Vt lkp 351lock pointed to by the first argument. 352.It Dv KA_SLOCKED 353Assert that the current thread has a shared lock on the 354.Vt lkp 355lock pointed to by the first argument. 356.It Dv KA_XLOCKED 357Assert that the current thread has an exclusive lock on the 358.Vt lkp 359lock pointed to by the first argument. 360.It Dv KA_UNLOCKED 361Assert that the current thread has no lock on the 362.Vt lkp 363lock pointed to by the first argument. 364.El 365.Pp 366In addition, one of the following optional assertions can be used with 367either an 368.Dv KA_LOCKED , 369.Dv KA_SLOCKED , 370or 371.Dv KA_XLOCKED 372assertion: 373.Bl -tag -width ".Dv KA_NOTRECURSED" 374.It Dv KA_RECURSED 375Assert that the current thread has a recursed lock on 376.Fa lkp . 377.It Dv KA_NOTRECURSED 378Assert that the current thread does not have a recursed lock on 379.Fa lkp . 380.El 381.Sh RETURN VALUES 382The 383.Fn lockmgr 384and 385.Fn lockmgr_rw 386functions return 0 on success and non-zero on failure. 387.Pp 388The 389.Fn lockstatus 390function returns: 391.Bl -tag -width ".Dv LK_EXCLUSIVE" 392.It Dv LK_EXCLUSIVE 393An exclusive lock is held by the current thread. 394.It Dv LK_EXCLOTHER 395An exclusive lock is held by someone other than the current thread. 396.It Dv LK_SHARED 397A shared lock is held. 398.It Li 0 399The lock is not held by anyone. 400.El 401.Sh ERRORS 402.Fn lockmgr 403and 404.Fn lockmgr_rw 405fail if: 406.Bl -tag -width Er 407.It Bq Er EBUSY 408.Dv LK_FORCEUPGRADE 409was requested and another thread had already requested a lock upgrade. 410.It Bq Er EBUSY 411.Dv LK_NOWAIT 412was set, and a sleep would have been required, or 413.Dv LK_TRYUPGRADE 414operation was not able to upgrade the lock. 415.It Bq Er EDEADLK 416A shared lock was attempted while the thread already held the exclusive lock. 417.It Bq Er ENOLCK 418.Dv LK_SLEEPFAIL 419was set and 420.Fn lockmgr 421or 422.Fn lockmgr_rw 423did sleep. 424.It Bq Er EINTR 425.Dv PCATCH 426was set in the lock priority, and a signal was delivered during a sleep. 427Note the 428.Er ERESTART 429error below. 430.It Bq Er ERESTART 431.Dv PCATCH 432was set in the lock priority, a signal was delivered during a sleep, 433and the system call is to be restarted. 434.It Bq Er EWOULDBLOCK 435a non-zero timeout was given, and the timeout expired. 436.El 437.Sh LOCKS 438If 439.Dv LK_INTERLOCK 440is passed in the 441.Fa flags 442argument to 443.Fn lockmgr 444or 445.Fn lockmgr_rw , 446the 447.Fa ilk 448must be held prior to calling 449.Fn lockmgr 450or 451.Fn lockmgr_rw , 452and will be returned unlocked. 453.Pp 454Upgrade attempts that fail result in the loss of the lock that 455is currently held. 456Also, it is invalid to upgrade an 457exclusive lock, and a 458.Xr panic 9 459will be the result of trying. 460.Sh SEE ALSO 461.Xr witness 4 , 462.Xr condvar 9 , 463.Xr locking 9 , 464.Xr mtx_assert 9 , 465.Xr mutex 9 , 466.Xr panic 9 , 467.Xr rwlock 9 , 468.Xr sleep 9 , 469.Xr sx 9 , 470.Xr VOP_PRINT 9 471.Sh AUTHORS 472This manual page was written by 473.An Chad David Aq Mt davidc@acns.ab.ca . 474