PIC 是一个非常古老的中断控制器,今天的中断主要通过 MSI 或 APIC 层次结构传递。
IRQ 路由、虚拟化等问题实际上更复杂。
我不会讨论这些。
中断优先级的概念仍然存在(虽然有点简化),它的工作原理如下:
当中断控制器接收到中断请求时,所有较低优先级的中断都被屏蔽,并将中断发送到CPU。
实际发生的是中断按其请求编号排序,编号越低优先级越高(0 的优先级高于 1)。
当任何请求行被切换或断言时,中断控制器将扫描每个请求行的状态,从数字 0 到最后一个。
一旦发现行断言或标记(使用使用或辅助寄存器)正在处理中,它就会停止。
这样,如果请求第 2 行首先被断言,然后请求第 4 行被断言,中断控制器将不会处理最后一个请求,直到第一个请求“完成”,因为第 2 行停止扫描。
所以local_irq_disable 可用于禁用所有中断,包括那些具有更高优先级的中断。
AFAIK,这个功能今天应该很少使用。这是一种非常简单但效率低下的方法,可以确保没有其他代码可以运行(可能会改变常见结构)。
一般来说,ISR 和设备之间需要进行一些协调以避免丢失中断。
有些设备需要软件写入一个特殊的寄存器,让他们知道它能够处理下一个中断。通过这种方式,设备可以实现内部通知队列。
键盘控制器的工作原理是这样的,如果您读取扫描码的速度不够快,您就会丢失它们。
如果设备随意且过于频繁地触发中断,中断控制器可以缓冲请求,以免丢失。
PIC 和 LAPIC 都可以在另一个请求正在进行时最多缓冲一个请求(它们基本上使用了这样一个事实,即每个中断都有一个请求寄存器和一个正在进行的寄存器)。
所以在连续三个中断的情况下,肯定会丢失一个。如果中断控制器无法将第一个中断传递给 CPU,因为更高优先级的中断正在进行,那么两个将丢失。
一般来说,软件不会除了中断控制器来缓冲任何请求。
所以你不应该找到依赖于此的代码(毕竟 CS 中唯一的数字是 0、1 和无穷大。所以就软件而言,2 并不存在)。
x86 作为 CPU 内核,在处理中断时不支持优先级。如果中断未被屏蔽,并且硬件中断到达,则提供服务。中断优先级由软件和中断控制器决定。
PIC 和 LAPIC(以及 MSI 和 IOAPIC)都给中断一个优先级,因此 x86 支持基于优先级的中断机制。
但是请注意,给予中断优先级并不一定是好的,很难判断网络数据包是否比击键更重要。
因此,Linux 有guideline to do as little work as possible in the ISR,而是将其余工作排队等待异步处理出 ISR。
这可能意味着只是从 ISR 返回到工作功能,以便不阻塞其他中断。
在绝大多数情况下,只需要在临界区运行一小部分代码,在这种情况下不应该发生其他中断,所以一般的做法是把EOI返回给中断控制器,并在临界区取消屏蔽中断。尽早 CPU 并编写代码,使其可以被中断。
如果出于性能原因需要停止另一个中断,通常采用的方法是将中断拆分到不同的内核,以便负载在所需的指标范围内。
在多核系统普及之前,中断过多会有效地减慢某些操作。
我想可以加载一个denial other interrupts for its own performance 的驱动程序,但这是一种由用户自行解决的 QoS/实时要求。