TCP接收窗口大小高于net.core.rmem_max

时间:2015-07-21 18:25:08

标签: linux performance tcp iperf congestion-control

我正在通过10Gbit链接连接的两台服务器之间运行iperf次测量。我试图将我观察到的最大窗口大小与系统配置参数相关联。

特别是,我观察到最大窗口大小为3 MiB。但是,我在系统文件中找不到相应的值。

通过运行sysctl -a,我得到以下值:

net.ipv4.tcp_rmem = 4096        87380   6291456
net.core.rmem_max = 212992

第一个值告诉我们最大接收器窗口大小为6 MiB。但是,TCP倾向于分配两倍的请求大小,因此最大接收器窗口大小应为3 MiB,正如我测量的那样。来自man tcp

  

请注意,TCP实际分配的次数是setsockopt(2)调用中请求的缓冲区大小的两倍,因此后续的getsockopt(2)调用将不会返回与setsockopt(2)调用中请求的缓冲区大小相同的缓冲区。 TCP使用额外空间用于管理目的和内部内核结构,/ proc文件值反映了与实际TCP窗口相比更大的大小。

但是,第二个值net.core.rmem_max表示最大接收器窗口大小不能超过208 KiB。根据{{​​1}}:

,这应该是硬限制
  

tcp_rmem   max:每个TCP套接字使用的接收缓冲区的最大大小。此值不会覆盖全局man tcp。这不用于限制在套接字上使用SO_RCVBUF声明的接收缓冲区的大小。

那么,为什么我发现最大窗口大小大于net.core.rmem_max中指定的窗口大小?

注意:我还计算了带宽延迟产品:net.core.rmem_max,大约3 MiB(10 Gbps @ 2毫秒RTT),从而验证我的流量捕获。

2 个答案:

答案 0 :(得分:7)

快速搜索了:

https://github.com/torvalds/linux/blob/4e5448a31d73d0e944b7adb9049438a09bc332cb/net/ipv4/tcp_output.c

void tcp_select_initial_window()

中的

if (wscale_ok) {
    /* Set window scaling on max possible window
     * See RFC1323 for an explanation of the limit to 14
     */
    space = max_t(u32, sysctl_tcp_rmem[2], sysctl_rmem_max);
    space = min_t(u32, space, *window_clamp);
    while (space > 65535 && (*rcv_wscale) < 14) {
        space >>= 1;
        (*rcv_wscale)++;
    }
}

max_t获取参数的较高值。所以更大的价值优先于此。

sysctl_rmem_max的另一个引用用于将参数限制为SO_RCVBUF(在net / core / sock.c中)。

所有其他tcp代码仅指sysctl_tcp_rmem

因此,如果不仔细查看代码,您可以得出结论:在所有情况下,较大的net.ipv4.tcp_rmem都会覆盖net.core.rmem_max,除非设置SO_RCVBUF(可以使用{{1}绕过其检查})

答案 1 :(得分:1)

net.ipv4.tcp_rmem根据https://serverfault.com/questions/734920/difference-between-net-core-rmem-max-and-net-ipv4-tcp-rmem优先net.core.rmem_max

  

似乎tcp设置优先于公共最大设置

但我同意你所说的,这似乎与man tcp中的内容相冲突,我可以重现你的发现。也许文档错了?请找出并评论!