本次我们了解一些除了iowait之外的问题,比如除了iowait,软中断就是一个常见的性能问题
我们就先看看什么是软中断
首先说,中断是一个常见的响应硬件设备请求的机制,会打断进程正常的调度和执行,然后调用内核的中断处理程序来响应设备的请求
那么,为何要有中断,中断的意义在什么?这需要我们拿一个生活中的例子进行查看,比如说订了一份外卖,但是并不知道外卖到的时间,那么就需要去苦苦等待外卖是不是到了
但是如果外卖到了的时候,让外卖员去打一个电话,那么就不需要苦苦等待了,就可以忙活别的事情,等待电话响
那么中断就是一种异步的事件处理机制,提高系统的并发处理能力
但是中断处理程序会打断其他进程的运行,减少正常进程的调度影响,中断处理程序就需要尽可能快的运行,如果中断本身要做的事情不多,那么处理起来并不会有问题,但是中断要处理的事情很多,中断服务程序就可能需要运行很长的时间
而且,中断程序在响应中断的时候,需要临时关闭中断,导致上一次中断处理完成之前,其他的中断都不能响应,导致中断可能丢失
以取外卖为例,如果订了2份外卖,第一份外卖电话到了,在电话中一直在商议发票开头,那么第二个外卖的电话可能就会出现打不通的情况
那么软中断就是为了应对上面的外卖处理方式,做出的系统中断机制,为了解决中断处理程序执行过长和中断丢失的问题,Linux将中断处理分为了两个阶段,也就是上部分和下半部
上半部分用于快速处理中断,在中断禁止模式下运行,处理和硬件紧密相关或者时间敏感的工作
下半部分用于延迟处理上半部分没有完成的任务,以内核线程的方式运行
举个例子,上半部分就是接电话,但是不商议发票抬头如何开,等待第二个配送员过来的时候,保证电话可以打通
对应到Unix系统中,网卡在收到数据包,会通过硬件中断的方式,通知内核有新的数据到了,内核就应该中断处理程序来响应其,那么这种情况下,上半部分和下半部分分别负责什么工作呢?
上半部分,就是快速处理程序,那么只需要将网卡数据读到内存,然后更新一下状态就可以了
下半部分,就是从内存中找到网络数据,按照网络协议栈,对数据进行逐层的解析和处理,知道送到应用程序
上半部分是直接处理硬件请求,也就是常说的硬中断,特点是快速执行
下半部分是内核触发的,软中断,特点是延迟执行
上半部分会打断CPU正在执行的任务,需要立刻执行,下半部分以内核线程的方式执行,每个CPU都对应一个软中断的内核线程
名字例如 ksoftirqd/CPU编号, 0号CPU对应的软中断内核名称就是 ksoftirqs/0
软中断不仅只包括硬件设备中断处理程序的下半部分,一些内核的自定义事件也属于软中断,比如内核调度和RCU锁
如何去查看软中断呢?
可以利用proc文件系统,是一种内核空间和用户空间
可以用来查看内核的数据结构,动态修改内核配置
在整个proc文件系统中
/proc/softirqs 中提供了软中断的运行情况
/proc/interrupts 提供了硬中断的运行情况
cat一下对应的 /proc/softirqs文件,我们可以看到各种类型软中断在CPU上的累计运行次数
$ cat /proc/softirqs
CPU0 CPU1 HI: 0 0 TIMER: 811613 1972736 NET_TX: 49 7 NET_RX: 1136736 1506885 BLOCK: 0 0 IRQ_POLL: 0 0 TASKLET: 304787 3691 SCHED: 689718 1897539 HRTIMER: 0 0 RCU: 1330771 1354737 |
软中断中,包含了10个类别,分别对应着不同的工作类型,NET_RX代表网络接收中断,NET_TX表示网络发送中断
在其中,NETRX 网络中断在不同cpu上的中断次数是同一个数量级,相差不大
TASKLET则不必同,因为TASKLET常见,所以每次TASKLET只会在调用它的函数的CPU上运行
这就导致了调度的不均匀,而且因为不能在多个CPU上并行运行,导致出现了性能限制
对于软中断的查看,直接使用ps命令就可以了,比如下面的指令
ps aux | grep softirq
对应的线程名字外面都有中括号,ps无法获取到对应的命令行参数
ps的输出中,名字在中括号中的,都是内核线程
Linux中的中断处理程序分为上半部和下半部
上半部对应硬件中断,处理快速中断
下半部对应软中断,异步处理上半部未完成的工作
Linux中的软中断包括网络收发,定时,调度 RCU锁等各种类型,可以通过查看 /proc/softirqs来观察软中断的运行情况
最后是软中断的理解
硬中断,就是常见的用户直接交互的输入,比如鼠标,键盘,如果不立即处理,会影响用户的使用,常见的可能是接受指令,设置一个标志位即可
软中断,则是在后台进行默默处理的,实际发力的进程
`