FreeBSD Man Pages

SPL(9) FreeBSD Kernel Developer's Manual SPL(9)
NAMEsplbio, splclock, splhigh, splimp, splnet, splsoftclock, splsofttty,
splstatclock, spltty, splvm, spl0, splx -- manipulate interrupt priori-
ties
SYNOPSIS#include <sys/types.h>
#include <sys/systm.h>
intrmask_tsplbio(void);
intrmask_tsplclock(void);
intrmask_tsplhigh(void);
intrmask_tsplimp(void);
intrmask_tsplnet(void);
intrmask_tsplsoftclock(void);
intrmask_tsplsofttty(void);
intrmask_tsplstatclock(void);
intrmask_tspltty(void);
voidspl0(void);
voidsplx(intrmask_tipl);
DESCRIPTIONThisAPIisdeprecated.Usemutexestoprotectdatastructuresinstead.See mutex(9) formoreinformation.TheAPIisnowacompleteNOP.ThismanpagedocumentshistoricalbehaviorsoyoucanunderstandthecodelockingthatthespldidwhenconvertingcodefromversionsofthekernelpriortoFreeBSD5.0.TheexamplesinthismanpagearealsoobsoleteandshouldnotbeviewedasdocumentingFreeBSD5.0andnewer.
The spl() function family sets the interrupt priority ``level'' of the
CPU. This prevents interrupt handlers of the blocked priority level from
being run. This is used in the ``synchronous'' part of a driver (the
part that runs on behalf of the user process) to examine or modify data
areas that might be examined or modified by interrupt handlers.
Each driver that uses interrupts is normally assigned to an interrupt
priority group by a keyword in its config line. For example:
device foo0 at isa? port 0x0815 irq 12 tty
assigns interrupt 12 to the ``tty'' priority group. The system automati-
cally arranges for interrupts in the xxx group to be called at a priority
>= splxxx()
The function splx() sets the interrupt priority to an absolute value.
The intent is that the value returned by the other functions should be
saved in a local variable, and later passed to splx() in order to restore
the previous priority.
The function spl0() lowers the priority to a value where all interrupt
handlers are unblocked, but ASTs (asynchronous system traps) remain
blocked until the system is about to return to user mode.
The traditional assignment of the various device drivers to the interrupt
priority groups can be roughly classified as:
splnet() Software part of the network interface drivers.
splimp() All network interface drivers.
splbio() All bufferedIO (i.e., disk and the like) drivers.
spltty() Basically, all non-network communications devices, but
effectively used for all drivers that are neither net-
work nor disks.
RETURN VALUES
All functions except splx() and spl0() return the previous priority
value.
EXAMPLES
This is a typical example demonstrating the usage:
struct foo_softc {
...
int flags;
#define FOO_ASLEEP 1
#define FOO_READY 2
} foo_softc[NFOO];
int
foowrite(...)
{
struct foo_softc *sc;
int s, error;
...
s = spltty();
if (!(sc->flags & FOO_READY)) {
/* Not ready, must sleep on resource. */
sc->flags |= FOO_ASLEEP;
error = tsleep(sc, PZERO, "foordy", 0);
sc->flags &= ~FOO_ASLEEP;
}
sc->flags &= ~FOO_READY;
splx(s);
...
}
void
foointr(...)
{
struct foo_softc *sc;
...
sc->flags |= FOO_READY;
if (sc->flags & FOO_ASLEEP)
/* Somebody was waiting for us, awake him. */
wakeup(sc);
...
}
Note that the interrupt handler should never reduce the priority level.
It is automatically called as it had raised the interrupt priority to its
own level, i.e., further interrupts of the same group are being blocked.
HISTORY
The interrupt priority levels appeared in a very early version of UNIX.
They have been traditionally known by number instead of by names, and
were inclusive up to higher priority levels (i.e., priority 5 has been
blocking everything up to level 5). This is no longer the case in
FreeBSD. The traditional name `level' for them is still reflected in the
letter `l' of the respective functions and variables, although they are
not really levels anymore, but rather different (partially inclusive)
sets of functions to be blocked during some periods of the life of the
system. The historical number scheme can be considered as a simple lin-
early ordered set of interrupt priority groups.
FreeBSD 5.0 eliminated spl entirely in favor of locking primitives which
scale to more than one processor.
AUTHORS
This manual page was written by Jorg Wunsch.
FreeBSD 10.2 July 21, 1996 FreeBSD 10.2