ethtool -K 关闭 TSO/GSO 后网络吞吐反而下降的业务场景验证

8次阅读

关闭TSO/GSO后吞吐下降是因TCP分段回归内核软中断处理,导致softirq压力陡增成为瓶颈,尤其在高吞吐小包混合场景下;典型表现为单流吞吐降15–30%、si%持续超40%、TcpOutSegs暴涨。

ethtool -K 关闭 TSO/GSO 后网络吞吐反而下降的业务场景验证

为什么 ethtool -K 关闭 TSO/GSO 后吞吐反而掉?

这不是配置错了,而是 TCP 分段逻辑被强行“降级”后,CPU 和网卡协同方式发生了根本变化。TSO(TCP Segmentation Offload)和 GSO(Generic Segmentation Offload)本质是把 TCP 大包的分段工作从内核协议下推到网卡硬件或驱动层;关闭后,所有分段回归内核软中断处理,尤其在高吞吐、小包混合场景下,softirq 压力陡增,反而成为瓶颈。

典型表现:单流大文件传输吞吐下降 15–30%,topsi%(softirq 占用)持续高于 40%,/proc/net/snmpTcpOutSegs 暴涨但 IpOutNoRoutesTcpRetransSegs 无异常。

哪些业务场景会明显踩中这个坑?

不是所有关 TSO/GSO 都会掉吞吐,关键看流量特征和硬件能力:

  • 使用 DPDK 或 XDP 的应用(如 Envoy、自研 proxy),本身绕过内核协议,关 TSO/GSO 几乎无影响,甚至因避免硬件分段校验开销而略升
  • 并发短连接 + 小响应体(如 http/1.1 jsON API),关 GSO 后每个 write() 触发一次 skb 分配+拷贝+软中断调度,alloc_skb__netif_receive_skb_core热点
  • 启用了 tcp_congestion_controlbbrcubic 且 RTT
  • 虚拟化环境(KVM + virtio-net),关 TSO 后 guest 内核需承担全部分段,而 virtio_net_hdr 头部处理又额外增加 CPU 开销

ethtool -K 关闭项的实际作用差异

ethtool -K eth0 tso off gso off 看似一步到位,但三者生效层级不同,误关可能白忙:

  • tso:仅影响 IPv4 TCP 流量,且依赖网卡支持(ethtool -i eth0supports-tso);关了但网卡不支持 TSO,实际无变化
  • gso:内核软件层分段开关,影响所有 L4 协议(TCP/udp/FULL),关了会强制所有发送路径走 dev_hard_start_xmit() 前分段,是吞吐下降主因
  • gro(常被一起关):是接收端聚合,关它一般不影响发送吞吐,但会抬高接收侧 CPU,间接加剧整体负载失衡

验证时建议逐项关闭:ethtool -K eth0 gso off 单独测,再加 tso off,比一并关更易定位根因。

怎么验证是不是真被 TSO/GSO 关闭拖累?

别只看 iperf3 -c 结果,要抓三层证据链:

  • 确认关闭生效:ethtool -k eth0 | grep -E "(tso|gso|gro)" 输出必须全为 off
  • 看软中断分布:cat /proc/softirqs | grep "NET_TX|NET_RX",对比开关前后同一负载下第 9 列(NET_TX)增长倍数,>2x 即强相关
  • 抓发送路径火焰图:perf record -e 'skb:consume_skb' -g -a sleep 30,关 GSO 后若 tcp_write_xmit → __tcp_push_pending_frames → tcp_mss_split_point 占比突增,就是内核分段成瓶颈
  • 检查 TX ring 状态:ethtool -S eth0 | grep tx_.*_errors,若 tx_dma_failedtx_timeout 上升,说明关 offload 后驱动提交速率跟不上

真正难的是区分「GSO 关闭导致吞吐降」和「GSO 关闭暴露了原有瓶颈」——比如原本网卡驱动有锁竞争,关 GSO 后分段调用变密集,锁争用被放大。这时候改驱动比关 GSO 更治本。

text=ZqhQzanResources