关闭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 都会掉吞吐,关键看流量特征和硬件能力:
- 使用 DPDK 或 XDP 的应用(如 Envoy、自研 proxy),本身绕过内核协议栈,关 TSO/GSO 几乎无影响,甚至因避免硬件分段校验开销而略升
- 高并发短连接 + 小响应体(如 HTTP/1.1 JSON API),关 GSO 后每个
write()触发一次 skb 分配+拷贝+软中断调度,alloc_skb和__netif_receive_skb_core成热点 - 启用了
tcp_congestion_control为bbr或cubic且 RTT -
虚拟化环境(KVM + virtio-net),关 TSO 后 guest 内核需承担全部分段,而
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,比一并关更易定位根因。
怎么验证是不是真被 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_failed或tx_timeout上升,说明关 offload 后驱动提交速率跟不上
真正难的是区分「GSO 关闭导致吞吐降」和「GSO 关闭暴露了原有瓶颈」——比如原本网卡驱动有锁竞争,关 GSO 后分段调用变密集,锁争用被放大。这时候改驱动比关 GSO 更治本。










