SoftIRQ和Tasklet之间的区别

ult*_*use 21 linux-kernel interrupt-handling softirq tasklet

在研究Linux中断处理时,我发现Tasklets和SoftIRQ是执行"下半部分"(较低优先级工作)的两种不同方法.我理解这一点(非常真实的需要).

不同的是,SoftIRQ是重要的,而Tasklet则不是.同样的SoftIRQ可以在不同的CPU上运行,而Tasklets不是这种情况.

虽然我从表面上理解这一点,但我无法理解这两个特征的要求.在什么情况下我们可以使用这些设施?如何识别我现在应该使用Tasklets和SoftIRQs.

另外,Tasklets是在SoftIRQ上制作的?在我用LKML阅读的一本书中,有关删除Tasklets的争论.我完全搞砸了为什么要引入这样的功能?一些短视(没有冒犯意味着)?

任何关于此的指示都会有所帮助.

man*_*m-n 18

包括/ LINUX/interrupt.h

/* PLEASE, avoid to allocate new softirqs, if you need not _really_ high
   frequency threaded job scheduling. For almost all the purposes
   tasklets are more than enough. F.e. all serial device BHs et
   al. should be converted to tasklets, not to softirqs.
 */

enum
{
        HI_SOFTIRQ=0,    /* High Priority */
        TIMER_SOFTIRQ,
        NET_TX_SOFTIRQ,
        NET_RX_SOFTIRQ,
        BLOCK_SOFTIRQ,
        BLOCK_IOPOLL_SOFTIRQ,
        TASKLET_SOFTIRQ,
        SCHED_SOFTIRQ,
        HRTIMER_SOFTIRQ,
        RCU_SOFTIRQ,    /* Preferable RCU should always be the last softirq */

        NR_SOFTIRQS
};
Run Code Online (Sandbox Code Playgroud)

softirq和之间的主要区别tasklet是:

分配

  • Softirqs在编译时静态分配.与tasklet不同,您无法动态注册和销毁softirq.
  • Tasklet可以使用静态分配,DECLARE_TASKLET(name, func, data)也可以动态分配,并在运行时使用初始化tasklet_init(name, func, data)

并发

  • Softirqs可以在多个CPU上同时运行,即使它们属于同一类型,因为softirqs是reentrant函数,必须使用自旋锁明确保护其数据结构.
  • Tasklet non-reentrant和同一类型的tasklet总是被序列化:换句话说,两个CPU不能同时执行相同类型的tasklet.但是,可以在多个CPU上同时执行不同类型的tasklet.

处理

  • Softirqs通过以下方式激活raise_softirq().待处理的软中断被处理do_softirq()ksoftirqd内核线程通过启用后local_bh_enable()spin_unlock_bh()
  • Tasklet是一个建立在softirq之上的下半部机制,即tasklet由两个softirqs表示:HI_SOFTIRQTASKLET_SOFTIRQ.Tasklet实际上是从softirq运行的.这些类型中唯一真正的区别是HI_SOFTIRQ基于tasklet的任务在tasklet之前运行TASKLET_SOFTIRQ.所以,tasklet_schedule()基本上是电话raise_softirq(TASKLET_SOFTIRQ)
  • 请注意,softirqs(以及因此的tasklet和定时器)在从硬件中断返回时运行,或者在从系统调用返回时运行.一旦引发softirq的线程结束,那么运行单个softirq(和其他)以最小化softirq latency.


Rau*_*ulp 11

Sofirqs是可重入的,即不同的CPU可以采用相同的softirq并执行它,而Tasklet是序列化的,运行tasklet的CPU是有权完成它,没有其他CPU可以接受它(以防万一)调度).参考这篇优秀的文章.

您还可以使用本地CPU上的local_bh_enable()来启用/禁用延迟处理,这实际上使_ _local_bh_count非零.

另请阅读本书(可免费下载)第131页 - 它解释了使用代码示例与伪/虚拟设备 - 滚轮的区别和解释.