我一直在调试 ESX vmware 主机使用 TCP/IP 通过虚拟交换机与虚拟 Linux 计算机通信的场景。发生拥塞事件后,vmware 主机正在等待虚拟机的确认,而虚拟机正在等待来自 vmware 主机的更多数据。大型接收卸载 (LRO) 已打开,问题似乎是 vmware 驱动程序没有向内核提供它正在组合的子段的大小(它可以通过 sk_buff 结构的 gso_size 字段来实现)。
使用通用接收卸载 (GRO) 代替 LRO 可以解决问题。因此,我有两个可能的解决方案,
1) 修复 vmware 驱动程序,以便它设置传递给内核的 sk_buff 的 gso_size 字段或 2) 关闭 LRO(使用 ethtool -K),并改用 GRO。
在网上搜索有关 LRO 和 GRO 的信息,我只找到了一些片段和观点,没有确凿的数据或明确的参考。我想知道使用 LRO 和 GRO 的优缺点是什么。
从我目前在网上的搜索来看,我认为:*) LRO 和 GRO 都可以减少确认的数量,这应该会减少网络流量,但可能也会降低慢启动或拥塞避免期间拥塞窗口 (cwnd) 的增长速度。*) LRO 和 GRO 都应该减少中断的数量和内核堆栈的遍历次数。由于 GRO 使用了新的 API (NAPI),它是否比 LRO 更能减少中断?*) LRO 有时会将过多的数据包组合在一起(特定数据包的报头不同,会破坏某些应用程序)。*) LRO 只支持 IPV-4,而 GRO 也可以支持 IPV-6。
答案1
根据这篇旧的 LWN 文章GRO 本质上是为了取代 LRO。据我所知,LRO 更具侵略性,这会导致数据包以有损方式组合(丢弃重要的报头数据),而 GRO 则更具限制性。
特别是,LRO 似乎在具有软件桥接和/或转发的环境中存在问题,这在虚拟化设置中很常见。
在调试奇怪的性能问题时,禁用这些卸载可能是您应该做的第一件事之一。