【问题标题】:When save states while dealing with tasklets?在处理小任务时保存状态?
【发布时间】:2018-06-30 00:41:10
【问题描述】:
【问题讨论】:
标签:
linux-kernel
interrupt-handling
tasklet
【解决方案1】:
作者指出 tasklet_schedule 可以在禁用或启用中断的情况下调用。由于它希望它们被禁用,它需要保存它们是否已经被禁用。然后在工作完成后,它知道是否启用它们(如果它们在调用之前启用,则启用它们,如果它们在调用之前禁用,则使它们禁用)。相反,tasklet_action 仅在启用中断的情况下调用,因此检查它们的状态没有意义。它们总是在返回时被禁用和启用。
【解决方案2】:
在 tasklet_schedule 的情况下:
我们不希望在调度 tasklet 时中断打扰我们,所以我们必须禁用它。但我们也知道,当我们完成调度 tasklet 后,我们希望回到调用调度 tasklet 之前的 IRQ 状态。为此,我们在做任何事情之前保存 IRQ 寄存器的状态,然后根据我们的要求禁用 IRQ,进行调度,现在在返回之前恢复 IRQ 的状态,然后从函数返回。
现在进入复杂的部分,为什么我们不需要在执行 tasklet 时保存 IRQ,即当处理程序调用 tasklet 函数时?
要了解我们需要看两个不同的段落:
在第 141 页:
softirq 处理程序在启用中断的情况下运行,并且不能
sleep 。当处理程序运行时,当前处理器上的软中断是
禁用。然而,另一个处理器可以执行其他软中断。如果
相同的软中断在执行时再次引发,另一个
处理器可以同时运行它。
因此,这声明了中断始终启用。
现在转到第 143 页:
- 禁用本地中断传递(不需要先保存它们的状态因为这里的代码总是被称为softirq
处理程序 和中断始终启用)并检索
此处理器的 tasklet_vec 或 tasklet_hi_vec 列表
因此我们可以得出结论,我们不需要保存 IRQ 状态,因为我们已经知道它的状态,并且它在所有情况下都会保持不变,所以我们只需禁用 IRQ 并稍后启用它。