rx_no_buffer_count 是网卡驱动因 rx ring buffer 无空闲描述符而丢弃接收包的计数,增长表明内核/驱动层软丢包,主因是 ring 深度不足、中断处理延迟或 NAPI 轮询跟不上流量。

rx_no_buffer_count 是什么,为什么它增长说明丢包
rx_no_buffer_count 是网卡驱动在接收数据包时,发现 rx ring buffer 中没有空闲描述符(即没有可用的 skb 或 page 缓冲区)而被迫丢弃的数据包计数。它不等于「物理线缆丢包」,而是内核/驱动层因资源不足导致的软丢包。
这个值持续上涨,基本意味着当前 rx ring 深度不够、中断处理不及时、或 NAPI 轮询跟不上流量节奏。常见于高吞吐(如 10G+)、小包(64B)、或 CPU 调度受限(比如绑核不当、软中断集中在一个 CPU)场景。
如何确认 rx ring 当前大小并安全调大
用 ethtool -g 查看和设置 ring buffer 大小。注意:不是所有驱动都支持动态调整,且最大值受硬件和驱动限制(例如 ixgbe 支持最大 4096,igb 通常上限 2048)。
- 先查当前配置:
ethtool -g eth0 - 尝试增大(以 ixgbe 卡为例):
ethtool -G eth0 rx 4096(需 root 权限) - 增大后务必验证:
ethtool -g eth0看是否生效;再观察ethtool -S eth0 | grep rx_no_buffer_count是否停止上涨 - 某些驱动(如 vmxnet3)不支持
ethtool -G,只能通过模块参数(如ring_size=4096)或 guest 内核启动参数调整
光调大 rx ring 不够:还要配好中断与 NAPI 行为
ring buffer 只是第一环。如果软中断(softirq)处理不过来,即使 buffer 很大,也会反复填满又来不及消费,最终仍触发 rx_no_buffer_count 增长。
- 检查软中断分布:
cat /proc/softirqs | grep -i net_rx,确认是否集中在单个 CPU - 启用 RPS(Receive Packet Steering)可将软中断分发到多核:
echo f > /sys/class/net/eth0/queues/rx-0/rps_cpus(十六进制掩码) - 调大
net.core.netdev_budget(默认 300),让每次 NAPI poll 处理更多包,减少轮询次数开销:sysctl -w net.core.netdev_budget=600 - 若使用 Intel 多队列网卡,确保
ethtool -l eth0显示的 combined 队列数 ≥ CPU 核数,并配合 irqbalance 或手动绑 IRQ 到不同 CPU
容易被忽略的干扰项:RSS、GRO、RPS 之间会互相影响
比如开启 GRO(Generic Receive Offload)后,虽然减少了上层协议栈压力,但会延迟包交付、拉长 ring buffer 占用时间;而 RPS 和 RSS 同时启用可能导致 hash 冲突或重复分发,反而加剧某核负载。
- 排查时建议先关掉 GRO:
ethtool -K eth0 gro off,观察rx_no_buffer_count是否缓解 - RSS 和 RPS 不要叠加使用——RSS 是硬件分流(推荐优先启用),RPS 是纯软件 fallback;两者共存可能打乱 CPU 缓存局部性
- 检查是否启用了 XDP 或 tc clsact,某些 eBPF 程序会阻塞收包路径,间接导致 ring 消费变慢
真正稳定的调优往往不是单点拉高某个参数,而是让 ring depth、中断分布、NAPI 负载、offload 开关之间形成匹配。尤其是小包场景下,rx_no_buffer_count 上涨常常是多个环节微小延迟叠加的结果,而不是某一个 buffer 太小这么简单。










