Linux Core - Interrupt
Top Half v.s. Botton Half
APIC
- Advanced Programmable Interrupt Controller - is a internal device to handle interrupt for ARM chip
.
Top Half
The top half is the interrupt handler, and it:[1][2]
- checks to make sure the interrupt was generated by the right hardware. This check is necessary for interrupt sharing.
- clears an interrupt pending bit on the interface board
- does what needs to be done immediately (usually read or write something to/from the device). This data is usually written to or read from a device-specific buffer, which has beed previous allocated.
- schedules handing the new information later if the handing required is not trivial.
An interrupt handler needs to be registered during initialization, and deregistered during cleanup.
#include <linux/interrupt.h>
int request_irq(unsigned int irq, irq_handler_t hander,
unsigned long flags, const char* name, void *dev);
and to remove an interrupt handler:
#include <linux/interrupt.h>
void free_irq(unsigned int irq, void *dev);
Botton Half
The linux bottom half mechanism are provided below:
softirq
- have higher priority than other interrupt, so it has higher performance.
- Intended for high frequency, low latency tasks.
- is not preemptible
tasklets
- can be run in parrallel, but the same tasklet cannot be run on multiple CPUs at the same time.
- `workqueues
- a linked list to be run at a deferred time.
- run in process context, therefore can sleep, and without inteferring with tasks running in any other queues.
- still can not transfer data to and from user space, as this is not a real user context.
space allocation | Scheduling Priority | Context | |
---|---|---|---|
SoftIRQ | static defined | High | Interrupt |
Tasklet | dynamic registered | medium | Interrupt |
Work Queue | dynamic registered | medium | Process |
softirq
The same type of softirq
can run on different processors simultanaeously. However, particular softirq (of the same type) cannot run concurrently on two processors, this ensures that there is no race condition.
From kernel 5.10, here's all available pre-defined softirqs
// include/linux/interrupt.h
enum {
HI_SOFTIRQ=0,
TIMER_SOFTIRQ, // timer
NET_TX_SOFTIRQ, // networking
NET_RX_SOFTIRQ, // networking
BLOCK_SOFTIRQ, // IO
IRQ_POLL_SOFTIRQ,
TASKLET_SOFTIRQ, // tasklet
SCHED_SOFTIRQ, // schedule
HRTIMER_SOFTIRQ, // timer
RCU_SOFTIRQ, // lock
NR_SOFTIRQS
};
ksoftirqd
In most cases, softirqs are scheduled in hardware interrupts, which may arrive very quickly, faster than they can be serviced. They are then queued (softirq is labeled as defered
) by the kernel in order to be processed later. ksoftirqd
are responsible for late execution (process context). A ksoftirqd is per-CPU kernel thread raised to handle unserved software interrupts
.[3][4][5][6]
example:
static void run_ksoftirqd(unsigned int cpu) {
local_irq_disable();
if (local_softirq_pending()) {
__do_softirq();
rcp_note_context_switch(cpu);
local_irq_enable();
cond_resched();
return;
}
local_irq_enable();
}
cwyark@roscube-test:~$ ps aux | grep ksoft
root 13 0.0 0.0 0 0 ? S 23:24 0:00 [ksoftirqd/0]
root 22 0.0 0.0 0 0 ? S 23:24 0:00 [ksoftirqd/1]
root 28 0.0 0.0 0 0 ? S 23:24 0:00 [ksoftirqd/2]
root 34 0.0 0.0 0 0 ? S 23:24 0:00 [ksoftirqd/3]
root 40 0.0 0.0 0 0 ? S 23:24 0:00 [ksoftirqd/4]
root 46 0.0 0.0 0 0 ? S 23:24 0:00 [ksoftirqd/5]
root 52 0.0 0.0 0 0 ? S 23:24 0:00 [ksoftirqd/6]
root 58 0.0 0.0 0 0 ? S 23:24 0:00 [ksoftirqd/7]
TaskLet
tasklet in linux is a lightweight, bottom-half mechanism for deferring work to be execute later in a context where it is safe to perform tasks that might sleep
or take a long time to complete
.
tasklets are non-preemptive, once a tasklet starts running, it runs to completion without being interrupted by other tasklets. however, tasklets can be preempted by softirqs, hard IRQs and kernel preemption.
Tasklets are executed on the same CPU where they were scheduled, and they run in interrupt context
.
- Individual tasklets are locked during execution, no problem about re-entrancy and no need for locking by the code.
Bottom Half | Multiple Processor |
---|---|
softirq | 相同性質的softirq可在不同處理器上同時執行、但是無法由多個處理器一起執行一個softirq |
tasklet | 同性質的tasklet不能同時執行 |
here's a reference [7]
Work Queue
work queue is more flexible than tasklet and can be created dynamically at runtime. It runs in process context, not in interrupt context, which means it can sleep
, perform file I/O, and wait on semaphores
, operations that is not possible in softirq or tasklet.
worker queues are managed by kworker threads
within the kernel.
Scheduler | deferred mechanism |
---|---|
kworker | work queues |
ksoftirqd | softirqs |