Deferred Work Selection¶
Deferred execution is a fundamental design technique in Linux drivers.
The primary goal is not simply to delay work, but to move processing from a restricted execution context to a more appropriate execution context.
Typical example:
This allows drivers to perform operations that may sleep, block, or require significant processing time.
Why Deferred Execution Exists¶
Interrupt handlers execute in hard IRQ context.
Hard IRQ context has strict limitations:
- Cannot sleep
- Cannot block
- Cannot wait for events
- Should execute as quickly as possible
For example, the following operations are typically not allowed inside an ISR:
Therefore, Linux drivers commonly move work into a thread context.
Execution Context¶
Hard IRQ Context¶
Examples:
Characteristics:
- Cannot sleep
- Cannot block
- Must return quickly
Typical responsibilities:
- Acknowledge interrupt
- Capture minimal state
- Schedule deferred work
Thread Context¶
Examples:
- Threaded IRQ
- Workqueue worker
- kthread_worker
- Dedicated kthread
Characteristics:
- Can sleep
- Can block
- Can use mutexes
- Can wait for events
Typical responsibilities:
- Register access
- Data processing
- State-machine execution
- Background work
Deferred Execution Mechanisms¶
Linux provides multiple mechanisms for deferred execution.
Threaded IRQ¶
Architecture:
Characteristics:
- Dedicated IRQ thread
- Closely tied to a specific interrupt source
- Supports sleeping operations
Typical use cases:
- I2C sensors
- SPI sensors
- GPIO expanders
Example:
Workqueue¶
Architecture:
Characteristics:
- Shared worker threads
- Low management overhead
- General-purpose deferred execution
Typical use cases:
- Debounce logic
- Background cleanup
- Short deferred work
Example:
kthread_worker¶
Architecture:
Characteristics:
- Dedicated worker thread
- FIFO ordering
- Driver-specific execution context
Typical use cases:
- Touch controllers
- Packet processing
- Ordered event handling
Example:
Dedicated kthread¶
Architecture:
Typical implementation:
Characteristics:
- Full control over execution flow
- Supports state machines
- Supports multiple event sources
Typical use cases:
- WiFi drivers
- Bluetooth drivers
- Modem drivers
- Complex protocol stacks
Producer / Queue / Consumer Model¶
Many Linux drivers follow a common architecture:
Examples:
| Component | Examples |
|---|---|
| Producer | IRQ, Timer, Hardware Event |
| Queue | FIFO, Ring Buffer, Work List |
| Consumer | Workqueue, kthread_worker, kthread |
The deferred execution mechanism often acts as the consumer.
Important Observation¶
A work item is not necessarily an event.
Example:
Multiple interrupts may occur while a worker is already running.
This is often acceptable because:
The worker processes all pending data before exiting.
This prevents event loss even when duplicate work scheduling is suppressed.
Driver Design Patterns¶
GPIO Button¶
Architecture:
Recommended mechanism:
Reason:
- Simple processing
- No state machine
- No dedicated thread required
I2C Sensor¶
Architecture:
Recommended mechanism:
Reason:
- IRQ-bound processing
- Sleepable register access
- Simple execution flow
Touch Controller¶
Architecture:
Recommended mechanism:
Reason:
- Ordered packet processing
- FIFO execution
- Dedicated worker
WiFi Driver¶
Architecture:
Recommended mechanism:
Reason:
- Multiple event sources
- Long-running background processing
- State-machine based design
Selection Matrix¶
| Requirement | Recommended Mechanism |
|---|---|
| Very short work, no sleep | ISR |
| IRQ-bound sleepable work | Threaded IRQ |
| Simple deferred work | Workqueue |
| FIFO ordering required | kthread_worker |
| Multiple event sources | Dedicated kthread |
| State machine required | Dedicated kthread |
Selection Flow¶
Need sleep?
│
├─ No
│ ↓
│ ISR
│
└─ Yes
│
├─ Need FSM?
│ ↓
│ Dedicated kthread
│
├─ Need multiple event sources?
│ ↓
│ Dedicated kthread
│
├─ Need FIFO ordering?
│ ↓
│ kthread_worker
│
├─ IRQ-bound processing?
│ ↓
│ Threaded IRQ
│
└─ Workqueue
Related Topics¶
- IRQ Bottom Half and Deferred Work
- Workqueue Internals
- Kthread
- Wait Queue Internals