Process context
Process context is associated with a task, such as a system call or kernel thread. Code can often sleep, wait for a mutex, and use APIs that may block, provided the surrounding locking and state rules permit it.
Hard interrupt context
A hard IRQ handler runs in response to an interrupt and must finish quickly. It must not sleep or call blocking operations. A common pattern is to acknowledge the interrupt, record essential state, and schedule deferred work.
Softirq, tasklets, and workqueues
Softirq-style bottom halves are intended for deferred work that still has atomic-context restrictions. Workqueues run in worker-thread context and can generally sleep. Threaded IRQs offer another option when the handler needs a sleepable part. The correct mechanism depends on latency, concurrency, and subsystem conventions.
Rules of thumb
- Do not take a mutex from hard IRQ context.
- Do not call a potentially sleeping API from atomic context.
- Use spinlocks only when appropriate for the context and critical section.
- Keep hard IRQ work short; defer expensive processing.
- Check whether an API is IRQ-safe in the target kernel documentation.
How to debug context errors
Warnings such as “sleeping function called from invalid context” often point to a blocking call under a spinlock or from an interrupt handler. Enable relevant kernel debugging options, read the complete stack trace, and identify the first driver frame that violates the context rules.
Kernel execution details evolve. Verify the semantics of the exact kernel version and subsystem you are targeting.
Final takeaway
Low-level engineering is about understanding the contract between hardware, firmware, and the operating system. Start with the specification, form a testable hypothesis, collect evidence, and validate behavior on the target platform.