Home  >  Article  >  Operation and Maintenance  >  Three ways to interrupt the lower half of Linux drivers

Three ways to interrupt the lower half of Linux drivers

嵌入式Linux充电站
嵌入式Linux充电站forward
2023-07-31 14:57:18968browse

What is the lower half of the interrupt

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:

  • The first part is the interrupt handler ( The upper half), the kernel completes the immediate response to hardware interrupts through its asynchronous execution.
  • The other part of the interrupt processing flow, bottom half(bottom half)

Next The half task is mainly to perform interrupt-related work, which is not completed by the interrupt service routine itself.

Three ways to interrupt the lower half of Linux drivers

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 upper half of the interrupt cannot be interrupted by the same type of interrupt, while

    the lower half can still be interrupted by interrupts.

  • #Usually the lower half will run as soon as the interrupt handler returns.

  • 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:

  • Soft interrupt
  • tasklet
  • ##Work queue

softirq

softirq is a softirq, the code is located in kernel/softirq.cIn the file;

Each softirq is represented by the

softirq_action structure:

Three ways to interrupt the lower half of Linux drivers
in

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.

When adding a soft interrupt, you need to add an enumeration constant in the file

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上并行运行的根本原因。

软中断实例

以一个按键驱动的中断处理为例,将按键驱动的中断处理分成上下两部分:

  • The upper part: Read the key value and trigger the soft interrupt
  • The lower part: Wake up Process
Three ways to interrupt the lower half of Linux drivers

Soft interrupt registration, in the driver's entry function, register the soft interrupt:

Three ways to interrupt the lower half of Linux drivers

Added enumeration constants:

Three ways to interrupt the lower half of Linux drivers

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 taskletsform.

tasklet

##tasklet is the use of soft interruptA kind of lower half mechanism implemented.

Is it better to use

soft interrupt or tasklet?

Choose whether to use

softirq or tasklet is actually very simple:

  • 通常你应该用tasklet就像我们在前面看到的,软中断资源有限,也麻烦,而且软中断的使用者屈指可数。它只在那些执行频率很高和连续性要求很高的情况下才需要。
  • tasklet却有更广泛的用途。大多数情况下用tasklet效果都不错,而且它们还非常容易使用。
  • 因为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, 然后允许系统在合适的时间调度它。

tasklet实例

以按键中断驱动为例:

Three ways to interrupt the lower half of Linux drivers

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_schedulescheduling.

work queue

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:

  • Use work queues if the deferred work requires sleep. Otherwise, use softirq or tasklets.
  • ##Work queues is suitable for allocating a large amount of memory and obtaining a semaphore. , or perform blocked I/O.
Related interface functions of work queue:

Three ways to interrupt the lower half of Linux drivers
In terms of use,

work queue is similar to tasklet:

Three ways to interrupt the lower half of Linux drivers

##

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!

Statement:
This article is reproduced at:嵌入式Linux充电站. If there is any infringement, please contact admin@php.cn delete