17

我知道有进程上下文和中断上下文,但是我不明白在执行 softirq 或 tasklet 时,它在哪个上下文下运行。

我看到有些人使用“下半部分上下文”一词,如果有这样的词,与其他词相比有什么区别。

softirq 和 tasklet 的另一个问题是为什么在执行期间不允许休眠?

谁能帮我找出这些问题,谢谢!

4

3 回答 3

21

softirq 和 tasklet 都是一种下半部分机制。不允许睡眠,因为它们在中断上下文而不是进程上下文下运行。如果允许睡眠,则 linux 无法调度它们并最终导致内核恐慌并出现 dequeue_task 错误。中断上下文甚至没有描述寄存器信息的数据结构,因此它们永远无法被 linux 调度。如果它被设计为具有该结构并且可以被调度,则中断处理过程的性能将受到影响。

于 2011-08-21T04:38:22.587 回答
15

@kai:您的 qs reg 在哪个上下文下半部分执行?

从技术上讲,softirq确实在中断上下文中运行——“softirq”上下文;只是它不是“硬中断”上下文(这是发生硬件中断时的上下文)。

因此,在 softirq 处理程序中,就 Linux 提供的“查找”宏而言:

in_interrupt:是的| in_irq: 没有 | in_softirq: 是 | in_serving_softirq:是的

但请注意(当心!!!:):“适用于中断处理程序的所有限制也适用于底半部分。因此,底半部分不能休眠,不能访问用户空间,也不能调用调度程序。” ——LDD3。

Jermaine 回答了你剩下的问题。

[更新] 此外,我想指出,可以定义简单而优雅的宏,以帮助在需要时打印调试信息。多年来,我将这些宏和便利例程放入头文件中;你可以在这里查看并下载它:“方便的标题”

有宏/功能可以:

  • 与 funcname / line# info 一起进行调试打印(通过通常的 printk() 或 trace_printk())并且仅当调试模式为 On 时
    • 转储内核模式堆栈
    • 打印当前上下文(进程或中断以及ftrace使用的形式的标志)
    • 一个简单的 assert() 宏 (!)
    • 一个 CPU 密集型 DELAY_LOOP(对于必须在处理器上旋转的测试台很有用)
    • 相当于用户模式睡眠功能
    • 给定两个时间戳(timeval 结构)计算时间增量的函数
    • 将十进制转换为二进制,以及
    • 还有几个。

哇:-)

于 2011-11-25T04:32:55.253 回答
9

我同意接受的答案和开湾的答案,但他们没有提到ksoftirqd。如果 CPU 处于 softirq 和/或 tasklet 的繁重负载下,它会调度其ksoftirqd线程,在进程上下文中处理引发的 softirq 和 tasklet。

所以我想 OP 问题的答案是:softirqs 可以在中断或进程上下文中运行。

更新:快速浏览在禁用本地 irqs 的情况下调用的run_ksoftirqd()节目。__do_softirq()因此,虽然技术上在进程上下文中运行,但同样的限制(如禁止睡眠)适用。

于 2014-10-17T06:55:37.563 回答