summaryrefslogtreecommitdiff
path: root/static/netbsd/man9/KERNEL_LOCK.9
diff options
context:
space:
mode:
authorJacob McDonnell <jacob@jacobmcdonnell.com>2026-04-25 15:32:58 -0400
committerJacob McDonnell <jacob@jacobmcdonnell.com>2026-04-25 15:32:58 -0400
commit5cb84ec742fd33f78c8022863fadaa8d0d93e176 (patch)
tree1a81ca3665e6153923e40db7b0d988f8573ab59c /static/netbsd/man9/KERNEL_LOCK.9
parenta59214f344567c037d5776879bcfc5fcc1d4d5f6 (diff)
feat: Added NetBSD man pages
Diffstat (limited to 'static/netbsd/man9/KERNEL_LOCK.9')
-rw-r--r--static/netbsd/man9/KERNEL_LOCK.9312
1 files changed, 312 insertions, 0 deletions
diff --git a/static/netbsd/man9/KERNEL_LOCK.9 b/static/netbsd/man9/KERNEL_LOCK.9
new file mode 100644
index 00000000..fca083ff
--- /dev/null
+++ b/static/netbsd/man9/KERNEL_LOCK.9
@@ -0,0 +1,312 @@
+.\" $NetBSD: KERNEL_LOCK.9,v 1.2 2022/02/15 22:58:25 wiz Exp $
+.\"
+.\" Copyright (c) 2022 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd February 13, 2022
+.Dt KERNEL_LOCK 9
+.Os
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.Sh NAME
+.Nm KERNEL_LOCK
+.Nd compatibility with legacy uniprocessor code
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.Sh SYNOPSIS
+.In sys/systm.h
+.\"
+.Ft void
+.Fn KERNEL_LOCK "int nlocks" "struct lwp *l"
+.Ft void
+.Fn KERNEL_UNLOCK_ONE "struct lwp *l"
+.Ft void
+.Fn KERNEL_UNLOCK_ALL "struct lwp *l" "int *nlocksp"
+.Ft void
+.Fn KERNEL_UNLOCK_LAST "struct lwp *l"
+.Ft bool
+.Fn KERNEL_LOCKED_P
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.Sh DESCRIPTION
+The
+.Nm
+facility serves to gradually transition software from the kernel's
+legacy uniprocessor execution model, where the kernel runs on only a
+single CPU and never in parallel on multiple CPUs, to a multiprocessor
+system.
+.Pp
+.Sy New code should not use Nm .
+.Nm
+is meant only for gradual transition of
+.Nx
+to natively MP-safe code, which uses
+.Xr mutex 9
+or other
+.Xr locking 9
+facilities to synchronize between threads and interrupt handlers.
+Use of
+.Nm
+hurts system performance and responsiveness.
+This man page exists only to document the legacy API in order to make
+it easier to transition away from.
+.Pp
+The kernel lock, sometimes also known as
+.Sq giant lock
+or
+.Sq big lock ,
+is a recursive exclusive spin-lock that can be held by a CPU at any
+interrupt priority level and is dropped while sleeping.
+This means:
+.Bl -tag -width "held by a CPU"
+.It recursive
+If a CPU already holds the kernel lock, it can be acquired again and
+again, as long as it is released an equal number of times.
+.It exclusive
+Only one CPU at a time can hold the kernel lock.
+.It spin-lock
+When one CPU holds the kernel lock and another CPU wants to hold it,
+the second CPU
+.Sq spins ,
+i.e., repeatedly executes instructions to see if the kernel lock is
+available yet, until the first CPU releases it.
+During this time, no other threads can run on the spinning CPU.
+.Pp
+This means holding the kernel lock for long periods of time, such as
+nontrivial computation, must be avoided.
+Under
+.Dv LOCKDEBUG
+kernels, holding the kernel lock for too long can lead to
+.Sq spinout
+crashes.
+.It held by a CPU
+The kernel lock is held by a CPU, not by a process, kthread, LWP, or
+interrupt handler.
+It may be shared by a kthread LWP and several softint LWPs at the same
+time, for example, if the softints interrupted the thread on a CPU.
+.It any interrupt priority level
+The kernel lock
+.Em does not
+block interrupts; subsystems running with the kernel lock use
+.Xr spl 9
+to synchronize with interrupt handlers.
+.Pp
+Interrupt handlers that are not marked MP-safe are always run with the
+kernel lock.
+If the interrupt arrives on a CPU where the kernel lock is already
+held, it is simply taken again recursively on interrupt entry and
+released to its original recursion depth on interrupt exit.
+.It dropped while sleeping
+Any time the kernel sleeps to let other threads run, for any reason
+including
+.Xr tsleep 9
+or
+.Xr condvar 9
+or even adaptive
+.Xr mutex 9
+locks, it releases the kernel lock before going to sleep and then
+reacquires it afterward.
+.Pp
+This means, for instance, that although data structures accessed only
+under the kernel lock won't be changed before the sleep, they may be
+changed by another thread during the sleep.
+For example, the following program may crash on an assertion failure
+because the sleep in
+.Xr mutex_enter 9
+can allow another CPU to run and change the global variable
+.Dv x :
+.Bd -literal
+ KERNEL_LOCK(1, NULL);
+ x = 42;
+ mutex_enter(...);
+ ...
+ mutex_exit(...);
+ KASSERT(x == 42);
+ KERNEL_UNLOCK_ONE(NULL);
+.Ed
+.Pp
+This means simply introducing calls to
+.Xr mutex_enter 9
+and
+.Xr mutex_exit 9
+can break kernel-locked assumptions.
+Subsystems need to be consistently converted from
+.Nm
+and
+.Xr spl 9
+to
+.Xr mutex 9 ,
+.Xr condvar 9 ,
+etc.; mixing
+.Xr mutex 9
+and
+.Nm
+usually doesn't work.
+.El
+.Pp
+Holding the kernel lock
+.Em does not
+prevent other code from running on other CPUs at the same time.
+It only prevents other
+.Em kernel-locked
+code from running on other CPUs at the same time.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.Sh FUNCTIONS
+.Bl -tag -width abcd
+.It Fn KERNEL_LOCK nlocks l
+Acquire
+.Fa nlocks
+recursive levels of kernel lock.
+.Pp
+If the kernel lock is already held by another CPU, spins until it can
+be acquired by this one.
+If the kernel lock is already held by this CPU, records the kernel
+lock recursion depth and returns immediately.
+.Pp
+Most of the time
+.Fa nlocks
+is 1, but code that deliberately releases all of the kernel locks held
+by the current CPU in order to sleep and later reacquire the same
+number of kernel locks will pass a value of
+.Fa nlocks
+obtained from
+.Fn KERNEL_UNLOCK_ALL .
+.It Fn KERNEL_UNLOCK_ONE l
+Release one level of the kernel lock.
+Equivalent to
+.Fo KERNEL_UNLOCK
+.Li 1 ,
+.Fa l ,
+.Dv NULL
+.Fc .
+.It Fn KERNEL_UNLOCK_ALL l nlocksp
+Store the kernel lock recursion depth at
+.Fa nlocksp
+and release all recursive levels of the kernel lock.
+.Pp
+This is often used inside logic implementing sleep, around a call to
+.Xr mi_switch 9 ,
+so that the same number of recursive kernel locks can be reacquired
+afterward once the thread is reawoken:
+.Bd -literal
+ int nlocks;
+
+ KERNEL_UNLOCK_ALL(l, &nlocks);
+ ... mi_switch(l) ...
+ KERNEL_LOCK(nlocks, l);
+.Ed
+.It Fn KERNEL_UNLOCK_LAST l
+Release the kernel lock, which must be held at exactly one level.
+.Pp
+This is normally used at the end of a non-MP-safe thread, which was
+known to have started with exactly one level of the kernel lock, and is
+now about to exit.
+.It Fn KERNEL_LOCKED_P
+True if the kernel lock is held.
+.Pp
+To be used only in diagnostic assertions with
+.Xr KASSERT 9 .
+.El
+.Pp
+The legacy argument
+.Fa l
+must be
+.Dv NULL
+or
+.Dv curlwp ,
+which mean the same thing.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.Sh NOTES
+Some
+.Nx
+kernel abstractions execute caller-specified functions with the kernel
+lock held by default, for compatibility with legacy code, but can be
+explicitly instructed
+.Em not
+to hold the kernel lock by passing an MP-safe flag:
+.Bl -bullet
+.It
+.Xr callout 9 ,
+.Dv CALLOUT_MPSAFE
+.It
+.Xr kfilter_register 9
+and
+.Xr knote 9 ,
+.Dv FILTEROPS_MPSAFE
+.It
+.Xr kthread 9 ,
+.Dv KTHREAD_MPSAFE
+.It
+.Xr pci_intr 9 ,
+.Dv PCI_INTR_MPSAFE
+.It
+.Xr scsipi 9 ,
+.Dv SCSIPI_ADAPT_MPSAFE
+.It
+.Xr softint 9 ,
+.Dv SOFTINT_MPSAFE
+.It
+.Xr usbdi 9
+pipes,
+.Dv USBD_MPSAFE
+.It
+.Xr usbdi 9
+tasks,
+.Dv USB_TASKQ_MPSAFE
+.It
+.Xr vnode 9 ,
+.Dv VV_MPSAFE
+.It
+.Xr workqueue 9 ,
+.Dv WQ_MPSAFE
+.El
+.Pp
+The following
+.Nx
+subsystems are still kernel-locked and need re-engineering to take
+advantage of parallelism on multiprocessor systems:
+.Bl -bullet
+.It
+.Xr ata 4 ,
+.Xr atapi 4 ,
+.Xr wd 4
+.It
+.Xr video 4
+.It
+.Xr autoconf 9
+.It
+most of the network stack by default, unless the option
+.Dv NET_MPSAFE
+is enabled
+.It
+.No ...
+.El
+.Pp
+All interrupt handlers at
+.Dv IPL_VM ,
+or lower
+.Pq Xr spl 9
+run with the kernel lock on most ports.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.Sh SEE ALSO
+.Xr locking 9 ,
+.Xr mutex 9 ,
+.Xr spl 9