linux中的中断

在linux通常都出现一个服务在运行中突然中断了,或者在运行的一个程序超时了,然后中断了,那么在linux中的中断到底指的是什么呢?

中断(interrupt)被定义为一个事件,该事件改变处理器执行的指令顺序,这样的事件与CPU芯片内外部硬件电路产生的电信号相对应。

中断通常分为同步(synchronous)中断和异步(asynchronous)中断。

  • 同步中断指的是当指令执行时由CPU控制单元产生的,之所以称为同步,是因为只有在一条指令终止执行后CPU才会发出中断。

  • 异步中断是由其他硬件设备依照CPU时钟信号随机产生的。

但是在Intel处理器中,把同步中断和异步中断分别称为异常(exception)和中断(interrupt). 而且在开发中,我们也使用中断信号来统称中断和异常。

中断是由间隔定时器和I/O设备产生的,例如,用户的一次按键会引起一个中断,虽然用户没有感觉,但是按键这个过程到下一次按键之间的间隔对于计算机指令时间来说是非常长的。

但是异常是由程序的错误产生的,或者由内核必须处理的异常条件产生的。第一种情况下,内核通过发送一个每个Unix程序员都熟悉的信号来处理异常,第二种情况下,内核执行恢复异常需要的所有步骤,例如缺页异常。

而且呢,中断是由间隔定时器和I/O设备产生的,例如,用户的一次按键会引起一个中断,虽然用户没有感觉,但是按键这个过程到下一次按键之间的间隔对于计算机指令时间来说是非常长的。

中断处理是由内核执行的最敏感的任务之一,因此它必须满足下面的约束:

当内核正打算去完成一些别的事情时,中断会随时到来。因此,内核的目标就是让中断尽可能快的处理完,尽其所能把更多的处理向后推迟。例如一个数据块已经到达了网线,当硬件中断内核时,内核只简单的标志数据到来了,让处理器恢复到它以前的运行状态,其余的处理稍后再进行。因此,内核响应中断后需要进行的操作氛围两部分,关键而紧急的部分内核立即执行,其他的推迟的部分内核随后会执行。

因为中断随时到来,所以内核可能正在处理其中一个中断的时候,另一个中断又会到来,应该尽可能多的允许这样的情况发生,因为这能维持更多的I/O设备处于忙状态,提高I/O设备的吞吐量。因此中断处理程序必须便写成使相应的内核控制路径能以嵌套的方式执行。当最后一个内核控制路径终止时,内核必须能恢复被中断执行的进程。

尽管内核在处理前一个中断时可以接受一个新的中断,但在内核代码中还是存在一些临界区,在临界区中,中断必须被禁止。必须尽可能的限制这样的临界区,因为根据以前的要求,内核,尤其时中断处理程序,应该在大部分时间内以开中断的方式运行。

查看Intel文档,可以看到里面把中断和异常分为了以下几类:

中断

中断这里分为了两类:

  • 可屏蔽中断,I/O设备发出的所有中断请求(IRQ)都产生可屏蔽中断,一个屏蔽的中断只要还是屏蔽的,控制单元就可以忽略它。
  • 非屏蔽中断,有一些危险的事件才能引起非屏蔽中断,例如硬件故障,非屏蔽中断总是由CPU辨认。

异常

通常当CPU执行指令时探测到一个异常,会产生一个处理器探测异常(processor-detected exception),可以进一步区分,这取决于CPU控制单元产生异常时保存在内核堆栈eip寄存器的值。

  • 故障(fault),通常可以纠正,一旦纠正,程序就可以重新开始,保存在eip寄存器中的值是引起故障的指令地址。
  • 陷阱(trap)在陷阱指令执行后立即报告,内核把控制权烦给程序后就可以继续它的执行而不失连续性。保存在eip中的值是一个随后要执行的指令地址。陷阱的主要作用是为了调试程序。
  • 异常中止(abort),发生一个严重的错误,控制单元出了问题,不能在eip寄存器中保存引起异常的指令所在的确切位置。异常中止用于报告严重的错误,例如硬件故障或系统表中无效的值或者不一致的值。这种异常会强制中止进程。
  • 编程异常(programmed exception),在编程者发出的请求时发送,是由int或int3指令触发的。

每个中断和异常是由0~255之间的一个数来标识的,Intel把这个8位无符号整数叫做一个向量(vector)。非屏蔽中断的向量和异常的向量是固定的,而可屏蔽中断的向量是可以通过对中断控制器的编程来改变。

在X86中,分为实模式和保护模式,实模式通常是CPU启动到BIOS再到操作系统启动前的这段时间,操作启动初始化完成进入到保护模式。在不同模式下中断的处理机制同步,在这里只简单探讨一下保护模式下的中断机制。

通常, 硬件中断发生频繁,将会是一件很消耗 CPU 资源的事情,Linux 默认情况下是将所有的硬件中断都绑定在 CPU0 上,在多核 CPU 条件下如果有办法把大量硬件中断分配给不同的 CPU (core) 处理显然能很好的平衡性能。

其中:

  • /proc/softirqs 提供了软中断的运行情况.
  • /proc/interrupts 提供了硬中断的运行情况.