Table of Contents
At any time each of the CPUs in a system can be:
not associated with any process, serving a hardware interrupt;
not associated with any process, serving a softirq, tasklet or bh;
running in kernel space, associated with a process;
running a process in user space.
There is a strict ordering between these: other than the last category (userspace) each can only be pre-empted by those above. For example, while a softirq is running on a CPU, no other softirq will pre-empt it, but a hardware interrupt can. However, any other CPUs in the system execute independently.
We'll see a number of ways that the user context can block interrupts, to become truly non-preemptable.
User context is when you are coming in from a system call or
other trap: you can sleep, and you own the CPU (except for
interrupts) until you call schedule()
.
In other words, user context (unlike userspace) is not pre-emptable.
You are always in user context on module load and unload, and on operations on the block device layer.
In user context, the current
pointer (indicating
the task we are currently executing) is valid, and
in_interrupt()
(include/linux/interrupt.h
) is false
.
Beware that if you have interrupts or bottom halves disabled
(see below), in_interrupt()
will return a
false positive.