1. 中断是什么?

在计算机中,中断是 系统用来响应硬件设备请求 的一种机制。操作系统收到 硬件的中断请求后,会打断正在执行的进程,然后调用内核中的 中断处理程序 来响应请求。
中断是⼀种 异步的事件处理机制可以提高系统的 并发处理能力
操作系统收到了中断请求后,会打断其他进程的运行。所以中断请求的 响应程序,也就是中断处理程序,要尽可能快的执行完,这样可以减少 对正常进程运行调度 的影响。
而且,中断处理程序在响应中断时,可能还会"临时关闭中断"。这意味着,在中断处理程序  执行完之前,系统中其他的中断请求 都无法被响应,也就是说 中断有可能会丢失,所以中断处理程序 要短且快。

2. 什么是软中断?

在Linux系统中,为了解决中断处理程序 执行时间过长和中断丢失 的问题,将中断过程分成了两个阶段:上半部下半部分
  • 上半部直接处理硬件请求,也就是硬中断,主要是负责耗时短的⼯作,特点是快速执⾏。(⼀般会暂时 关闭中断请求,处理与 硬件紧密相关或者时间敏感 的事情
  • 下半部由内核触发,也就是软中断,主要是负责上半部未完成的⼯作,通常都是耗时较长的事情,特点是延迟执行。(⼀般以 内核线程 的方式运行)
区别:硬中断(上半部) 会先打断 CPU正在执行的任务,然后执行中断处理程序软中断(下半部) 以内核线程的方式执行,每一个CPU 都对应一个软中断内核线程,名字通常为 "ksoftirqd / CPU编号"。(比如:0号CPU对应的 软中断内核线程的名字是ksoftirqd/0)
软中断不仅包括 硬件设备中断处理程序的下半部分,⼀些内核的自定义事件 也属于软中断。(比如:内核调度、RCU锁 等)

3.系统中有哪些软中断?

在Linux系统中,可以通过 cat /proc/softirqs命令 查看软中断的运行情况;通过 cat /proc/interrupts命令 查看硬中断的运行情况。

可以看到,每个CPU都有自己对应的 不同类型软中断的累计运行次数。以下3点需要注意:
  • 第⼀列的内容代表 软中断的类型。在该系统中,软中断包括了 10 个类型,分别对应不同的⼯作类型。(比如:NET_RX 表示网络接收中断,NET_TX 表示网络发送中断、TIMER 表示定时中断、RCU 表示RCU锁中断、SCHED 表示内核调度中断)
  • 正常情况下,同⼀种中断在不同CPU上 的累计次数相差不大。(比如:该系统中,NET_RX在 CPU0、CPU1、CPU2、CPU3 上的中断次数 基本是同⼀数量级,相差不大)
  • 这些数值是 系统自运行以来的累计中断次数,数值本身 没什么参考意义,但系统中的 中断次数的变化速率 是需要关注的。可以使用 watch -d cat /proc/softirqs命令 查看中断次数的变化速率
前面提到,软中断是以 内核线程的方式 执行的,可以使用 ps命令 查看软中断内核线程的结果

可以发现,内核线程的名字外⾯ 都有中括号,这说明 ps命令 无法获取它们的命令行参数,所以⼀般来说,名字在中括号中的线程 都可以认为是内核线程。而且,可以看到有4个 ksoftirqd内核线程,这是因为这台服务器的CPU 是4核心的,每个CPU核心 都对应着⼀个内核线程。

4. 如何定位软中断 CPU 使用率过高的问题?

可以使用 top命令 查看系统中的软中断情况。

黄色部分si 就是CPU在软中断上的使用率。可以发现,所有CPU的使用率 都不高 (id 表示空闲CPU的百分比),Cpu0和Cpu1的使用率 只有3%和4%左右,并且都用于软中断。另外,CPU使用率最高的进程 也是软中断ksoftirqd ,因此可以认为 此时的系统开销主要来源于软中断。
如果想要知道 是哪种软中断类型导致的,可以使用 watch -d cat /proc/softirqs命令 查看每个软中断类型的 中断次数的变化速率。

对于网络I/O较高的 Web服务器,NET_RX网络接收中断 的变化速率 相比其他中断类型快很多。
如果发现 NET_RX网络接收中断 次数的变化速率过快,可以使用 sar -n DEV命令 查看网卡的网络包接收速率,然后分析 是哪个网卡有大量的网络包进来。

再通过 tcpdump 抓包,分析这些数据包的来源。如果是非法的地址,可以考虑增加"防火qiang";如果是正常流量,则要考虑硬件升级等。