Sync with reality.

This commit is contained in:
ad 2007-12-05 04:47:56 +00:00
parent 96302ffc73
commit be843f3b0a
1 changed files with 123 additions and 177 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: spl.9,v 1.26 2007/02/17 08:44:08 wiz Exp $
.\" $NetBSD: spl.9,v 1.27 2007/12/05 04:47:56 ad Exp $
.\"
.\" Copyright (c) 2000, 2001 Jason R. Thorpe. All rights reserved.
.\" Copyright (c) 1997 Michael Long.
@ -27,72 +27,48 @@
.\" (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 11, 2007
.Dd Decenber 5, 2007
.Dt SPL 9
.Os
.Sh NAME
.Nm spl ,
.Nm spl0 ,
.Nm splaudio ,
.Nm splbio ,
.Nm splclock ,
.Nm splhigh ,
.Nm splvm ,
.Nm spllock ,
.Nm spllowersoftclock ,
.Nm splnet ,
.Nm splsched ,
.Nm splserial ,
.Nm splsoftbio ,
.Nm splsoftclock ,
.Nm splsoftnet ,
.Nm splsoftserial ,
.Nm splstatclock ,
.Nm spltty ,
.Nm splvm ,
.Nm splx
.Nd modify system interrupt priority level
.Sh SYNOPSIS
.In sys/param.h
.Ft int
.Fn splaudio void
.Ft void
.Fn spl0 void
.Ft int
.Fn splhigh void
.Ft int
.Fn spllock void
.Ft int
.Fn splserial void
.Ft int
.Fn splsched void
.Ft int
.Fn splclock void
.Ft int
.Fn splstatclock void
.Ft int
.Fn splvm void
.Ft int
.Fn spltty void
.Fn splsoftbio void
.Ft int
.Fn splsoftclock void
.Ft int
.Fn splsoftserial void
.Ft int
.Fn splnet void
.Ft int
.Fn splbio void
.Ft int
.Fn splsoftnet void
.Ft int
.Fn splsoftclock void
.Ft void
.Fn spllowersoftclock void
.Ft void
.Fn spl0 void
.Ft void
.Fn splx "int s"
.Sh DESCRIPTION
These functions raise and lower the system priority level.
These functions raise and lower the interrupt priority level.
They are used by kernel code to block interrupts in critical
sections, in order to protect data structures (much like
a locking primitive).
sections, in order to protect data structures.
.Pp
In a multi-CPU system, these functions change the interrupt
priority level on the local CPU only.
In general, device drivers should not make use of these interfaces.
To ensure correct synchronization, device drivers should use the
.Xr condvar 9 ,
@ -101,148 +77,125 @@ and
.Xr rwlock 9
interfaces.
.Pp
Interrupt priorities are not arranged in a strict hierarchy, although
interrupt hardware sometimes is.
For this reason the priorities listed here are arranged from
.Dq highest
to
.Dq lowest .
In other words, if a platform's hardware interrupts are arranged in
a hierarchical manner, a priority level should also block all of the
levels listed below it.
Interrupt priorities are arranged in a strict hierarchy, although
sometimes levels may be equivalent (overlap).
The hierarchy means that raising the IPL to any level will block
interrupts at that level, and at all lower levels.
The hierarchy is used to minimize data loss due to interrupts not
being serviced in a timely fashion.
.Pp
Note that a strict hierarchy is not required.
For example,
.Fn splnet
is not required to block disk controller interrupts, as they
do not access the same data structures.
However, the priorities are presented as a hierarchy in order to
minimize data loss due to blocked interrupts, or interrupts not being
serviced in a timely fashion.
.Pp
A
.Nm
function exists for each distinct priority level which can exist in
the system, as well as for some special priority levels that are
designed to be used in conjunction with multiprocessor-safe locking
primitives.
These levels may be divided into two main types: hard and soft.
The levels may be divided into two groups: hard and soft.
Hard interrupts are generated by hardware devices.
Soft interrupts are a way of deferring hardware interrupts to do more
expensive processing at a lower interrupt priority, and are explicitly
scheduled by the higher-level interrupt handler.
The most common use of this is in the networking code, where network
interface drivers defer the more expensive TCP/IP processing in order
to avoid dropping additional incoming packets.
Software interrupts are further described by
.Xr softintr 9 .
.Xr softint 9 .
.Pp
Note that hard interupt handlers do not possess process (thread) context
and so it is not valid to use kernel facilities that may attempt to sleep
from a hardware interrupt.
For example, it is not possible to acquire a reader/writer lock from
a hardware interrupt.
Soft interrupt handlers possess limited process context and so may sleep
briefly in order to acquire a reader/writer lock or adaptive mutex,
but may not sleep for any other reason.
.Pp
In order of highest to lowest priority, the priority-raising functions
are:
.Bl -tag -width splsoftserialXX
.It Fn splhigh
blocks all hard and soft interrupts.
It is used for code that cannot tolerate any interrupts, like hardware
context switching code and the
.Xr ddb 4
in-kernel debugger.
.It Fn spllock
blocks all hard and soft interrupts that can acquire a simple lock.
This is provided as a distinct level from
.Fn splhigh
as some platforms may need to make use of extremely high priority
interrupts while locks are spinning, which would be blocked by
.Fn splhigh .
.It Fn splserial
blocks hard interrupts from serial interfaces (IPL_SERIAL).
Code running at this level may not access the tty subsystem.
along with their counterpart symbolic tags are:
.Bl -tag -width splsoft
.It Fn splhigh , IPL_HIGH
.Pp
Blocks all hard and soft interrupts, including the higest level I/O
interrupts, such as interrupts from serial interfaces and the
statistics clock (if any).
It is also used for code that cannot tolerate any interrupts.
.Pp
Code running at this level may not (in general) directly access
machine indepenent kernel services.
For example, it is illegal to call the kernel
.Fn printf
function or to try and allocate memory.
The methods of synchronization available are: spin mutexes and
scheduling a soft interrupt.
Generally, all code run at this level must schedule additional
processing to run in a software interrupt.
Note that code running at this priority is not blocked by
.Fn splvm
(described below), and is therefore prohibited from using the
kernel memory allocators.
.It Fn splsched
blocks all hard and soft interrupts that may access scheduler data
structures.
Code running at or above this level may not call
.Fn sleep ,
.Fn tsleep ,
.Fn ltsleep ,
or
.Fn wakeup ,
nor may it post signals.
.It Fn splclock
blocks the hardware clock interrupt.
It is used by
.Fn hardclock
to update kernel and process times, and must be used by any other code
that accesses time-related data, specifically the
.Va time
and
.Va mono_time
global variables.
This level also protects the
.Pp
Code with thread context running at this level must not use a kernel
interface that may cause the current LWP to sleep, such as the
.Xr condvar
interfaces.
.Pp
Interrupt handlers at this level cannot acquire the global kernel_lock
and so must be coded to ensure correct synchronization on muliprocessor
systems.
.It Fn splsched , IPL_SCHED
.Pp
Blocks all medium priority hardware interrupts, such as interrupts
from audio devices, and the clock interrupt.
.Pp
Interrupt handlers running at this level endure the same restrictions as
at IPL_HIGH, but may access scheduler interfaces, and so may awaken LWPs
(light weight processes) using the
.Xr condvar 9
interfaces, and may schedule callouts using the
.Xr callout 9
data structures, and nothing running at or above this level may
schedule, cancel, or otherwise access any callout-related data
structures.
.It Fn splstatclock
blocks the hardware statistics clock interrupt.
It is used by
.Fn statclock
to update kernel profiling and other statistics, and must be used by
any code that accesses that data.
This is the clock that drives scheduling.
This level is identical to
.Fn splclock
if there is no separate statistics clock.
.It Fn splvm
blocks hard interrupts from all devices that are allowed to use the
kernel
.Xr malloc 9 ,
or any virtual memory operations.
That includes all disk, network, and tty device interrupts.
The temptation to abuse the semantics of
.Fn splvm
should be avoided; if you feel as if you need to block more than
one class of interrupts at a time, use software interrupts instead.
.It Fn spltty
blocks hard and soft interrupts from TTY devices (IPL_TTY).
This must also block soft serial interrupts.
.It Fn splaudio
blocks hard interrupts generated by audio devices (IPL_AUDIO).
.It Fn splsoftserial
blocks soft interrupts generated by serial devices (IPL_SOFTSERIAL).
.It Fn splnet
blocks hard interrupts from network interfaces (IPL_NET).
.It Fn splbio
blocks hard interrupts from disks and other mass-storage
devices (IPL_BIO).
.It Fn splsoftnet
blocks soft network interrupts (IPL_SOFTNET).
Soft interrupts blocked by this priority are also blocked by all
of the priorities listed above.
.It Fn splsoftclock
blocks soft clock interrupts.
This is the priority at which the
interfaces.
.Pp
Code with thread context running at this level may sleep via the
.Xr condvar
interfaces, and may use other kernel facilities that could cause the
current LWP to sleep.
.It Fn splvm , IPL_VM
.Pp
Blocks hard interrupts from 'low' priority hardware interrupts, such
as interrupts from network, block I/O and tty devices.
.Pp
Code running at this level endures the same restrictions as at IPL_SCHED,
but may use the deprecated
.Xr malloc 9
or endorsed
.Xr pool_cache 9
interfaces to allocate memory.
.Pp
At the time of writing, the global
.Dv kernel_lock
is automatically acquired for interrupts at this level, in order to
support device drivers that do not provide their own multiprocessor
synchronization.
A future release of the system may allow the automatic acquisition of
.Dv kernel_lock
to be disabled for individual interrupt handlers.
.It Fn splsoftserial , IPL_SOFTSERIAL
.Pp
Blocks soft interrupts at the IPL_SOFTSERIAL symbolic level.
.Pp
This is the first of the software levels.
Soft interrupts at this level and lower may acquire reader/writer
locks or adaptive mutexes.
.It Fn splsoftnet , IPL_SOFTNET
.Pp
Blocks soft interrupts at the IPL_SOFTNET symbolic level.
.It Fn splsoftnet , IPL_SOFTBIO
.Pp
Blocks soft interrupts at the IPL_SOFTBIO symbolic level.
.It Fn splsoftnet , IPL_SOFTCLOCK
.Pp
Blocks soft interrupts at the IPL_SOFTCLOCK symbolic level.
.Pp
This is the priority at which callbacks generated by the
.Xr callout 9
facility runs.
Soft interrupts blocked by this priority are also blocked by all
of the priorities listed above.
In particular,
.Fn splsoftnet
must be a higher priority than
.Fn splsoftclock .
.El
.Pp
Two functions lower the system priority level.
They are:
.Bl -tag -width spllowersoftclockXX
.It Fn spllowersoftclock
unblocks all interrupts but the soft clock interrupt.
.It Fn spl0
unblocks all interrupts.
One function lowers the system priority level:
.Bl -tag -width splsoft
.It Fn spl0 , IPL_NONE
.Pp
Unblocks all interrupts.
This should rarely be used directly;
.Fn splx
should be used instead.
.El
.Pp
The
@ -252,20 +205,6 @@ function restores the system priority level to the one encoded in
which must be a value previously returned by one of the other
.Nm
functions.
.Pp
Note that the functions which lower the system priority level
.Po
.Fn spllowersoftclock ,
.Fn spl0 ,
and
.Fn splx
.Pc
do not return a value.
They should only be used in places where the system priority level
is being decreased permanently.
It is inappropriate to attempt to use them where the
system priority level is being decreased temporarily, and would
need to be restored to a previous value before continuing.
.Sh SEE ALSO
.Xr condvar 9 ,
.Xr mutex 9 ,
@ -314,3 +253,10 @@ was replaced by
and code which abused the semantics of
.Fn splimp
was changed to not mix interrupt priority levels.
.Pp
Between
.Nx 4.0
and
.Nx 5.0 ,
the hardware levels were reduced in number and a strict hierarchy
defined.