中断处理期间禁用中断

10

当内核正在处理一个中断时,为什么会禁用其他中断?

如果错过了携带重要消息的中断会怎样?


有一些内核在中断处理程序中不禁用中断,并具有中断堆栈,允许高优先级中断打断低优先级中断。 - RRON
3个回答

10

这可以防止“堆叠中断”导致内核栈溢出。同时也可以防止死锁和/或固定。

大多数硬件不会“丢失”中断。在中断期间,CPU的“中断标志”被清除,但中断控制器[一个单独的实体]仍然可用/启用以记录新的中断。如果CPU正在处理硬件_A的中断(在“中断服务例程”ISR_A中),则可以仍然断言硬件_B的中断。它将被中断控制器记住,但此时不会中断CPU。当ISR_A返回时,退出时重新启用中断标志,现在立即,ISR_B将被输入(并且其调用堆栈帧将从与ISR_A相同的内存位置开始)。

虽然中断不会丢失/丢弃,但ISR应尽可能短[快速执行],以最小化延迟。换句话说,ISR_A不应该花费太长时间,以至于hardware_B将溢出某些内部状态/缓冲区[因为它继续累积数据等待ISR服务]。

最小化延迟是仔细设计内核和ISR设计的一部分。在Linux中,ISR可以分为ISR部分和“底半部分”或“tasklet”部分。ISR [禁用中断]只进行处理/使设备静止所需的最小操作(例如清除设备中的位,以防止其立即重新断言中断)。

然后,它启用相应的tasklet [以启用中断运行]执行可能需要更长时间的更繁琐的操作。尽管名称为tasklet,但它们不像在“ps”中显示的完整任务/进程那样。它们是将ISR必须执行的工作拆分的[非常]轻量级/高效方法,以最小化延迟。


3
让我们逐个问题来看。
为什么内核正在处理中断时会禁用中断?
虽然有许多类型的中断,例如I/O、定时器、看门狗、串口、外围设备和DMA,但让我们以I/O为例。我们将谈论一个原始案例并将其扩展到内核。
想象一下连接到CPU特定中断引脚的火警/传感器位0/1。 0是正常状态,1是火灾!然后,将配置该输入的中断为“电平触发”。传感器触发1的那一刻,ISR必须执行相关代码以启动警报或自动拨打消防局电话。进入ISR时应通常清除中断。如果未清除,则硬件将继续中断CPU,并且ISR内部的安全代码将永远不会执行。
此外,CPU需要维护其当前执行状态的堆栈。重复中断使情况变得复杂。
第二个例子是“边沿触发”或“过渡触发”。想象一下一系列位被送到输入线/引脚(NRZ编码)。如果ISR的工作是将这些位组装成单词(8、16、32等长度),则需要在周期中清除中断,将位组装到缓冲区中,并再次启用中断。不清除中断会导致一次过渡出现故障,将1位误认为2位。
因此,实践是设置和启用中断,如果被中断,则清除它,在相关位置执行ISR代码并重新启用中断。
内核本身是关键的代码段,调度程序(也是操作系统计时器、操作系统时钟)依赖于硬件定时器中断。CPU的硬件部分包含中断逻辑维护状态转换。它还具有用于启用、禁用、屏蔽和设置中断优先级的硬连线逻辑。
如果内核模块或驱动程序模块应安全地执行代码,则必须在执行处理程序之前禁用中断以获得确定性行为。
如果错过携带重要消息的中断会怎样?
中断处理不应太长(在重新启用中断之前)。根据中断频率和处理程序的复杂性,应正确设计代码。

0
如果控制器断言了任何中断,由于INTR线正在处理第一个中断,它无法传递给CPU。
但更重要的是,中断可以传递给其他CPU,现在多CPU系统非常普遍。
并且作为第一次回复 - 始终保持中断处理程序小而轻量级。 可以采用任何底半部方法,如tasklet、workqueue、threaded IRQ,可以创建内核线程。您可以获得多个SOFT IRQ选项。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接