07. 从零带你学习Linux内核:软硬中断
/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 | 键盘/鼠标相关 |
IPI | CPU 间中断 |
如果某个网卡对应的中断数增长很快,说明网卡收发包比较频繁。
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 | 调度相关软中断 | 调度压力 |
RCU | RCU 机制相关 | 内核同步机制 |
对你的项目来说,最重要的是:
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 里的 softirq | CPU 处理软中断花掉的时间 |
所以:
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_RXsoftirq 完成。
10.2 为什么 softirq 高通常和网络有关?
答:
Linux 网络协议栈大量使用 softirq。网卡收到包后会触发硬中断,硬中断里做少量处理,后续收包和协议栈处理会交给
NET_RXsoftirq。高并发、小包很多或者 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_RXsoftirq,所以NET_RX增长很快通常说明网络包处理压力大。/proc/softirqs里的值是累计次数,监控程序需要两次采样做差,计算每秒 softirq 增长速率。我的项目里 Worker 会采集 softirq 指标,并结合网络吞吐、PPS、CPU softirq 时间和 load,一起判断服务器网络处理压力。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)