splhigh(9)
- NetBSD Manual Pages
SPL(9) NetBSD Kernel Developer's Manual SPL(9)
NAME
spl, spl0, splaudio, splbio, splclock, splhigh, splvm, spllock,
spllowersoftclock, splnet, splsched, splserial, splsoftclock, splsoftnet,
splsoftserial, splstatclock, spltty, splvm, splx -- modify system inter-
rupt priority level
SYNOPSIS
#include <sys/param.h>
int
splaudio(void);
int
splhigh(void);
int
spllock(void);
int
splserial(void);
int
splsched(void);
int
splclock(void);
int
splstatclock(void);
int
splvm(void);
int
spltty(void);
int
splsoftserial(void);
int
splnet(void);
int
splbio(void);
int
splsoftnet(void);
int
splsoftclock(void);
void
spllowersoftclock(void);
void
spl0(void);
void
splx(int s);
DESCRIPTION
These functions raise and lower the system priority level. They are used
by kernel code to block interrupts in critical sections, in order to pro-
tect data structures (much like a locking primitive) or to ensure unin-
terrupted access to hardware devices which are sensitive to timing.
Interrupt priorities are not arranged in a strict hierarchy, although
interrupt hardware sometimes is. For this reason the priorities listed
here are arranged from ``highest'' to ``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.
Note that a strict hierarchy is not required. For example, 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.
A spl 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. 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 network-
ing code, where network interface drivers defer the more expensive TCP/IP
processing in order to avoid dropping additional incoming packets. Soft-
ware interrupts are further described by softintr(9).
In order of highest to lowest priority, the priority-raising functions
are:
splhigh() blocks all hard and soft interrupts. It is used for
code that cannot tolerate any interrupts, like hardware
context switching code and the ddb(4) in-kernel debug-
ger.
spllock() blocks all hard and soft interrupts that can acquire a
simple lock. This is provided as a distinct level from
splhigh() as some platforms may need to make use of
extremely high priority interrupts while locks are spin-
ning, which would be blocked by splhigh().
splserial() blocks hard interrupts from serial interfaces
(IPL_SERIAL). Code running at this level may not access
the tty subsystem. Generally, all code run at this
level must schedule additional processing to run in a
software interrupt. Note that code running at this pri-
ority is not blocked by splvm() (described below), and
is therefore prohibited from using the kernel memory
allocators.
splsched() blocks all hard and soft interrupts that may access
scheduler data structures. Code running at or above
this level may not call sleep(), tsleep(), ltsleep(), or
wakeup(), nor may it post signals.
splclock() blocks the hardware clock interrupt. It is used by
hardclock() to update kernel and process times, and must
be used by any other code that accesses time-related
data, specifically the time and mono_time global vari-
ables. This level also protects the callout(9) data
structures, and nothing running at or above this level
may schedule, cancel, or otherwise access any callout-
related data structures.
splstatclock() blocks the hardware statistics clock interrupt. It is
used by 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 splclock() if there is no
separate statistics clock.
splvm() blocks hard interrupts from all devices that are allowed
to use the kernel malloc(9), or any virtual memory oper-
ations. That includes all disk, network, and tty device
interrupts. The temptation to abuse the semantics of
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.
spltty() blocks hard and soft interrupts from TTY devices
(IPL_TTY). This must also block soft serial interrupts.
splaudio() blocks hard interrupts generated by audio devices
(IPL_AUDIO).
splsoftserial() blocks soft interrupts generated by serial devices
(IPL_SOFTSERIAL).
splnet() blocks hard interrupts from network interfaces
(IPL_NET).
splbio() blocks hard interrupts from disks and other mass-storage
devices (IPL_BIO).
splsoftnet() blocks soft network interrupts (IPL_SOFTNET). Soft
interrupts blocked by this priority are also blocked by
all of the priorities listed above.
splsoftclock() blocks soft clock interrupts. This is the priority at
which the callout(9) facility runs. Soft interrupts
blocked by this priority are also blocked by all of the
priorities listed above. In particular, splsoftnet()
must be a higher priority than splsoftclock().
Two functions lower the system priority level. They are:
spllowersoftclock() unblocks all interrupts but the soft clock inter-
rupt.
spl0() unblocks all interrupts.
The splx() function restores the system priority level to the one encoded
in s, which must be a value previously returned by one of the other spl
functions.
Note that the functions which lower the system priority level
(spllowersoftclock(), spl0(), and splx()) 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.
HISTORY
In 4.4BSD, splnet() was used to block network software interrupts. Most
device drivers used splimp() to block hardware interrupts. To avoid
unnecessarily blocking other interrupts, in NetBSD 1.1 a new function was
added that blocks only network hardware interrupts. For consistency with
other spl functions, the old splnet() function was renamed to
splsoftnet(), and the new function was named splnet().
Originally, splsoftclock() lowered the system priority level. During the
NetBSD 1.5 development cycle, spllowersoftclock() was introduced and the
semantics of splsoftclock() were changed.
The splimp() call was removed from the kernel between NetBSD 1.5 and
NetBSD 1.6. The function of splimp() was replaced by splvm() and code
which abused the semantics of splimp() was changed to not mix interrupt
priority levels.
NetBSD 4.0.1 September 23, 2006 NetBSD 4.0.1
Powered by man-cgi (2024-03-20).
Maintained for NetBSD
by Kimmo Suominen.
Based on man-cgi by Panagiotis Christias.