- NetBSD Manual Pages
SPL(9) NetBSD Kernel Developer's Manual SPL(9)
Powered by man-cgi (2021-06-01).
Maintained for NetBSD
by Kimmo Suominen.
Based on man-cgi by Panagiotis Christias.
spl, spl0, splhigh, splvm, splbio, splnet, spltty, splsched, splsoftbio,
splsoftclock, splsoftnet, splsoftserial, splx -- modify system interrupt
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.
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 driv-
ers should use the condvar(9), mutex(9), and rwlock(9) interfaces.
Interrupt priorities are arranged in a strict hierarchy, although some-
times levels may be equivalent (overlap). The hierarchy means that rais-
ing 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 inter-
rupts not being serviced in a timely fashion.
The levels may be divided into two groups: hard and soft. Hard inter-
rupts 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. Software interrupts are further described by
Note that hard interrupt 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
In order of highest to lowest priority, the priority-raising functions
along with their counterpart symbolic tags are:
Blocks all hard and soft interrupts, including the highest 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.
Code running at this level may not (in general) directly access
machine independent kernel services. For example, it is illegal
to call the kernel printf() function or to try and allocate mem-
ory. 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 soft-
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 condvar(9) interfaces.
Interrupt handlers at this level cannot acquire the global ker-
nel_lock and so must be coded to ensure correct synchronization
on multiprocessor systems.
Blocks all medium priority hardware interrupts, such as inter-
rupts from audio devices, and the clock interrupt.
Interrupt handlers running at this level endure the same
restrictions as at IPL_HIGH, but may access scheduler inter-
faces, and so may awaken LWPs (light weight processes) using the
condvar(9) interfaces, and may schedule callouts using the
Code with thread context running at this level may sleep via the
condvar(9) interfaces, and may use other kernel facilities that
could cause the current LWP to sleep.
Blocks hard interrupts from ``low'' priority hardware inter-
rupts, such as interrupts from network, block I/O and tty
Code running at this level endures the same restrictions as at
IPL_SCHED, but may use the deprecated malloc(9) or endorsed
pool_cache(9) interfaces to allocate memory.
The global kernel_lock is automatically acquired for interrupts
at this level by default, in order to support device drivers
that do not provide their own multiprocessor synchronization.
The automatic acquisition of kernel_lock can be disabled for
individual interrupt handlers by device drivers if supported by
subsystem, see e.g. pci_intr_establish(9).
splbio(), splnet(), and spltty() are synonyms for splvm().
Their use is deprecated; all new code should use splvm().
Blocks soft interrupts at the IPL_SOFTSERIAL symbolic level.
This is the first of the software levels. Soft interrupts at
this level and lower may acquire reader/writer locks or adaptive
Blocks soft interrupts at the IPL_SOFTNET symbolic level.
Blocks soft interrupts at the IPL_SOFTBIO symbolic level.
Blocks soft interrupts at the IPL_SOFTCLOCK symbolic level.
This is the priority at which callbacks generated by the
callout(9) facility runs.
One function lowers the system priority level:
Unblocks all interrupts. This should rarely be used directly;
splx() should be used instead.
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
condvar(9), i386/splraise(9), kpreempt(9), mutex(9), rwlock(9)
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
Between NetBSD 4.0 and NetBSD 5.0, the hardware levels were reduced in
number and a strict hierarchy defined.
NetBSD 9.99 April 7, 2020 NetBSD 9.99