Home > Article > Operation and Maintenance > Three ways to interrupt the lower half of Linux drivers
When an interrupt is generated, the interrupt handler will be entered.
But the interrupt handler must be fast, asynchronous, and simple to respond quickly to the hardware and complete those time-critical operations.
Therefore, for other tasks that have relatively loose time requirements, they should be postponed until the interrupt is activated before running .
In this way, the entire interrupt processing process is divided into two parts:
Next The half task is mainly to perform interrupt-related work, which is not completed by the interrupt service routine itself.
Lower half It is not necessary to specify an exact time, just postpone these tasks a little longer so that they can be done when the system is not too busyAnd After the interruption and recovery, can be executed.
The main difference between the upper and lower halves:
The upper half refers to Interrupt handler, The lower half refers to some tasks that can be postponed although they are related to interrupts.
the lower half can still be interrupted by interrupts.
The first half is simple and fast, disable some or all interruptions during execution.
The second half will be executed later, and all interrupts can be responded to during execution.
Linux
, there are three main ways to implement the lower half of the interrupt:
softirq is a softirq, the code is located in
kernel/softirq.cIn the file;
softirq_action structure:
softirq.c A softirq vector array
softirq_vec is defined:
static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp; enum { HI_SOFTIRQ=0, /*用于高优先级的tasklet*/ TIMER_SOFTIRQ, /*用于定时器的下半部*/ NET_TX_SOFTIRQ, /*用于网络层发包*/ NET_RX_SOFTIRQ, /*用于网络层收报*/ BLOCK_SOFTIRQ, BLOCK_IOPOLL_SOFTIRQ, TASKLET_SOFTIRQ, /*用于低优先级的tasklet*/ SCHED_SOFTIRQ, HRTIMER_SOFTIRQ, RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */ NR_SOFTIRQS };The number of members of the array is determined by
NR_SOFTIRQS, which is an enumeration constant.
include/linux/interrupt.h .
Several key points in using soft interrupts:
相关接口
void open_softirq(int nr, void (*action)(struct softirq_action *))
即注册对应类型的处理函数到全局数组softirq_vec
中。
void raise_softirq(unsigned int nr)
实际上即以软中断类型nr
作为偏移量会置位irq_stat[cpu_id]
的成员变量__softirq_pending
.
__softirq_pending
字段中的每一个bit
,对应着某一个软中断,某个bit
被置位,说明有相应的软中断等待处理。
这也是同一类型软中断可以在多个cpu
上并行运行的根本原因。
以一个按键驱动的中断处理为例,将按键驱动的中断处理分成上下两部分:
Soft interrupt registration, in the driver's entry function, register the soft interrupt:
Added enumeration constants:
As you can see, using soft interrupts requires modifying the kernel, and adding an enumeration is a bit cumbersome.
Therefore, we usually do not recommend increasing the number of soft interrupts without authorization. If new soft interrupts are needed, try to implement them as soft interrupt-based tasklets
form.
##tasklet is the use of soft interruptA kind of lower half mechanism implemented.
Is it better to usesoft interrupt or tasklet?
softirq or tasklet is actually very simple:
tasklet
。就像我们在前面看到的,软中断资源有限,也麻烦,而且软中断的使用者屈指可数。它只在那些执行频率很高和连续性要求很高的情况下才需要。tasklet
效果都不错,而且它们还非常容易使用。tasklet
的使用步骤如下:
1、编写tasklet
处理函数(下半部)
void my_tasklet_fun (unsigned long data)
2、声明tasklet
//静态 DECLARE_TASKLET(my_tasklet,my_tasklet_fun,data); //动态 Struct tasklet_struct xxx; tasklet_init(&xxx,tasklet_handler,dev)
3、调度 tasklet
tasklet_schedule(&my_tasklet);
登记my_tasklet
, 然后允许系统在合适的时间调度它。
以按键中断驱动为例:
First use DECLARE_TASKLET
to statically declare a tasklet
, specify its lower half function as btn_tasklet_func
, and interrupt the service After the function (upper half) obtains the key value, it calls tasklet_schedule
scheduling.
work queue
is work queue, It is also a type that interrupts the lower half.
Work queue
Defer the second half of the work to a kernel thread for execution - work
always runs in the process context .
Two important points:
sleep
. Otherwise, use softirq
or tasklets
. is suitable for allocating a large amount of memory and obtaining a semaphore. , or perform blocked
I/O.
work queue is similar to tasklet:
The above is the detailed content of Three ways to interrupt the lower half of Linux drivers. For more information, please follow other related articles on the PHP Chinese website!