中断处理程序使用哪个堆栈 - Linux
Posted
技术标签:
【中文标题】中断处理程序使用哪个堆栈 - Linux【英文标题】:Which stack is used by Interrupt Handler - Linux 【发布时间】:2015-04-29 19:41:06 【问题描述】:在多任务系统中,当任何硬件对特定 CPU 产生中断时,CPU 可以执行以下任何一种情况,除非它已经在为 ISR 提供服务:
-
用户模式进程正在 CPU 上执行
内核模式进程正在 CPU 上执行
想知道上述两种情况下中断处理程序使用哪个堆栈以及为什么?
【问题讨论】:
在 Wikipedia 上查找会比在这里询问要快。 【参考方案1】:所有中断都由内核处理。这是由为该特定中断编写的中断处理程序完成的。对于中断处理程序,有 IRQ 堆栈。中断处理程序堆栈的设置是配置选项。内核堆栈的大小可能并不总是足够内核工作和所需的空间 IRQ 处理例程。因此 2 堆栈进入画面。
-
硬件 IRQ 堆栈。
软件 IRQ 堆栈。
与每个进程分配的常规内核堆栈相比,每个 CPU 分配两个额外的堆栈。每当发生硬件中断(或处理 softIRQ)时,内核需要切换到 适当的堆栈。 从历史上看,中断处理程序没有收到自己的堆栈。相反,中断处理程序将共享正在运行的进程的堆栈,它们被中断。内核堆栈大小为两页;通常,在 32 位架构上为 8KB,在 64 位架构上为 16KB。因为在此设置中,中断处理程序共享堆栈,所以它们必须非常节俭地分配在那里的数据。当然,内核堆栈一开始是有限的,所以所有内核代码都应该谨慎。
【讨论】:
嗯,我的理解是只有一个中断堆栈。您有“软件 IRQ 堆栈”和“硬件 IRQ 堆栈”的来源吗? @srd 我有几个参考。请通读:1.了解Linux内核:第4章中断处理books.google.co.in/… 2.专业Linux内核架构:第14章3.***问题:***.com/questions/28115819/… 这在一定程度上回答了。我实际上正在查看当前执行的任务是用户/内核时会发生什么。但是我自己找到了答案。如果中断要在用户级别执行,则 TSS 堆栈切换发生到其相应的内核堆栈,如果它在与内核相同的特权级别执行,则使用中断的内核堆栈。 知道如果堆栈溢出发生在内核级中断处理函数中会发生什么吗?在这种情况下,注册的异常处理程序将被调用? 如果通过中断门调用中断或异常处理程序,处理器会清除 EFLAGS 寄存器中的中断使能 (IF) 标志,以防止后续中断干扰处理程序的执行。 ISR 必须是原子的,并且没有人应该能够抢占 ISR。因此,除 NMI 外,本地 CPU 上的所有中断都被禁用。当一个给定的中断处理程序正在执行时,相应的中断线在所有处理器上被屏蔽,防止接收到同一条线上的另一个中断。通常所有其他中断都在其他 CPU 上启用。【参考方案2】:Interrupts 仅由内核处理。所以它是一些使用的内核堆栈(在这两种情况下)。
中断不会(直接)影响用户processes。
进程可能会得到signals,但这些不是中断。见signal(7)...
【讨论】:
我不知道是否有人回答我,但我要求一些东西。如果中断处理程序允许进一步的中断并导致内核堆栈溢出怎么办......这种情况的解决方案是什么?【参考方案3】:从历史上看,中断处理程序不接收自己的堆栈。 相反,他们将共享他们中断的进程的堆栈。 请注意,一个进程始终在运行。当没有其他可调度时,空闲任务运行。
内核堆栈大小为两页:
32 位架构为 8KB。
64 位架构为 16KB。
由于共享堆栈,中断处理程序必须非常节俭地分配在那里的数据。
在 2.6 内核进程的早期,添加了一个选项以将堆栈大小从两页减少到一页,在 32 位系统上仅提供 4KB 堆栈,并且为中断处理程序提供了自己的堆栈,每个处理器一个堆栈,一页大小。这个堆栈被称为中断堆栈。
虽然中断堆栈的总大小是原始共享堆栈的一半,但平均可用堆栈空间更大,因为中断处理程序将整页内存留给自己,因为以前系统上的每个进程都需要两页连续的、不可交换的内核内存。 您的中断处理程序不应该关心正在使用的堆栈设置或内核堆栈的大小。始终使用绝对最小量的堆栈空间
https://notes.shichao.io/lkd/ch7/#stacks-of-an-interrupt-handler
【讨论】:
以上是关于中断处理程序使用哪个堆栈 - Linux的主要内容,如果未能解决你的问题,请参考以下文章