
关闭TSO/GSO后吞吐下降是因TCP分段回归内核软中断处理,导致softirq压力陡增成为瓶颈,尤其在高吞吐小包混合场景下;典型表现为单流吞吐降15–30%、si%持续超40%、TcpOutSegs暴涨。
ethtool -K 关闭 TSO/GSO 后吞吐反而掉?这不是配置错了,而是 TCP 分段逻辑被强行“降级”后,CPU 和网卡协同方式发生了根本变化。TSO(TCP Segmentation Offload)和 GSO(Generic Segmentation Offload)本质是把 TCP 大包的分段工作从内核协议栈下推到网卡硬件或驱动层;关闭后,所有分段回归内核软中断处理,尤其在高吞吐、小包混合场景下,softirq 压力陡增,反而成为瓶颈。
典型表现:单流大文件传输吞吐下降 15–30%,top 中 si%(softirq 占用)持续高于 40%,/proc/net/snmp 里 TcpOutSegs 暴涨但 IpOutNoRoutes 或 TcpRetransSegs 无异常。
不是所有关 TSO/GSO 都会掉吞吐,关键看流量特征和硬件能力:
write() 触发一次 skb 分配+拷贝+软中断调度,alloc_skb 和 __netif_
receive_skb_core 成热点
tcp_congestion_control 为 bbr 或 cubic 且 RTT
virtio_net_hdr 头部处理又额外增加 CPU 开销ethtool -K 关闭项的实际作用差异ethtool -K eth0 tso off gso off 看似一步到位,但三者生效层级不同,误关可能白忙:
tso:仅影响 IPv4 TCP 流量,且依赖网卡支持(ethtool -i eth0 查 supports-tso);关了但网卡不支持 TSO,实际无变化gso:内核软件层分段开关,影响所有 L4 协议(TCP/UDP/FULL),关了会强制所有发送路径走 dev_hard_start_xmit() 前分段,是吞吐下降主因gro(常被一起关):是接收端聚合,关它一般不影响发送吞吐,但会抬高接收侧 CPU,间接加剧整体负载失衡验证时建议逐项关闭:ethtool -K eth0 gso off 单独测,再加 tso off,比一并关更易定位根因。
别只看 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 占比突增,就是内核分段成瓶颈ethtool -S eth0 | grep tx_.*_errors,若 tx_dma_failed 或 tx_timeout 上升,说明关 offload 后驱动提交速率跟不上真正难的是区分「GSO 关闭导致吞吐降」和「GSO 关闭暴露了原有瓶颈」——比如原本网卡驱动有锁竞争,关 GSO 后分段调用变密集,锁争用被放大。这时候改驱动比关 GSO 更治本。