/proc/softirqs + /proc/interrupts

这一节讲:

硬中断、软中断,以及为什么 softirq 高通常和网络包处理压力有关。

这是性能监控项目里比较有“系统味”的部分。你的项目源里也把 CPU stat、softirq、eBPF TC Hook、BPF map 作为底层机制重点,要求回答时能讲清楚 Worker 端如何采集这些指标并上报 Manager。


1. 先分清:硬中断和软中断

1.1 硬中断是什么

硬中断就是硬件设备打断 CPU。

比如:

网卡收到数据包
磁盘 I/O 完成
键盘输入
定时器到期

硬件会通知 CPU:

CPU 正在执行普通代码
    ↓
硬件发出 interrupt
    ↓
CPU 暂停当前任务
    ↓
进入中断处理程序
    ↓
处理完再回去

小白理解:

硬中断就是“硬件有急事,直接打断 CPU”。


1.2 软中断是什么

硬中断不能做太多事情,因为它会打断 CPU 当前执行流程。如果硬中断处理太久,系统响应会变差。

所以 Linux 常用一种机制:

硬中断里只做紧急、少量工作
    ↓
把后续较重的工作丢给软中断
    ↓
软中断稍后继续处理

小白理解:

软中断是硬中断的“后半段处理机制”。


2. 网络包处理里的硬中断和软中断

这是最重要的链路。

网卡收到包时,大致过程是:

网卡收到数据包
    ↓
触发硬中断
    ↓
CPU 进入网卡驱动的中断处理
    ↓
硬中断里只做少量工作,例如通知内核有包来了
    ↓
后续大量包处理交给 NET_RX softirq
    ↓
内核网络协议栈继续处理包

所以网络高并发时,经常看到:

rx_packets 很高
rx_pps 很高
    ↓
NET_RX softirq 增长很快
    ↓
CPU 的 softirq 时间上升

这就是为什么:

softirq 高,经常说明网络包处理压力大。

不是绝对,但非常常见。


3. /proc/interrupts 看什么

执行:

cat /proc/interrupts

可能看到类似:

           CPU0       CPU1
  0:         34          0   IO-APIC   2-edge      timer
  1:          2          0   IO-APIC   1-edge      i8042
 24:     123456      98765   PCI-MSI   eth0
 25:      54321      67890   PCI-MSI   nvme0q0

它主要看:

每个硬中断号
每个 CPU 上处理了多少次
中断来源是什么

常见来源:

来源说明
timer定时器中断
eth0 / 网卡名网卡中断
nvme / sda磁盘设备中断
i8042键盘/鼠标相关
IPICPU 间中断

如果某个网卡对应的中断数增长很快,说明网卡收发包比较频繁。


4. /proc/softirqs 看什么

执行:

cat /proc/softirqs

可能看到:

                    CPU0       CPU1
          HI:          0          0
       TIMER:    1234567    1200345
      NET_TX:       1234       1567
      NET_RX:     987654     876543
       BLOCK:      12345      23456
    IRQ_POLL:          0          0
     TASKLET:      45678      34567
       SCHED:     234567     245678
     HRTIMER:          0          0
         RCU:     345678     356789

你第一阶段重点记:

NET_RX
NET_TX
TIMER
BLOCK
SCHED
RCU
类型含义重点
NET_RX网络接收方向软中断收包压力
NET_TX网络发送方向软中断发包压力
TIMER定时器软中断定时任务、内核定时器
BLOCK块设备相关软中断磁盘 I/O
SCHED调度相关软中断调度压力
RCURCU 机制相关内核同步机制

对你的项目来说,最重要的是:

NET_RX
NET_TX

5. /proc/softirqs 也是累计值

这一点和 /proc/stat、/proc/diskstats、/proc/net/dev 一样。

比如:

NET_RX:  987654  876543

它不是“当前每秒处理了多少软中断”。

它表示:

从系统启动以来
CPU0 处理过 987654 次 NET_RX softirq
CPU1 处理过 876543 次 NET_RX softirq

所以监控程序也要两次采样:

第一次读取 /proc/softirqs
    ↓
等待 interval 秒
    ↓
第二次读取 /proc/softirqs
    ↓
做差分
    ↓
计算每秒 softirq 增长次数

公式:

softirq_rate = (softirq_now - softirq_prev) / interval_seconds

例如:

第一次 NET_RX = 100000
第二次 NET_RX = 103000
间隔 1 秒

NET_RX rate = 3000 次/s

说明这一秒内处理了大约 3000 次网络接收软中断。


6. softirq 高说明什么

6.1 NET_RX 高

通常说明:

收包压力大
小包很多
网卡接收方向压力大
内核协议栈处理压力大

可能伴随:

rx_packets / rx_pps 高
CPU softirq 时间高
load 上升
网络延迟上升
rx_drop 增长

尤其是小包场景:

带宽不一定高
但 PPS 很高
softirq 可能很高

因为小包多,内核要处理的“包数量”多。


6.2 NET_TX 高

通常说明:

发送方向包处理压力大
应用大量发包
内核网络发送路径压力大

可能伴随:

tx_packets / tx_pps 高
tx_drop 增长
CPU system/softirq 时间上升

6.3 BLOCK 高

可能和块设备 I/O 有关,比如磁盘。

这时要联动:

/proc/diskstats
/proc/stat 里的 iowait
/proc/loadavg

7. softirq 和 CPU 使用率的关系

在 /proc/stat 里,CPU 字段有一个:

