linux中断下半部处理

1、软中断

注册软中断
   如:open_softirq(MY_SOFTIRQ, my_softirq_action)
在中断处理程序中触发软中断
 如:raise_softirq(MY_SOFTIRQ)

2、tasklet

初始化一个tasklet:

  方法1:
  DECLARE_TASKLET(name, func, data);定义名字为name的tasklet,默认为enable状态,也就是count字段等于0。
  DECLARE_TASKLET_DISABLED(name, func, data);定义名字为name的tasklet,默认为enable状态,也就是count字段等于1。

 方法2:
 先定义一个tasklet_struct,然后用tasklet_init函数进行初始化,该方法默认tasklet处于enable状态:
struct tasklet_struct tasklet_xxx;
......
tasklet_init(&tasklet_xxx, func, data);

登记任务

 tasklet_schedule()

3、工作队列

初始化工作队列

INIT_WORK

登记工作队列

schedule_work

Q: 为什么软中断不能睡眠?

      Linux在软中断上下文中是不能睡眠的,原因在于Linux的软中断实现上下文有可能是中断上下文,如果在中断上下文中睡眠,那么会导致Linux无法调度,直接的反应是系统Kernel Panic,并且提示dequeue_task出错。所以,在软中断上下文中,我们不能使用信号量等可能导致睡眠的函数。

      在最近的一个项目中,我们在dm-io的callback函数中去持有semaphore访问竞争资源( 会睡眠,即发生调度),导致了系统的kernel panic。其原因就在于dm-io的回调函数在scsi soft irq中执行,scsi soft irq是一个软中断,其会在硬中断发生之后被执行,执行上下文为中断上下文。 中断上下文中无法睡眠的原因大家一定很清楚,原因在于中断上下文不是一个进程上下文,其没有一个专门用来描述CPU寄存器等信息的数据结构,所以无法被调度器调度。

       Linux对中断进行了有效的管理,一个中断发生之后,都会通过相应的中断向量表获取该中断的处理函数。在Linux操作系统中都会调用do_IRQ这个函数,在这个函数中都会执行__do_IRQ(),__do_IRQ函数调用该中断的具体执行函数。在执行过程中,该函数通过中断号找到具体的中断描述结构irq_desc,该结构对某一具体硬件中断进行了描述。在irq_desc结构中存在一条链表irqaction,这条链表中的某一项成员都是一个中断处理方法。这条链表很有意思,其实现了中断共享,例如传统的PCI总线就是采用共享中断的方法,该链表中的一个节点就对应了一个PCI设备的中断处理方法。在PCI设备驱动加载时,都需要注册本设备的中断处理函数,通常会调用request_irq这个函数,通过这个函数会构造一个具体的irq action,然后挂接到某个具体irq_desc的action链表下,实现中断处理方法的注册。在__do_IRQ函数中会通过handle_IRQ_event()函数遍历所有的action节点,完成中断处理过程。到目前为止,中断处理函数do_IRQ完成的都是上半部的工作,也就是设备注册的中断服务程序。在中断上半部中,通常都是关中断的,基本都是完成很简单的操作,否则将会导致中断的丢失。耗时时间相对较长,对实时性要求不是最高的应用都会被延迟处理,都会在中断下半部中执行。所以,在中断上半部中都会触发软中断事件,然后执行完毕,退出服务。 __do_IRQ完成之后,返回到do_IRQ函数,在该函数中调用了一个非常重要的函数irq_exit(),在该函数中调用invoke_softirq(),invoke_softirq调用do_softirq()函数,执行软中断的操作。此时,程序的执行环境还是中断上下文,但是与中断上半部不同的是,软中断执行过程中是开中断的,能够被硬中断而中断。所以,如果用户的程序在软中断中睡眠,操作系统该如何调度呢?只有kernel panic了。另外,软中断除了上述执行点之外,还有其他的执行点,在内核中还有一个软中断的daemon处理软中断事务,驱动程序也可以自己触发一个软中断事件,并且在软中断的daemon上下文中执行。但是硬中断触发的事件都不会在这个daemon的上下文中执行,除非修改Linux中的do__IRQ代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值