中断嵌套,排序



我正在阅读Linux内核文档,我有以下问题(X86_64Arch);

  1. 当PIC向CPU发送中断时,会禁用该特定中断吗,直到CPU发出确认?如果是这样的话,为什么我们需要在ISR中使用local_irq_disable()
  2. 与上述问题相关,但假设CPU正在其ISR中处理一个中断,并且如果同一设备向CPU发送了3个中断,该如何处理?它会在某个缓冲区中串行化吗(如果是,在哪里)
  3. X86体系结构支持基于优先级的中断

PIC是一个非常古老的中断控制器,如今中断大多通过MSI或APIC层次结构提供
实际上,IRQ路由、虚拟化等问题更为复杂。我不会讨论这些。

中断优先级的概念仍然存在(尽管有点简化),其工作原理如下:当中断控制器接收到中断请求时,所有较低优先级的中断都将被屏蔽,并将中断发送到CPU
实际发生的情况是,中断按请求编号排序,编号越低优先级越高(0的优先级高于1)
任何请求行被切换或断言时,中断控制器将扫描从数字0到最后一个的每个请求行的状态
一旦发现在处理中断言或标记(使用或辅助寄存器)的行,它就会停止
这样,如果请求行2首先被断言,然后请求行4被断言,则中断控制器将不提供最后一个请求,直到第一个请求为"0";完成";因为第2行停止扫描。

因此,local_irq_disable可用于禁用所有中断,包括优先级较高的中断
AFAIK,今天应该很少使用此功能。这是一种非常简单但效率低下的方法,可以确保没有其他代码可以运行(可能会改变公共结构)。

通常,ISR和设备之间需要进行一些协调,以避免中断丢失
有些设备需要软件写入一个特殊寄存器,让它们知道它能够处理下一个中断。通过这种方式,设备可以实现通知的内部队列
键盘控制器的工作方式有点像这样,如果你读扫描码不够快,你只会丢失它们
如果设备随意频繁地触发中断,中断控制器可以缓冲请求,以免它们丢失
PIC和LAPIC最多可以缓冲一个请求,而另一个请求正在进行中(它们基本上使用这样一个事实,即每个中断都有一个请求寄存器和一个正在进行的寄存器)
因此,在连续三次中断的情况下,肯定会丢失一次。如果中断控制器因为正在进行更高优先级的中断而无法将第一个中断发送到CPU,那么将丢失两个中断。一般来说,软件除了中断控制器缓冲任何请求外,不会
因此,您不应该找到依赖于此的代码(毕竟,CS中唯一的数字是0、1和无穷大。因此,就软件而言,2并不存在)。

x86作为CPU核心,在处理中断时不支持优先级。如果中断没有被屏蔽,并且硬件中断到达,则为其提供服务。这取决于软件和中断控制器来确定中断的优先级
PIC和LAPIC(以及MSIs和IOAPIC)都赋予中断优先级,因此出于所有实际目的,x86支持基于优先级的中断机制。

然而,请注意,给予中断优先级并不一定好,很难判断网络数据包是否比按键更重要
因此,Linux的指导原则是在ISR中尽可能少地做工作,而将要异步处理的其余工作从ISR中排队。这可能意味着为了不阻止其他中断,只从ISR返回工作功能
在绝大多数情况下,只有一小部分代码需要在关键部分运行,这是一种不应发生其他中断的情况,因此通常的方法是将EOI返回到中断控制器,并尽早在CPU中取消屏蔽中断,然后编写代码,使其可以被中断。

如果出于性能原因需要停止另一个中断,通常采取的方法是将中断拆分到不同的核心,以便负载在所需的指标范围内
在多核系统普及之前,中断过多会有效地降低一些操作的速度
我想加载一个驱动程序是可能的,它会为了自己的性能拒绝其他中断,但这是一种QoS/实时要求,由用户来解决。

最新更新