softirq

这表示:

CPU 花在处理软中断上的时间。

所以你可以这样联动:

/proc/softirqs
    -> 看软中断次数增长

/proc/stat 的 softirq 字段
    -> 看 CPU 花了多少时间处理软中断

两者不是完全一样。

指标看什么
/proc/softirqs软中断次数
/proc/stat 里的 softirqCPU 处理软中断花掉的时间

所以:

NET_RX 次数高
    ↓
说明网络接收软中断频繁

CPU softirq 时间高
    ↓
说明 CPU 被软中断处理占用了较多时间

如果两个都高,网络包处理压力基本比较明显。


8. 和 eBPF / /proc/net/dev 怎么联动

你前面学了:

/proc/net/dev
    -> 网卡收发 bytes / packets / drops / errors

eBPF TC Hook
    -> 包经过 ingress / egress 路径时统计 bytes / packets

/proc/softirqs
    -> 内核处理网络包带来的软中断压力

联动诊断:

现象判断
rx_bytes 高,rx_pps 不高,NET_RX 不高大包流量,网络吞吐高,但包处理压力不一定大
rx_bytes 不高,rx_pps 高,NET_RX 高小包多,内核包处理压力大
rx_drop 增长,NET_RX 高,CPU softirq 高收包处理不过来,可能丢包
eBPF ingress bytes 高,NET_RX 高入方向流量大且触发内核处理压力
tx_pps 高,NET_TX 高出方向发包压力大

你的项目里网络采集使用 eBPF TC Hook,是在 ingress/egress 包路径上统计 bytes 和 packets;同时项目也把 softirq 作为监控指标之一,因此可以把“流量大小”和“内核处理压力”结合起来看。


9. 放到你的性能监控项目里

项目链路可以这样讲:

Worker 采集 softirq
    ↓
读取 /proc/softirqs 或通过内核模块暴露 softirq 统计
    ↓
解析 NET_RX / NET_TX / TIMER / BLOCK 等累计值
    ↓
保存上一轮采样值
    ↓
下一轮做差分
    ↓
计算 softirq rate
    ↓
MetricCollector 聚合到 MonitorInfo
    ↓
MonitorPusher 通过 gRPC Push 到 Manager
    ↓
HostManager 结合 CPU / 网络 / load 计算健康分
    ↓
MySQL 落库,QueryService 查询趋势

你的项目资料里也明确:Worker 端有 CPU、内存、磁盘、网络、eBPF、用户态监控等多个采集模块,并且 softirq 可以通过内核模块暴露给用户态,最终统一聚合成 MonitorInfo 上报。


10. 面试官最可能问什么

10.1 硬中断和软中断有什么区别?

答:

硬中断是硬件设备直接打断 CPU,比如网卡收包、磁盘 I/O 完成。硬中断处理要求尽量快,所以一般只做少量紧急工作。软中断是内核把一部分后续处理延后执行的机制,可以理解为硬中断的后半段。网络收包时,硬中断通知 CPU 有包到达,后续大量协议栈处理通常交给 NET_RX softirq 完成。


10.2 为什么 softirq 高通常和网络有关?

答:

Linux 网络协议栈大量使用 softirq。网卡收到包后会触发硬中断,硬中断里做少量处理,后续收包和协议栈处理会交给 NET_RX softirq。高并发、小包很多或者 PPS 很高时,NET_RX 增长会很快,CPU 也可能花更多时间处理 softirq,所以 softirq 高经常说明网络包处理压力大。


10.3 /proc/softirqs 怎么算速率?

答:

/proc/softirqs 里的值是从系统启动以来每类软中断在每个 CPU 上的累计次数,不是当前速率。监控程序需要两次采样做差,再除以采样间隔,得到 NET_RX、NET_TX 等软中断的每秒增长速率。


10.4 /proc/interrupts 和 /proc/softirqs 有什么区别?

答:

/proc/interrupts 主要看硬中断,比如网卡、磁盘、定时器等硬件中断在每个 CPU 上触发了多少次;/proc/softirqs 看软中断,比如 NET_RX、NET_TX、TIMER、BLOCK 等内核延后处理机制的执行次数。前者更接近硬件事件,后者更接近内核后续处理压力。


11. 小白最小记忆版

背这个:

硬中断:硬件直接打断 CPU,例如网卡收包、磁盘 I/O 完成。

软中断:内核把硬中断后续较重的工作延后处理。

网卡收包:
硬中断通知 CPU
-> 后续协议栈处理交给 NET_RX softirq。

/proc/interrupts 看硬中断次数。

/proc/softirqs 看软中断次数。

/proc/softirqs 也是累计值,要两次采样做差。

NET_RX 高,通常说明网络接收包处理压力大。

PPS 高时,即使带宽不高,也可能导致 softirq 高。

12. 面试版一句话

硬中断是硬件设备直接打断 CPU,例如网卡收包或磁盘 I/O 完成;软中断是内核把硬中断后续较重的工作延后处理的一种机制。网络收包时,硬中断通常只做少量紧急处理,后续大量协议栈处理会交给 NET_RX softirq,所以 NET_RX 增长很快通常说明网络包处理压力大。/proc/softirqs 里的值是累计次数,监控程序需要两次采样做差,计算每秒 softirq 增长速率。我的项目里 Worker 会采集 softirq 指标,并结合网络吞吐、PPS、CPU softirq 时间和 load,一起判断服务器网络处理压力。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