2. 网络I/O模型演进:从轮询(Polling)到中断驱动,再到混合模型(NAPI)

网络I/O模型是网卡驱动性能的底层骨架。从早期的轮询到经典的中断驱动,再到Linux内核创新的NAPI混合模型,每一次演进都围绕一个核心矛盾:CPU利用率与网络吞吐量之间的权衡。理解这一演进路径,是后续调优中断合并与NAPI权重的基础。

2.1 轮询模型:以CPU换延迟

在早期操作系统或嵌入式裸机环境中,网卡驱动采用轮询(Polling)方式工作。CPU不断读取网卡状态寄存器,检查是否有新数据包到达。

核心特征:CPU 100%占用,无中断开销,但无法处理其他任务。
轮询模型工作流程 CPU 持续轮询状态寄存器 网卡NIC 数据包到达缓冲区 读状态寄存器 返回数据/空 ⚠ 轮询模型代价 • 低延迟:数据包到达后立即被CPU取走 • 高CPU占用:即使无数据,CPU也在空转
指标 轮询模型 适用场景
延迟 极低(微秒级) 实时系统、高频交易
CPU利用率 100%(空转浪费) 专用硬件、单任务环境
吞吐量 受限于CPU频率 低负载、确定性场景

2.2 中断驱动模型:解放CPU,但引入新问题

随着多任务操作系统普及,中断驱动(Interrupt-Driven)模型成为主流。网卡在数据包到达时通过硬件中断通知CPU,CPU暂停当前任务,执行中断服务程序(ISR)处理数据。

关键改进:CPU只在有数据时被唤醒,空闲时可执行其他进程,大幅提升系统整体利用率。
中断驱动模型工作流程 网卡NIC 数据包到达 中断控制器 IRQ路由 CPU 执行ISR 硬件中断 触发 ⚠ 中断驱动模型的致命缺陷:中断风暴 1. 高吞吐场景下,每个数据包都产生中断 2. CPU频繁保存/恢复上下文,缓存污染严重 3. 实测:10Gbps线速下,纯中断模型CPU 100%用于中断处理 4. 结果:吞吐量不升反降,系统响应变慢
中断风暴(Interrupt Storm):当网络流量超过某个阈值,中断频率高到CPU无法处理其他任务,系统吞吐量反而下降。这是驱动调优必须避免的状态。

2.3 NAPI混合模型:中断+轮询的优雅结合

NAPI(New API)是Linux内核在2.4.20版本引入的混合I/O模型,由David S. Miller等人设计。其核心思想:低负载用中断,高负载切轮询。

NAPI核心机制:中断关闭 + 轮询调度。第一个数据包触发中断后,驱动关闭中断并注册轮询回调,后续数据包通过轮询批量处理,处理完毕再重新开启中断。
NAPI混合模型状态机 状态1:中断开启 等待数据包 状态2:中断触发 执行ISR,关闭中断 状态3:轮询处理 批量收包,权重控制 状态4:开启中断 收包完毕,恢复中断 数据包到达 注册poll回调 收包完成 开启中断 NAPI优势 • 低负载:中断 • 高负载:轮询 • 减少中断次数 • 批量收包 • 缓存友好 • 可调权重

2.4 三种模型对比总结

特性 轮询模型 中断驱动模型 NAPI混合模型
CPU空闲利用率 100%(空转) 接近0%(可调度) 接近0%(可调度)
低负载延迟 极低 低(中断响应) 低(中断响应)
高负载吞吐量 受限于CPU频率 中断风暴,吞吐下降 线性增长,无风暴
中断次数 0 每个数据包1次 可调(合并后)
缓存污染 低 高(频繁上下文切换) 低(批量处理)
Linux内核支持 非标准驱动 传统驱动 所有现代驱动

2.5 NAPI关键数据结构

NAPI的核心数据结构是 napi_struct,每个NAPI实例对应一个轮询队列。驱动在初始化时注册poll回调函数和权重(weight)。

/* 内核源码:include/linux/netdevice.h */
struct napi_struct {
    struct list_head    poll_list;    /* 轮询链表 */
    unsigned long       state;        /* NAPI状态标志 */
    int                 weight;       /* 轮询权重(单次最大收包数) */
    int                 (*poll)(struct napi_struct *, int); /* 轮询回调 */
    struct net_device   *dev;         /* 关联网络设备 */
    struct list_head    dev_list;     /* 设备链表 */
    // ... 其他字段
};
权重(weight)是NAPI调优的核心参数。它决定了每次轮询回调最多处理多少个数据包。默认值通常为64,但实际调优需要根据CPU频率、网卡速率、包大小综合计算。

2.6 从模型到调优:NAPI权重的影响

NAPI权重直接影响CPU在中断和轮询之间的切换频率:

  • 权重过小:轮询很快退出,频繁回到中断模式,中断次数增加,CPU开销上升。
  • 权重过大:轮询占用CPU时间过长,导致其他任务延迟增大,甚至触发软锁检测。
  • 理想值:使每次轮询刚好处理完一个调度周期内到达的数据包,既不浪费中断,也不过度占用CPU。
NAPI权重对CPU开销的影响曲线 NAPI权重 CPU开销 中断开销 轮询开销 最优区域