在调用中断处理程序之前,CPU是否禁用本地CPU上的所有中断? 或者它是否仅禁用正在服务的特定中断线?
答案 0 :(得分:3)
x86在跳转到中断向量之前禁用所有本地中断(当然除了NMI)。 Linux通常会屏蔽特定的中断并重新启用其余的中断(未被屏蔽),除非将特定的标志传递给中断处理程序注册。
请注意,虽然这意味着您的中断处理程序不会在同一个CPU上自行竞争,但它可以并且将在SMP / SMT系统中的其他CPU上运行。
答案 1 :(得分:2)
通常(至少在x86中),中断会禁止中断。
当收到中断时,硬件会执行以下操作:
1.将所有寄存器保存在预定位置
2.将指令指针(AKA程序计数器)设置为中断处理程序的地址
3.将控制中断的寄存器设置为禁用所有(或大多数)中断的值。这可以防止另一个中断中断此中断。
异常是NMI(不可屏蔽中断),无法禁用。
答案 2 :(得分:1)
是的,没关系。 我还要添加我认为可能相关的内容。
在许多现实世界的驱动程序/内核代码中,经常使用“下半部”(bh)处理程序 - tasklet,softirqs。这些bh在中断上下文中运行,可以与SMP上的上半部分处理程序(esp softirq)并行运行。
当然,最近有一个移动(主要是从PREEMPT_RT项目迁移的代码)转向主线,基本上摆脱了'bh'机制 - 所有中断处理程序都将在禁用所有中断的情况下运行。不仅如此,处理程序(可以)转换为内核线程 - 这些是所谓的“线程”中断处理程序。
截至今天,选择仍由开发人员决定 - 您可以使用'传统'th / bh样式或线程样式。
参考和细节:
答案 3 :(得分:0)
引用英特尔拥有的,令人惊讶的精心编写的“英特尔®64和IA-32架构软件开发人员手册”,第1卷,第6-10页:
如果调用中断或异常处理程序 通过中断门,处理器清除EFLAGS寄存器中的中断允许(IF)标志以防止 后续中断干扰处理程序的执行。通过陷阱调用处理程序时 门,IF标志的状态不会改变。
所以只是要清楚 - 是的,有效的CPU在调用中断处理程序之前“禁用”所有中断。正确描述,处理器只是触发一个标志,使其忽略所有中断请求。除了可能不可屏蔽的中断和/或它自己的软件例外(请有人在此纠正我,未经验证)。
答案 4 :(得分:0)
我们希望ISR是原子的,没有人能够抢占ISR。
因此,ISR禁用本地中断(即当前处理器上的中断),一旦ISR调用ret_from_intr()函数(即我们已完成ISR),就会在当前处理器上再次启用中断。
如果发生中断,它将由另一个处理器(在SMP系统中)提供服务,并且与该中断相关的ISR将开始运行。
在SMP系统中,我们还需要在ISR中包含适当的同步机制(自旋锁)。