24

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

不同之处在于,SoftIRQ 是可重入的,而 Tasklet 则不是。相同的 SoftIRQ 可以在不同的 CPU 上运行,而 Tasklet 则不是这样。

虽然我从表面上理解这一点,但我无法理解这两个功能的要求。在什么情况下我们可以使用这些设施?如何识别我现在应该使用 Tasklet,然后使用 SoftIRQ。

另外,我们所说的 Tasklet 是在 SoftIRQ 上制作的是什么意思?在我用 LKML 阅读的一本书中,有关于删除 Tasklet 的争论。我完全糊涂了,为什么要引入这样的功能?有些短视(没有冒犯的意思)?

对此的任何指示都会有很大帮助。

4

4 回答 4

21

包括/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
};

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

分配

  • Softirq 是在编译时静态分配的。与 tasklet 不同,您不能动态注册和销毁软中断。
  • Tasklet 可以使用静态分配DECLARE_TASKLET(name, func, data),也可以动态分配并在运行时使用初始化tasklet_init(name, func, data)

并发

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

加工

  • 软中断通过raise_softirq(). 待处理的软中断在被启用或被启用do_softirq()后由ksoftirqd内核线程处理local_bh_enable()spin_unlock_bh()
  • Tasklet 是建立在 softirq 之上的下半部分机制,即 tasklet 由两个 softirq 表示:HI_SOFTIRQTASKLET_SOFTIRQ. Tasklet 实际上是从 softirq 运行的。这些类型中唯一真正的区别是HI_SOFTIRQ基于 tasklet 的 tasklet 在 tasklet 之前运行TASKLET_SOFTIRQ。所以,tasklet_schedule()基本上打电话raise_softirq(TASKLET_SOFTIRQ)
  • 请注意,软中断(以及因此的小任务和计时器)在从硬件中断返回或从系统调用返回时运行。同样,只要引发 softirq 的线程结束,就会运行单个 softirq(以及其他)以最小化softirq latency.
于 2015-07-29T16:44:58.113 回答
11

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

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

请阅读本书(可免费下载)第 131 页 - 它解释了差异以及使用带有假/虚拟设备的代码示例的解释 - 滚轮。

于 2012-05-31T15:27:07.923 回答
2

Softirq 在编译时静态分配。与 tasklet 不同,您不能动态注册和销毁 softirqs。Tasklets 类似于 softirqs(工作),但是它们具有更简单的接口。只有非常高频率和高线程的使用才需要 Softirq,而 tasklet 在任何其他情况下都可以。

于 2014-10-01T05:09:24.290 回答
1

Tasklet 是在 softirq 之上实现的,所以它们是 softirq。它们由两个softirq的“HI_SOFTIRQ & TASKLET_SOFTIRQ”表示,区别是优先级。尽管它们是在 softirq 之上实现的,但它们的不同之处在于:

  • Tasklet 可以静态或动态地创建/销毁,但 softirq 只能通过静态方式。

  • 两个不同的 tasklet 可以在同一个 cpu 上同时运行。但是两个相同类型的tasklet不能在同一个cpu上运行。而 softirq 则相反。

Softirq 保留用于系统上大多数时间关键和重要的下半部分处理。

于 2015-06-16T04:56:12.033 回答