Operating-System Kernels

interrupt context versus process context

When code runs inside the kernel, it is always running in one of two 'moods,' and which one decides what that code is allowed to do. Process context means the kernel is running on behalf of a specific process - for example servicing a system call that some program made - so there is a real task behind this work that can legitimately be put to sleep and woken later. Interrupt context (sometimes called atomic context) means the kernel is running because a hardware interrupt fired; there is no friendly process behind it, just a sudden 'handle me now' that hijacked whatever was running.

The practical difference is sharp and worth memorizing. In process context the kernel may sleep: it can block waiting for a lock, call a function that might wait for memory, or do anything that could put the current task to sleep, because there is a task to put to sleep and the scheduler can run something else meanwhile. In interrupt context the kernel must NOT sleep - there is no associated process to suspend, so blocking would freeze the whole CPU with no one to wake up, deadlocking the system. Therefore interrupt-context code can only use non-blocking operations: spinlocks rather than sleeping mutexes, and memory allocations that are told never to wait.

Why this is a load-bearing concept: nearly every kernel rule about 'can I call this here?' reduces to which context you are in. Top-half interrupt handlers and softirqs run in interrupt context (no sleeping); system-call code and workqueue handlers run in process context (sleeping allowed). A huge fraction of beginner kernel bugs come from calling a may-sleep function from interrupt context. The kernel even has a debug check (in_atomic / might_sleep) that screams when code tries to sleep where it must not, precisely because this mistake is so common and so fatal.

process context (syscall handler): mutex_lock(&m); kmalloc(n, GFP_KERNEL); // may sleep -- OK. interrupt context (softirq): spin_lock(&l); kmalloc(n, GFP_ATOMIC); // must NOT sleep -- mutex_lock or GFP_KERNEL here would be a bug.

Process context may sleep (mutex, GFP_KERNEL); interrupt context may not (spinlock, GFP_ATOMIC). The context dictates which calls are legal.

The phrase 'may not sleep' is not a style preference - sleeping in interrupt context can deadlock the machine, because there is no task to suspend and resume. When unsure which context you are in, assume you cannot sleep; the kernel's might_sleep() debug check exists precisely because this error is so easy to make.

Also called
interrupt contextatomic contextprocess context中斷脈絡行程脈絡