Understanding the concurrency of contexts
Mainly, there are three types of contexts that any Linux kernel code runs.
- Hardware interrupt context (aka top half): Hardware interrupt handler that does not have any relation with current process. in_irq() is true.
- Software interrupt context (aka bottom half): Deferred handler such as softirq, tasklet, bottom half, timer, etc. in_softirq() is true.
- User context (aka process context): Code runs in the context of kernel mode or user mode processes. in_interrupt() is false.
The term 'interrupt context' is used for both hardware interrupt context and software interrupt context. In this context, in_interrupt() returns true.
Hardware interrupt context
When an interrupt happens, the kernel calls appropriate interrupt handler. While doing this, the kernel disables the interrupt line that is is serving. Thus the same interrupt handler is not executed simultaneously, also the interrupt handler cannot be nested.
- An interrupt handler does not run simultaneously in multi-processor environment.
- An interrupt handler is not reentrant.
- An interrupt handler can be preempted by other interrupt handler.
- Different interrupt handlers may run simultaneously.
In the interrupt context, the codes do not run on behalf of current process,
Software interrupt context
Software interrupt is a way to defer jobs out of hardware interrupt context. The hardware interrupt handler defers a job, and the kernel starts running the jobs after it exits the hardware interrupt handler. In general, there are three types of software interrupt.
- Softirqs: Softirqs are fundamental primitive that implements deferred handling. Each processors has a kernel thread that runs softirq handlers, and if any softirqs are pending, the CPU runs the handler whenever it exits the hardware interrupt handler. Same softirq handler can run on multiple processors at the same time.
- Tasklets: Tasklets are built on top of Softirqs. The difference between softirqs and tasklets is that tasklets of different types can run concurrently on several CPUs, but tasklets of the same type cannot. Thus the synchronization inside the tasklet handler becomes simpler than softirq handler.
- Bottom-half: This is traditional deferred call mechanism that was used long time ago, and it should not be used any more. The reason it needs to be avoided is that, any bottom half handlers can not run concurrently on multiple processors. Bottom halves were statically allocated in the kernel.
Hardware interrupt handlers
If a data structure is used by only one interrupt handler, it does not need protection.
If a data structure is accessed by multiple interrupt handlers, it needs protection.
- Use spin_lock_irq() variant.
Hardware interrupt and software interrupt
A hardware interrupt handler is not preempted by software interrupt handler in UP. However, they may run simultaneously in SMP.