中断处理程序使用哪个堆栈 - Linux

Which stack is used by Interrupt Handler - Linux

在多任务系统中,当任何硬件生成对特定 CPU 的中断时,其中 CPU 可以执行以下任一情况,除非它已经在服务 ISR:

  1. 用户模式进程正在 CPU
  2. 上执行
  3. 内核模式进程正在 CPU
  4. 上执行

想知道在以上两种情况下中断处理程序使用了哪个堆栈,为什么?

Interrupts 仅由内核处理。所以使用了一些内核堆栈(在两种情况下)。

中断不会(直接)影响用户 processes

进程可能会 signals, but these are not interrupts. See signal(7)...

所有中断都由内核处理。这是由为特定中断编写的中断处理程序完成的。对于中断处理程序,有 IRQ 堆栈。中断处理程序堆栈的设置是配置选项。内核堆栈的大小可能并不总是足以满足内核工作需要 space IRQ 处理例程。因此 2 stack 出现了。

  1. 硬件 IRQ 堆栈。
  2. 软件 IRQ 堆栈。

与按进程分配的常规内核堆栈相比,两个额外的堆栈按 CPU 分配。每当发生硬件中断(或处理软IRQ)时,内核需要切换到 适当的堆栈。 从历史上看,中断处理程序没有收到自己的堆栈。相反,中断处理程序将共享 运行 进程的堆栈,它们被中断了。内核堆栈有两页大小;通常,在 32 位架构上为 8KB,在 64 位架构上为 16KB。因为在此设置中,中断处理程序共享堆栈,所以它们必须非常节俭地分配在那里的数据。当然,内核堆栈是有限的,所以所有内核代码都应该谨慎。

从历史上看,中断处理程序没有收到自己的堆栈。 相反,他们会共享他们中断的进程的堆栈。 请注意,进程始终为 运行。当没有其他可调度时,空闲任务运行。

内核堆栈大小为两页:

32 位架构上为 8KB。

64 位架构上为 16KB。

由于共享堆栈,中断处理程序必须非常节俭地分配在那里的数据。

在2.6内核进程的早期,增加了一个选项将堆栈大小从两页减少到一页,在32位系统上只提供4KB的堆栈,并且中断处理程序被赋予了自己的堆栈,每个堆栈一个处理器,一页大小。该堆栈称为中断堆栈。

尽管中断堆栈的总大小是原始共享堆栈的一半,但可用的平均堆栈 space 更大,因为中断处理程序将整页内存占为己有,因为以前每个进程都在系统需要两页连续的、不可交换的内核内存。 您的中断处理程序不应该关心正在使用的堆栈设置或内核堆栈的大小。始终使用绝对最小数量的堆栈 space

https://notes.shichao.io/lkd/ch7/#stacks-of-an-interrupt-handler