关闭TSO/GSO导致网络性能下降,是因为在高吞吐、低延迟且CPU充足、网卡硬件能力强的场景(如K8s微服务RPC、VFIO直通存储、DPDK共存环境)中,强行关闭会增加softirq开销、小包激增、内存压力及调度失衡,正确做法是依据ethtool、softnet_stat和tcpdump数据判断真实瓶颈。

关闭 TSO/GSO 后网络性能下降,不是配置错了,而是用错了场景。真实业务中,这种“关了反而更慢”的情况往往出现在高吞吐、低延迟敏感但 CPU 资源充足、网卡硬件能力被低估的环境中。
典型业务场景:容器化微服务高频 RPC 通信
在 Kubernetes 集群中运行大量 gRPC 或 Thrift 服务,单 Pod 每秒发起数千次短连接或流式请求。此时若宿主机网卡(如 Intel X710、Mellanox ConnectX-5)支持高效 TSO/GSO,且内核已启用 GRO/LRO 配合处理接收端聚合,强行关闭 TSO/GSO 会导致:
- 内核协议栈需对每个 TCP 报文做软件分段,显著增加 softirq 处理时间
- veth pair + CNI 插件(如 Calico eBPF 或 Cilium)路径变长,小包数量激增,加剧队列竞争和丢包重传
- iperf3 测试显示带宽从 9.2Gbps 掉到 5.8Gbps,同时 netstat -s 中 “TCP: packets retransmitted” 上升 3–5 倍
虚拟化平台直通网卡下的高性能存储访问
Proxmox VE 或 OpenStack 环境中,VM 使用 VFIO 直通 10G/25G 网卡访问 Ceph 或 NVMe-oF 存储后端。这类场景依赖网卡硬件完成大块数据的零拷贝分段与校验卸载:
- 关闭 TSO/GSO 后,4MB 的写请求需拆成 ~2600 个 1500 字节的帧,触发大量 SKB 分配与释放,引发内存碎片和 slab 压力
- ethtool -S 显示 tx_errors、tx_aborted_errors 明显上升,dmesg 出现 “skb_over_panic” 或 “page allocation failure”
- iostat 观察到存储写入 IOPS 下降 40%,而 top 中 ksoftirqd/0 占用率持续高于 70%
DPDK 或用户态协议栈共存环境
当服务器同时运行 DPDK 应用(如 OVS-DPDK、FD.io VPP)和传统 Linux 网络栈服务(如 Nginx、PostgreSQL)时,TSO/GSO 关闭可能破坏协同逻辑:
- DPDK 应用通常绕过内核,依赖网卡硬件完成分段;而 Linux 栈服务关闭 TSO 后发包变小,导致同一物理队列中大小包混杂,破坏硬件调度公平性
- tc qdisc(如 fq_codel)对小包的排队延迟敏感,平均 RTT 从 80μs 升至 220μs,P99 延迟翻倍
- 抓包发现发送端 tcpdump 显示大量 1500 字节帧,但接收端 wireshark 解析出重复 ACK 和 SACK 乱序,说明链路层效率反被削弱
关键判断依据:别只看 CPU,要看路径瓶颈在哪
是否该关 TSO/GSO,不能只看“CPU 高不高”。真正要查的是:
- ethtool -S eth0 中 tx_tso_packets / rx_gro_packets 是否为 0(说明硬件没起作用,关了也没损失)
- cat /proc/net/softnet_stat 第 1 列(processed)和第 2 列(dropped)比值是否持续 > 1000(软中断过载才值得关)
- tcpdump -i eth0 -nn -c 100 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0' 看 SYN/FIN 包占比——若超 15%,说明连接极短,TSO 效益本就有限
不复杂但容易忽略:关卸载是调优手段,不是默认动作。先确认瓶颈真在 CPU 分段,再动手。











