浅谈中断
以前每次看到中断,就觉得很神秘,后面随着学习和了解,有了大概的了解,来浅谈下中断。
一 中断的定义
我们来想下,计算机中的各个设备的运行速度差异非常大,特别是CPU和外设,为了整体性能的提升,CPU在工作的时候显然不能停下来等着外部设备操作完毕。比如我们CPU读磁盘文件的时候,不可能等数据读取结束了,而是CPU切换到其他线程上继续执行。
那当外部磁盘完成了读数据之后,一般是将磁盘数据拷贝到内核缓存之后,需要通知CPU,告速它,”嘿,你要的数据准备好了,可以继续了!“ 这种通知机制,就是中断。
磁盘控制器,网络适配器和定时芯片,都可以发生中断,这些芯片通过向CPU的一个管脚发信号,并将异常号放到系统总线上。当CPU执行完毕当前的一条指令后,发现管脚的电压变高了,就从系统总线上读取异常信号,然后调用中断的处理程序,处理完成后返回原来的指令流,继续执行。
这样理解中断,即是将正在执行的指令暂停,执行相关的中断处理程序,有了中断,我们就可以让CPU相应外部的输入。
二 软中断和硬中断
关于软中断和硬中断,极客时间《Linux性能优化和实战》中有一个非常恰当的例子,就是收外卖。
比如你定了一份外卖,你不知道什么时候来,而且没有公共放外卖的地方。如果没有”中断“,那就需要一直门口等着,是不是看看外卖来了没有。
如果你和外卖员约定好,你到小区门口就给我打电话,这样你就可以暂时不管外卖继续做你该做的事情,然后外卖人员到门口给你打电话(发生了中断) ,你就可以下来拿外卖了。所以中断其实是一种异步的事件处理机制,可以提高系统的并发处理能力。
这里面,外卖人员给你打电话的时候就相当于发生了中断,接电话的时间相当于中断处理时间,在接电话的时候,如果你同时定了其他外卖,其他外卖人员也给你打电话的时候,你就无法接了这个外卖人员的电话,这就相当于我们在处理中断的时候,同时关闭了中断响应(防止破坏上下文)。
所以中断处理程序必须快,但是有的中断, 需要很长的时间来处理中断,对于这种情况,将中断分成上半部分和下半部分。
- 上半部分,直接处理硬件请求,要求执行速度快,称为硬中断。
- 下半部分,由内核触发,处理中断的下半部分,称为软中断。
比较典型的场景,网络收包的时候,网卡通过DMA技术将网络包反倒内核的ring buffer中,然后发起硬中断,硬中断处理程序从ring buffer取出来,构造sk_buff放入到backlog队列中。更新硬件寄存器状态,同时发出软中断。内核软中断线程遍历到当前的网络软中断,从网络协议栈的底层向上对数据包进行处理,然后把它放进队列中,等应用层程序调用recv处理。
在网络收包的过程中,如果包都是很小的包,又是高吞吐量的环境,导致短时间内有大量的包,显然,会发生大量的硬中断和软中断,这些中断都会占用CPU,限制了网络的吞吐量,对于这种情况linux的NAPI,每次中断时候不只处理一个网络包,而是不断轮询设备队列,直到队列为空。更极端的例子是DPDK这个高性能网络包处理库,则是采用一直轮询的方式来达到不需要中断,快速进行包处理的目的,这也造成了DPDK的轮询模式下CPU占据100%的现象。
三 实践
上次在top命令介绍中,我们可以从top命令中看到软中断和硬中断所占的CPU:
top中的中断显示
查看Linux下软中断情况:
cat /proc/softirqs
查看linux下硬中断情况:
cat /proc/interrupts
如果仅仅这样看,是看不到变化的,可以采用以下命令查看:
watch cat /proc/softirqs
watch cat /proc/interrupts
查看下硬中断:
硬中断
其中:
- 第一列:0,8,9这些代表不同的中断号,系统为不同的请求分配不同的中断号。越小优先级越高。
- 第二列-第五列 表示这个中断在不同cpu上的计数。
- 第六列 可编程中断控制器
- 第七列 设备名
四 网络收包中的中断
网络收包的时候,会发生硬中断和软中断,如果设置不好,也会影响到收包的性能。这种问题可以这样去查:
- 先查看各个cpu的具体占用情况:
[root@localhost ~]# mpstat -P ALL 1
Linux 3.10.0-693.el7.x86_64 (localhost.localdomain) 06/22/2020 _x86_64_ (4 CPU)
11:00:00 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
11:00:01 PM all 2.76 0.00 0.25 0.00 0.00 0.00 0.00 0.00 0.00 96.98
11:00:01 PM 0 4.95 0.00 0.99 0.99 0.00 0.00 0.00 0.00 0.00 93.07
11:00:01 PM 1 3.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 97.00
11:00:01 PM 2 1.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 98.00
11:00:01 PM 3 2.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 98.00
通过此命令查看irq和soft 即硬中断和软中断在各个cpu占用上是否均衡。
如果irq的不均衡,集中在特定的cpu上,需要查看下具体的硬中断类型。
watch cat /proc/interrupts
通过以上命令,来查看cpu上不同的硬中断的数量上,配合mpstat
命令就知道是哪个中断号引起的了。
假设是44号中断引起的,我们就可以看下 此中断号对应的处理cpu:
[root@localhost ~]# cat /proc/irq/44/smp_affinity
02
通过这个值,我们就可以知道这个中断是在2号cpu上处理的,smp_affinity值哪一位为一,就是标识哪个cpu处理,可以同时被多个cpu处理,这就达到中断均衡的目的。
假如我们先让2个cpu,1号cpu和2号cpu同时处理此中断用以下命令即可达到目的
echo 3> /proc/irq/44/smp_affinity
如果是多个cpu,比如64个,我们先让网络的收包中断均衡到这些cpu上,可以在网上找一个set_irq_affinity 的脚本(找不到可以联系我)执行下面命令,将0,2,4,6等32个cpu绑定到p1p1的中断上。
set_irq_affinity 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62 p1p1
注意这种指定cpu方式,需要关闭中断自动均衡程序:
service irqbalance stop
service irqbalance status
五诗词欣赏
登科后
- 唐 孟郊
昔日龌龊不足夸,今朝放荡思无涯。
春风得意马蹄疾,一日看尽长安花。