1、课程导论:为什么需要关注软中断亲和性?现代网卡多队列与多核CPU的挑战
1.1 从单核到多核:网络收包路径的演变
在早期的 Linux 网络协议栈中,所有网络收包处理(从网卡中断到协议栈解析)几乎都集中在单个 CPU 核心上。随着 10GbE、25GbE 乃至 100GbE 网卡的普及,单核 CPU 的处理能力已成为网络吞吐的瓶颈。现代服务器普遍配备 32 核、64 核甚至更多核心的 CPU,而现代网卡也支持 多队列(Multi-Queue) 技术,例如 Intel 的 RSS(Receive Side Scaling)和 Mellanox 的 RPS(Receive Packet Steering)。
这种硬件与 CPU 架构的并行化趋势,带来了一个核心问题:如何将网卡多个队列的中断及后续的软中断(SoftIRQ)处理,合理地分散到多个 CPU 核心上,从而避免单核过载,最大化利用多核并行能力? 这正是软中断 CPU 亲和性配置要解决的关键挑战。
1.2 软中断亲和性:连接硬件与CPU的桥梁
软中断(SoftIRQ)是 Linux 内核在硬中断处理完成后,将耗时工作(如网络协议栈处理)推迟到更安全上下文中执行的机制。对于网络收包,NET_RX_SOFTIRQ 是核心的软中断类型。软中断的 CPU 亲和性,决定了哪个 CPU 核心来执行这个软中断处理函数。
当网卡通过 DMA 将数据包写入内存并触发硬中断后,硬中断处理程序通常会做最少的工作(如更新统计、调度软中断),然后由软中断完成协议栈的绝大部分工作。如果软中断始终在同一个 CPU 上执行,即使网卡有多个队列,也无法利用多核优势。
NET_RX_SOFTIRQ 的处理权分散到多个 CPU 核心上,并与网卡硬件队列的中断亲和性协同工作,形成“一队列一核心”或“多队列多核心”的并行处理流水线。
1.3 现代网卡多队列技术:RSS 与 RPS
现代网卡通过硬件多队列技术,将数据包流分散到不同的接收队列。Linux 内核提供了两种主要机制来利用这种并行性:
| 特性 | RSS (Receive Side Scaling) | RPS (Receive Packet Steering) |
|---|---|---|
| 实现层级 | 网卡硬件 | Linux 内核软件 |
| 数据包分发 | 基于哈希(IP、端口)将数据包分配到硬件队列 | 在软中断上下文中,将数据包分发到指定 CPU 的 backlog 队列 |
| 中断亲和性 | 每个硬件队列的中断可以绑定到不同 CPU | 不依赖硬件中断,完全由内核调度 |
| 适用场景 | 硬件支持多队列的网卡(如 ixgbe、mlx5) | 硬件队列数少于 CPU 核心数,或需要更细粒度负载均衡 |
| 配置方式 | /proc/irq/<IRQ>/smp_affinity |
/sys/class/net/<eth>/queues/rx-<n>/rps_cpus |
1.4 不配置亲和性的典型性能问题
当软中断亲和性配置不当或未配置时,在高吞吐场景下会暴露以下性能问题:
- 单核软中断过载(SoftIRQ Starvation): 所有网络收包软中断集中在单个 CPU 上,该 CPU 的
si使用率接近 100%,而其他 CPU 空闲,导致整体吞吐受限。 - CPU 缓存抖动(Cache Thrashing): 数据包在多个 CPU 之间频繁迁移,导致 L1/L2 缓存失效,增加内存访问延迟。
- 锁竞争加剧: 协议栈中的共享数据结构(如路由表、socket 锁)在多个 CPU 上被频繁访问,导致 spinlock 争用,降低并发效率。
- 中断风暴(Interrupt Storm): 在极端情况下,高频率的中断和软中断调度可能导致 CPU 无法处理其他任务,系统响应变慢。
1.5 性能指标对比:配置前后的差异
以下表格展示了在 25GbE 网卡、64 核 CPU 环境下,配置软中断亲和性前后的典型性能指标对比:
| 性能指标 | 未配置亲和性 | 配置亲和性后 | 提升幅度 |
|---|---|---|---|
| 最大吞吐量 (Gbps) | 4.2 | 23.8 | +466% |
| CPU 软中断使用率 (峰值) | 98% (单核) | 45% (分散到 8 核) | 负载均衡 |
| 平均延迟 (μs) | 125 | 38 | -70% |
| P99 延迟 (μs) | 480 | 95 | -80% |
| 丢包率 (满负载) | 2.3% | 0.01% | 显著降低 |