Linux软中断原理浅析




构成软中断机制的核心元素包括:
 
1、  软中断状态寄存器soft interrupt state(irq_stat)
2、  软中断向量表(softirq_vec)
3、  软中断守护daemon


软中断的工作工程模拟了实际的中断处理过程:
1、当某一软中断时间发生后,首先需要设置对应的中断标记位,触发中断事务( raise_softirq() 设置软中断 状态bitmap ,触发软中断 事务
2、然后唤醒守护线程去检测中断状态寄存器( 在Linux中 软中断daemon线程函数为do_softirq()
3、如果通过查询发现某一软中断事务发生之后,那么通过软中断向量表调用软中断服务程序action()。

这就是软中断的过程,与硬件中断唯一不同 的地方是从中断标记到中断服务程序的映射过程。在CPU的硬件中断发生之后,CPU需要将硬件中断请求通过向量表映射成具体的服务程序,这个过程是硬件自 动完成的,但是软中断不是,其需要守护线程去实现这一过程,这也就是软件模拟的中断,故称之为软中断。
 
一个软中断不会去抢占另一个软中断,只有硬件中断才可以抢占软中断,所以软中断能够保证对时间的严格要求。

软中断守护daemon 是软中断机制的实现核心,其实现过程也比较简单,通过查询软中断状态irq_stat来判断事件是否发生,如果发生, 那么映 射到软中断向量表,调用执行注册的action函数就可以了。从这一点分析可以看出,软中断的服务程序的执行上下文为软中断daemon。

常用的软中断函数列表如下:
1、  Open_softirq,注册一个软中断,将软中断服务程序注册到软中断向量表。

  void open_softirq(int nr, void (*action)(struct softirq_action*), void *data)
  
  open_softirq()会填充softirq_vec[nr],将action和data设为传入的参数。TASKLET_SOFTIRQ填充为tasklet_action(NULL),HI_SOFTIRQ填充为tasklet_hi_action(NULL),在do_softirq()函数中,这两个函数会被调用,分别启动tasklet_vec[cpu]和tasklet_hi_vec[cpu]链上的tasklet运行。



2、  Raise_softirq,设置软中断状态bitmap,触发软中断事务。

  static inline void __cpu_raise_softirq(int cpu, int nr)
   
  这个函数用来激活软中断,实际上就是第cpu号CPU的第nr号软中断的active位置1。在do_softirq()中将判断这个active位。tasklet_schedule()和tasklet_hi_schedule()都会调用这个函数。



do_softirq()有4个执行时机,分别是:从系统调用中返回(arch/i386/kernel/entry.S::ENTRY(ret_from_sys_call))、从异常中返回(arch/i386/kernel/entry.S::ret_from_exception标号)、调度程序中(kernel/sched.c::schedule()),以及处理完硬件中断之后(kernel/irq.c::do_IRQ())。它将遍历所有的softirq_vec,依次启动其中的action()。需要注意的是,软中断服务程序,不允许在硬中断服务程序中执行,也不允许在软中断服务程序中嵌套执行,但允许多个软中断服务程序同时在多个CPU上并发。




你可能感兴趣的:(Linux软中断原理浅析)