关闭 offload 后延迟不一定降低,甚至可能升高;因 cpu 软中断压力增大导致 ping 毛刺增多、tcpretrans 突增、net_rx 软中断飙升,真正需关的是 gro 和 lro,其余如 rx/tx 校验可保留以平衡延迟与吞吐。

ethtool -K 关闭 offload 后延迟真的降了吗?
不一定,甚至可能更高。关闭 rx、tx、gso 等 offload 并不等于“让网卡变老实”,而是把原本由硬件/驱动完成的分片、校验、时间戳等工作强行转给 CPU 做——在高吞吐或高包频场景下,CPU 软中断压力反而上升,softirq 处理延迟波动更明显。
典型表现是:ping 延迟毛刺变多,tcpretrans 统计突增,/proc/interrupts 中对应网卡的软中断计数飙升。
-
ethtool -K eth0 rx off tx off gso off tso off gro off lro off一气关掉所有,常是过度操作 - 真正影响低延迟的关键项其实是
gro(Generic Receive Offload)和lro(Large Receive Offload),它们会合并多个小包为大帧再交到协议栈,破坏时序感知 -
tso/gso主要影响发包路径,对收包延迟无直接作用;盲目关掉反而削弱吞吐能力
哪些 offload 必须关?哪些可以留?
取决于你跑的是什么应用:
- 实时音视频、高频交易、DPDK 用户态协议栈:必须关
gro和lro,避免包合并导致 jitter 不可控 - 普通 TCP 服务(如 nginx、redis):可只关
gro,保留rx(硬件校验)和tx(硬件校验)以降低 CPU 消耗 - 使用
SO_TIMESTAMPING或 PTP 硬件时间戳的场景:必须关rx,否则校验卸载会干扰时间戳插入点 -
sg(Scatter-Gather)、tx(TCP checksum)这类不影响包到达时序的 offload,通常建议保留
ethtool -k 显示 “on” 却不起效?常见原因
ethtool -k 只读取驱动当前配置视图,并不验证硬件是否真支持或已启用。以下情况会导致“显示开启但实际无效”:
- 驱动未加载 offload 支持模块(如某些老版本
e1000e驱动默认禁用gro,即使ethtool -k显示on) - 固件版本过旧,网卡硬件本身不支持该 offload(例如部分 Intel I210 固件需 ≥ 4.5 才支持完整 GRO)
- 内核启动参数含
net.ifnames=0或biosdevname=0不影响 offload,但容易让人误查错网卡名,导致ethtool -K作用于错误设备 - 容器或虚拟化环境下(如 KVM + virtio),
ethtool -k查的是 virtio-net 驱动模拟值,真实 offload 由 host 决定,guest 里关不掉底层硬件行为
验证关闭是否生效的可靠方法
别只信 ethtool -k 输出,要看运行时行为:
- 抓包看包长:
tcpdump -i eth0 -c 10 'tcp port 80' -w /tmp/test.pcap,然后用 Wireshark 检查是否有 >1500 字节的 TCP 段——若有,说明gro或lro仍生效 - 查内核统计:
cat /proc/net/snmp | grep -A1 'TcpExt',关注TCPSegsOut与TCPFastRetrans的比值突变;关掉gro后,小包数量应明显上升 - 观察软中断分布:
watch -n1 'cat /proc/softirqs | grep -E "(NET_RX|NET_TX)"',关掉gro后NET_RX计数应更平稳,但总次数上升 - 确认驱动实际加载参数:
modinfo e1000e | grep -i gro,有些驱动编译时就禁用了 GRO 支持,ethtool -K无法启用
offload 的开关不是非黑即白的配置项,它和驱动版本、固件能力、内核网络栈路径深度强耦合。最容易被忽略的是:同一块网卡,在不同内核版本下,gro 的合并阈值、超时逻辑、触发条件都可能变化——别拿 A 机器的配置直接套到 B 机器上。










