2012-07-09 148 views

回答

3

86跳转到相应的中断向量禁止所有的本地中断(当然除了NMI)。除非特定的标志被传递给中断处理程序注册,否则Linux通常会屏蔽特定的中断并重新启用其余中断(未被屏蔽)。

请注意,虽然这意味着您的中断处理程序不会在同一个CPU上与自身竞争,但它可以并将与在SMP/SMT系统中的其他CPU上运行的本身竞争。

+0

您能否提供声明来源“x86在禁止所有本地中断前跳到中断向量”?我有英特尔3卷体系结构文档和8259A文档。我无法找到任何告诉我中断在跳转到中断向量之前被自动禁止的情况,即在进入ISR(中断服务程序/中断处理程序过程)时 – amn 2015-03-17 22:55:32

+2

不严格的HW行为 - 问题在linux内核。 LAPIC的行为是可编程的,但这是Linux编程的方式 - 所有的中断具有相同的优先级,所以一个阻塞另一个,但Linux软件在中断处理程序运行之前很快重新启用中断。 – gby 2015-03-19 08:43:41

+0

我后来在“Intel 64 and IA-32 Arch.Developer's Manual”,p。389中找到了有关“默认”x86硬件行为的提及。 6-10 Vol。 1:“如果中断或异常处理程序通过中断门调用 ,则处理器清除EFLAGS寄存器中的中断允许(IF)标志,以防止后续中断干扰处理程序的执行。”感谢您解决与Linux有关的问题。 – amn 2015-03-21 14:20:32

2

通常(至少在x86中),中断会禁止中断。

当收到中断时,硬件执行以下操作:
1.将所有寄存器保存在预定位置。
2.将指令指针(AKA程序计数器)设置为中断处理程序的地址。
3.将控制中断的寄存器设置为禁用所有(或大部分)中断的值。这可以防止另一个中断打断这个中断。

NMI(不可屏蔽中断)是一个例外,它不能被禁用。

+4

来自Linux内核开发 ** Linux中的中断处理程序不需要是可重入的。当一个给定的中断处理程序正在执行时,相应的中断线在所有处理器上被屏蔽掉,从而防止接收到同一线上的另一个中断。通常所有其他中断都被使能,所以其他中断服务,但当前行总是被禁止。因此,不会同时调用同一个中断处理程序来服务嵌套中断。这极大地简化了您的中断处理程序的编写。** 因此,只有当前中断线被屏蔽。 – Harman 2012-07-10 18:26:06

+0

@Harman,这意味着只有当前中断线保证被屏蔽。我很确定x86上的实际实现是将它们全部掩盖起来。 – ugoren 2012-07-11 10:42:24

1

是的,没关系。 我想添加我认为可能相关的内容。

在许多真实世界的驱动程序/内核代码中,“下半部”(bh)处理程序经常使用 - tasklets,softirqs。这些bh运行在中断上下文中,并且可以与它们在SMP(esp softirq's)上的上半部分(th)处理程序并行运行。当然,最近有一个举措(主要是代码从PREEMPT_RT项目迁移到主线),基本上摆脱了'bh'机制 - 所有中断处理程序将在所有中断禁用的情况下运行。不仅如此,处理程序(可以)转换为内核线程 - 这些是所谓的“线程化”中断处理程序。

截至今天,选择仍留给开发人员 - 您可以使用'传统'th/bh风格或线程风格。

参考和详细信息:

http://lwn.net/Articles/380931/

http://lwn.net/Articles/302043/

0

引用英特尔的自己,令人惊讶的精心编写的“英特尔®64和IA-32架构软件开发人员手册”,第1卷,页6-10:

如果中断或异常处理程序被调用 通过一个中断门,处理器清除EFLAGS寄存器中的中断使能(IF)标志,以防止随后的中断干扰处理程序的执行。当通过陷阱 调用处理程序时,IF标志的状态不会改变。

所以只是要清楚 - 是的,实际上CPU在调用中断处理程序之前“禁用”所有中断。恰当地描述,处理器只是触发一个标志,使其忽略所有中断请求。除了可能不可屏蔽的中断和/或它自己的软件异常(请有人纠正我,未验证)。

0

我们希望ISR是原子的,没有人应该能够抢占ISR。因此,ISR禁止本地中断(即当前处理器上的中断),并且一旦ISR调用ret_from_intr()函数(即,我们已经完成ISR),则在当前处理器上再次启用中断。

如果发生中断,它将由另一个处理器(在SMP系统中)提供服务,并且与该中断相关的ISR将开始运行。

在SMP系统中,我们还需要在ISR中包含适当的同步机制(自旋锁定)。

+1

您能否详细说明您的答案,并添加关于您提供的解决方案的更多描述? – abarisone 2015-09-22 12:01:52

相关问题