中断处理期间禁用中断

问题描述 投票:0回答:3

为什么当内核当前正在处理中断时禁用中断?

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

operating-system interrupt interrupt-handling
3个回答
10
投票

这可以防止可能溢出内核堆栈的“堆栈中断”。它还可以防止死锁和/或“固定”。

大多数硬件不会“丢失”中断。在中断期间,CPU 的“中断标志”被清除,但中断控制器[一个单独的野兽]仍然可用/启用以记录新中断。如果 CPU 正在处理 hardware_A 的中断(在“中断服务程序”ISR_A 中),则 hardware_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 为例。我们将讨论一个原始案例并将其扩展到内核中。

想象一个火警/传感器位 0/1 连接到 CPU 的特定中断引脚。 0为正常状态,1为火灾!然后,可以将该输入的中断配置为“电平触发”。当传感器触发 1 时,ISR 必须执行相关代码来拉响警报或自动拨打消防部门电话。通常,在进入 ISR 时中断应该被清除。如果不清除,硬件会不断中断 CPU,ISR 内的安全代码将永远不会执行。

CPU还需要维护其当前执行状态的堆栈。反复出现的中断使情况变得复杂。

“边沿触发”或“转换触发”的第二个示例想象一系列位出现在输入线/引脚上(NRZ 编码)。如果 ISR 的工作是将这些位组装成字(8、16、32,无论长度),我们需要清除中断,将位组装到缓冲区中,然后再次启用中断(循环)。不清除中断会导致毛刺 y 转换将 1 位误认为 2 位。

因此,实践是设置并启用中断,如果中断,则清除它,执行 ISR 代码并在相关的地方启用中断。

内核

内核本身是一段关键代码,调度程序(还有操作系统定时器、操作系统时钟)依赖于硬件定时器中断。 CPU 的硬件部分包含中断逻辑,负责维护状态转换。它还具有用于启用、禁用、屏蔽和设置中断优先级的硬连线逻辑。

如果内核模块或驱动程序模块应安全地执行代码,则只能通过在执行处理程序之前禁用中断来获得确定性行为

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

中断处理不应太长(在重新启用中断之前)。应根据中断的频率和处理程序的复杂性来正确设计代码。


0
投票

如果向控制器发出任何中断,则无法将其传递到 CPU,因为 INTR 线正忙于处理第一个中断。

但更重要的是中断可以传递给其他CPU,现在多CPU系统已经很常见了。

作为第一个回复 - 始终保持中断处理程序小而轻。 可以有任何bottom half方法,如tasklet、workqueue、线程IRQ,可以创建内核线程。您可以获得多个软IRQ选项。

© www.soinside.com 2019 - 2024. All rights reserved.