真正代表丢包的关键字段是:rx_dropped(内核层丢包)、rx_over_errors(ring buffer溢出)、rx_fifo_errors(fifo溢出)、rx_missed_errors(vcpu调度丢失);其余带drop或error的字段多为中间状态或伪丢包,需结合环境与数据流向分层判断。

ethtool -S 输出里哪些字段真正代表丢包
ethtool -S 的统计项命名混乱,很多带 drop 或 error 的字段并不等于“丢包”。真正指向硬件/驱动层丢包的只有几个关键字段,其余多是中间状态或聚合计数:
-
rx_dropped:数据已进 Ring Buffer,但因内核内存不足、NAPI 调度延迟或中断风暴被丢弃——这是协议栈入口前的最后一道防线 -
rx_over_errors:Ring Buffer 溢出,数据包根本没进驱动队列,最典型的物理层缓冲区瓶颈信号 -
rx_fifo_errors:物理 FIFO 缓冲区溢出(常与rx_over_errors同步增长),说明网卡芯片来不及把包 DMA 到内存 -
rx_missed_errors:虚拟化场景下特别关键,vCPU 调度不及时导致网卡收包中断丢失,值上升基本可锁定宿主机 CPU 过载或 vCPU 绑定不合理 - 别被
rx_errors带偏——它只是 CRC、frame、length 等错误的总和,增长说明链路质量差,但不直接等于丢包
为什么 grep "drop" 会误判
直接 ethtool -S eth0 | grep -i drop 容易漏掉真正问题,也容易被干扰:
- 有些驱动把重传、过滤、管理帧等行为也记为
tx_drop_*,比如tx_aborted_errors是冲突重试失败,不是丢包 -
rx_no_buffer_count在部分 Intel 驱动中存在,表示 Ring Buffer 空间全满时网卡拒绝接收新包,但它不叫drop,grep drop就看不到 - 虚拟网卡(如
virtio_net)可能压根不暴露rx_fifo_errors,只报rx_missed_errors,此时必须结合cat /proc/net/dev的Rx-OVR列交叉验证
如何用 ethtool -S 快速定位丢包环节
不要通读全部输出。按数据流向分三步查,每步只盯 1–2 个字段:
-
先看物理层是否扛得住:执行
ethtool -S eth0 | grep -E "(rx_over_errors|rx_fifo_errors)",若非零且持续上涨 → Ring Buffer 太小或 CPU 处理不过来 → 立即执行ethtool -g eth0查当前大小,再用ethtool -G eth0 rx 4096扩容 -
再看驱动/内核是否跟得上:运行
ethtool -S eth0 | grep rx_dropped,若明显增长(尤其伴随netstat -s | grep "packet receive errors"上升)→ 检查sysctl net.core.netdev_max_backlog和软中断负载(cat /proc/softirqs | grep NET_RX) -
最后排除“伪丢包”:执行
tc -s qdisc show dev eth0,若看到dropped计数在涨,且配置了netem loss→ 不是故障,是人为丢包规则,删掉即可:tc qdisc del dev eth0 root
ethtool -S 在不同网卡上的表现差异
同一命令,在物理网卡、SR-IOV VF、virtio-net 上看到的字段完全不同,硬套文档会踩坑:
- Intel e1000e/i40e 驱动通常提供完整字段:
rx_no_buffer_count、rx_crc_errors、rx_length_errors - Marvell/Realtek 部分型号驱动不支持
-S,返回no stats available,此时只能依赖/proc/net/dev和ifconfig的overruns字段 - virtio-net(云服务器常见)几乎不暴露 FIFO 类指标,
rx_missed_errors是核心线索;若该值高,top -H看ksoftirqd线程 CPU 占用是否打满 - DPDK 应用接管网卡后,
ethtool -S统计可能停滞或归零,因为驱动绕过了内核协议栈
真正难的不是看懂某个字段,而是理解它在当前硬件+驱动+内核组合下的实际含义。同一个 rx_over_errors,在物理机上可能是 Ring Buffer 小,在 KVM 里可能是 vCPU 抢占太狠,在容器里可能是 CNI 插件挂了 tc 规则。查之前,先确认你面对的是什么环境。











