In this lesson, you will learn how the Linux kernel maintains system responsiveness by splitting interrupt processing into two distinct phases.
The Interrupt Dilemma
When hardware triggers an interrupt (IRQ), the CPU stops its current task to execute an Interrupt Service Routine (ISR). To keep the system stable and responsive, the ISR must execute as quickly as possible. If the CPU spends too much time inside an ISR, other hardware interrupts may be missed, or the system may appear to "freeze."
To solve this, the kernel divides interrupt processing into two parts:
- Top Half: The actual ISR. It performs only the strictly time-critical tasks, such as acknowledging the hardware and moving data to a buffer. It then schedules the second half to run later.
- Bottom Half: This section handles the more complex, time-consuming processing that doesn't need to happen within the immediate hardware context.
Tasklets: The Bottom Half Mechanism
A tasklet is a common mechanism used to implement the "bottom half." Once the top half finishes, it marks a tasklet as "pending." The kernel then executes the tasklet at a safer, later time when the system is not actively blocking other interrupts.
Tasklets have a unique property: they are guaranteed to run in atomic context, meaning they cannot sleep, cannot access user-space memory, and are strictly serialized. If you have multiple CPUs, a specific tasklet will only ever execute on one CPU at a time, which simplifies your synchronization logic.
Conceptual Implementation
A driver typically schedules a tasklet after the ISR has captured the urgent data:
/* The function to run as the bottom half */
void my_tasklet_handler(unsigned long data) {
/* Perform heavy processing here */
}
/* Define the tasklet */
DECLARE_TASKLET(my_tasklet, my_tasklet_handler, 0);
/* Inside the top half (ISR) */
tasklet_schedule(&my_tasklet);
By offloading the heavy lifting to a tasklet, the ISR can exit almost immediately, allowing the kernel to resume high-priority tasks and re-enable local interrupts, ensuring that your system remains performant even under heavy hardware load.
Key Takeaway: Bottom halves allow the kernel to keep the system responsive by offloading time-consuming data processing from the immediate hardware interrupt routine to a scheduled tasklet.