Bottom Halfs

Bottom-halfs are non-critical portion of interrupt-handlers, i.e. interrupt-handler code that is executed with interrupts enabled. Bottom-halfs can be masked by processes when they access any data shared with bottom-halfs using local_bh_disable, spin_lock_bh, etc. functions.

Though bottom-halfs are a deferred work, in priority they are considered as equal to interrupts. So kernel processes them as quickly as possible. Kernel guarantees to execute all unmasked bottom-halfs on meeting below two conditions:

1. Following the execution of any top-half, after interrupts are enabled.
2. Following any process’s context switch, on a call to schedule(), before another process is scheduled.

Two types of bottom-halfs are supported with different different concurrency semantics.

Softirqs

Bottom-halfs which can be executed on multiple cpus simultaneously, are called softirqs. Softirqs are completely reentrant, which means, softirq code for an interrupt X can be executed on multiple cpus simultaneously.

This concurrency requirement suggest that the device serviced is of very high priority and/or can generate interrupts at a every high rate. Very few devices need this level of interrupt service, so Linux supports only a fixed number of softirqs and which devices belong to this class is decided at compile time.

Tasklets

Tasklets are sufficient to service almost all devices. Tasklets are a type of bottom-halfs which are guaranteed to be executed in serial. When tasklet code for interrupt X is executing on cpu ONE, it will be delayed from execution on other cpus. In fact, as a cache optimization, it is queued to execute on cpu ONE after completion.

There is no limitation on number of tasklets. Device drivers can add or remove tasklets dynamically.

Implementation Notes

Since all interrupt-handlers need not have work as a bottom-half, Linux provides a fixed number of bottom-halfs. After completing any top-half it iterates over all bottom-half slots looking for active (or activated) bottom-halfs and executes them.

One of the bottom-half slot has a reentrant framework which in turn iterates over all registered softirqs and executes the pending softirqs (of course, only when it is not executing on other cpus at that time). This is how tasklets are built on top of softirqs and provide serialization.

Leave a comment