软中断
tasklet
软中断和tasklet区别?
触发软中断
和
的区别?
软中断为什么不能睡眠?
原因在于Linux的软中断实现上下文有可能是中断上下文,如果在中断上下文中睡眠,那么会导致Linux无法调度,直接的反应是系统Kernel Panic,并且提示dequeue_task出错。所以,在软中断上下文中,我们不能使用信号量等可能导致睡眠的函数,这一点在编写IO回调函数时需要特别注意。
中断上下文不是一个进程上下文,其没有一个专门用来描述CPU寄存器等信息的数据结构,所以无法被调度器调度。如果将中断上下文也设计成进程上下文,那么调度器就可以对其进行调度,如果在开中断的情况下,其自然就可以睡眠了。但是,如果这样设计,那么中断处理的效率将会降低。中断(硬中断、软中断)处理都是些耗时不是很长,对实时性要求很高,执行频度较高的应用
一个中断发生之后,都会通过相应的中断向量表获取该中断的处理函数。在Linux操作系统中都会调用do_IRQ这个函数,在这个函数中都会执行__do_IRQ(),__do_IRQ函数调用该中断的具体执行函数,__do_IRQ完成之后,返回到do_IRQ函数,在该函数中调用了一个非常重要的函数irq_exit(),在该函数中调用invoke_softirq(),invoke_softirq调用do_softirq()函数,执行软中断的操作。此时,程序的执行环境还是中断上下文,但是与中断上半部不同的是,软中断执行过程中是开中断的,能够被硬中断而中断,所以,如果用户的程序在软中断中睡眠,操作系统该如何调度呢?
tasklet利用软中断实现,但众所周知ksoftirqd是来处理软中断的内核线程,它运行在中断上下文还是进程上下文?如何参与调度?
如上面链接里的老哥所诉,ksoftirqd运行在进程上下文,但在ksoftirqd运行期间,通常也是不允许睡眠的,进入ksoftirqd之后,softirq也是被屏蔽的,相当于是执行了local_bh_disable(),执行被local_bh_disable()和local_bh_enable()包围的代码区域时,由于softirq是被屏蔽的,也是处在“softirq上下文”,所以在这段时间里也是不能睡眠。
其实还是有点闷逼,ksoftirqd明明运行在进程上下文,怎么就变成了softirq上下文,意思是进入ksoftirqd之后,softirq也是被屏蔽的,相当于是执行了local_bh_disable(),而local_bh_disable()和local_bh_enable()包围的代码区域时,处于软中断上下文?
工作队列就是创建的内核线程,那它和ksoftirqd/n线程有啥区别?
工作队列线程主要用于异步执行需要执行的任务,而ksoftirqd/n线程主要用于处理软中断