中断是什么?
中断是系统用来响应硬件设备请求的一种机制,操作系统收到硬件的中断请求,会打断正在执行的进程,然后调用内核中的中断处理程序来相应请求。
中断好比外卖打电话,打了电话可以停下手中的事情
中断是一种异步的事件处理机制,可以提高系统的并发处理能力。
操作系统收到了中断请求,会打断其他进程的运行,所以中断请求的相应程序,也就是中断处理程序,要尽可能快的执行,减少对正常进程运行调度的影响。
中断处理程序在相应中断时,还会[临时关闭中断],如果当前中断处理程序没有执行完之前,系统中其他的中断请求都无法被响应,也就是说中断有可能会丢失,所以中断处理程序要短且快。
什么是软中断?
Linux系统为了解决中断处理程序执行过长和中断丢失问题,将中断过程分为了两个阶段,分别是[上半部和下半部]。
- 上半部用来快速处理中断,一般会暂时关闭中断请求,主要负责处理跟硬件紧密相关或者时间敏感的事情。[打电话告诉配送员我正在下楼]
- 下半部用来延迟处理上半部未完成的工作,一般以[内核线程]的方式运行。[下楼后跟配送员说其他事情]
举例:网卡接受网络包,通过DMA方式将接收到的数据写入内存,通过硬件中断通知内核有新的数据到了,于是内核就会调用对应的中断处理程序来处理程序来处理事件,这个事件的处理也会分成上半部分和下半部分。
上半部分,会禁止网卡中断,避免频繁硬中断,而降低内核的工作效率。
接着,内核会触发一个软中断,把一些处理比较耗时复杂的事情,交给[软中断处理程序]去做,也就是中断的下半部,主要是需要从内存中找到网络数据,在按照网络协议栈,对网络数据进行逐层解析和处理,最后把数据送给应用程序。
所以中断处理程序的上半部分和下半部分可以理解为:
- 上半部直接处理硬件请求,也就是硬中断,主要是扶着耗时短的工作,特点是快速执行。
- 下半部是由内核触发,也就是软中断,主要负责上半部未完成的工作,通常都是耗时比较长的事情,特点是延迟执行;
区别:硬中断会大段CPU正在执行的任务,然后立即执行中断处理程序,而软中断是以内核线程的方式执行,每一个CPU都对应一个软中断内核线程,名字通常为[ksoftirqd/CPU编号],比如0号CPU对应的软中断内核线程的名字是ksoftirqd/0。
不过,软中断不只是包括硬件设备中断处理程序的下半部,一些内核自定义事件也属于软中断,比如内核调度,RCU锁等。
系统里有哪些软中断?
/proc/softirqs知晓软中断的运行情况
/proc/interrupts知晓硬中断的运行情况
NET_RX:网络接受中断
NET_TX:网络发送中断
TIMER:定时中断
RCU:RCU锁中断
SCHED:内核调度中断
关注系统的中断次数的变化速率,使用watch -d cat /proc/softiqs命令查看
如何定位软中断CPU使用率过高的问题?
top命令,知道当前的系统的软中断的情况
si:CPU在软中断上的使用率
如果发现NET_RX网络接受中断次数的变化速率过快,接下来就可以使用sar -n DEV查看网卡的网络包接受速率情况,然后分析是哪个网卡有大量的网络包进来。
通过tcpdump抓包,分析包的来源,如果是非法地址,考虑加防火墙,如果是正常流量,考虑硬件升级。
总结
为了避免由于中断处理程序执行时间过长,而影响正常进程的调度,Linux 将中断处理程序分为上半部和下半部:
- 上半部,对应硬中断,由硬件触发中断,用来快速处理中断;
- 下半部,对应软中断,由内核触发中断,用来异步处理上半部未完成的工作;
Linux 中的软中断包括网络收发、定时、调度、RCU 锁等各种类型,可以通过查看 /proc/softirqs 来观察软中断的累计中断次数情况,如果要实时查看中断次数的变化率,可以使用 watch -d cat /proc/softirqs 命令。
每一个 CPU 都有各自的软中断内核线程,我们还可以用 ps 命令来查看内核线程,一般名字在中括号里面到,都认为是内核线程。
如果在 top 命令发现,CPU 在软中断上的使用率比较高,而且 CPU 使用率最高的进程也是软中断 ksoftirqd 的时候,这种一般可以认为系统的开销被软中断占据了。
这时我们就可以分析是哪种软中断类型导致的,一般来说都是因为网络接收软中断导致的,如果是的话,可以用 sar 命令查看是哪个网卡的有大量的网络包接收,再用 tcpdump 抓网络包,做进一步分析该网络包的源头是不是非法地址,如果是就需要考虑防火墙增加规则,如果不是,则考虑硬件升级等。