读了 Linux NAPI 收包源码,发现网卡驱动在 10Gbps 下不丢包的 4 层缓冲设计

张开发
2026/4/16 10:11:06 15 分钟阅读

分享文章

读了 Linux NAPI 收包源码,发现网卡驱动在 10Gbps 下不丢包的 4 层缓冲设计
写网络服务端程序的人,对epoll_wait返回可读事件、然后recv把数据拿走这件事不会陌生。网卡收到包,内核通知你的程序,你读出来处理。干净利落。数据就在那儿等着你,拿走就行。但如果有人问你:这个包从光纤进入网卡的那一刻起,到你的recv能拿到数据,中间到底经过了几层缓冲?每一层在干什么?为什么需要这么多层?先看一组数字。10Gbps 以太网,最小帧 64 字节加上前导码和帧间隔共 84 字节,换算成比特是 672 bits。10,000,000,000 ÷ 672 ≈14,880,952——也就是说在最极端的小包场景下,网卡每秒要处理将近1488 万个包,平均每67.2 纳秒就来一个。即使按常见的 1500 字节 MTU 计算,每秒也有82 万个包,每 1.2 微秒一个。如果每个包都触发一次硬件中断,按每次中断处理耗时 5 微秒算,1488 万次中断需要 74.4 秒的 CPU 时间——一秒钟里需要 74 个 CPU 核心只做中断处理这一件事。这显然不现实。即使是 82 万次中断,5 微秒一次也需要 4.1 秒,4 个核心满载。这就是 10Gbps 网络给内核收包路径带来的核心压力:包的到达速率远远超过了"每包一次中断"模型的处理能力。不是 CPU 不够快,是中断本身的开销——保存寄存器、切换上下文、缓存失效——在这个速率下成了不可承受的代价。Linux 内

更多文章