文章目录
- tcp_rmem - 取值是:3个整数向量: min, default, max
- min
- default:
- max
- rmem_default
- rmem_max
- 具体的用法
- 相关的方法
tcp_rmem - 取值是:3个整数向量: min, default, max
min
TCP sockets使用的最小接收缓存大小。这个最小值的作用是在,内存处在轻微压力下时,也会给socket分配的内存大小。
Default: 4K
default:
TCP sockets 初始时分配的接收缓存大小。这个值会覆盖net.core.rmem_default这个值。 默认是:87380 bytes。这个值也是计算窗口的输入值,This value results in window of 65535 with default setting of tcp_adv_win_scale and tcp_app_win:0 and a bit less for default tcp_app_win. See below about these variables.
max
允许TCP socket自动选择接收缓存的最大值。不会覆盖net.core.rmem_max。调用setsockopt()设置SO_RCVBUF会将自动调整缓存大小的方法关闭,这样这个值就没有任何作用了。默认值,在87380字节到6M之间,具体值依赖于RAM的大小。
rmem_default
The default setting of the socket receive buffer in bytes.
rmem_max
The maximum receive socket buffer size in bytes.
具体的用法
创建socket一开始的recv buff的大小是rmem_default;后续tcp层会重新设置这个receivebuffer到tcp_rmem:default;
然后,socket的用户标记为非SOCK_RCVBUF_LOCK;就会调用tcp_fixup_rcvbuf函数进行接收缓存大小的重新计算。
sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
相关的方法
void sock_init_data(struct socket *sock, struct sock *sk)
{
sk_init_common(sk);
sk->sk_send_head = NULL;
timer_setup(&sk->sk_timer, NULL, 0);
sk->sk_allocation = GFP_KERNEL;
sk->sk_rcvbuf = sysctl_rmem_default;
{
.procname = "rmem_default",
.data = &sysctl_rmem_default,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec_minmax,
.extra1 = &min_rcvbuf,
},
/* 3. Tuning rcvbuf, when connection enters established state. */
static void tcp_fixup_rcvbuf(struct sock *sk)
{
u32 mss = tcp_sk(sk)->advmss;
int rcvmem;
rcvmem = 2 * SKB_TRUESIZE(mss + MAX_TCP_HEADER) *
tcp_default_init_rwnd(mss);
/* Dynamic Right Sizing (DRS) has 2 to 3 RTT latency
* Allow enough cushion so that sender is not limited by our window
*/
if (sock_net(sk)->ipv4.sysctl_tcp_moderate_rcvbuf)
rcvmem <<= 2;
if (sk->sk_rcvbuf < rcvmem)
sk->sk_rcvbuf = min(rcvmem, sock_net(sk)->ipv4.sysctl_tcp_rmem[2]);
}
case SO_RCVBUF:
/* Don't error on this BSD doesn't and if you think
* about it this is right. Otherwise apps have to
* play 'guess the biggest size' games. RCVBUF/SNDBUF
* are treated in BSD as hints
*/
val = min_t(u32, val, sysctl_rmem_max);
set_rcvbuf:
/* Ensure val * 2 fits into an int, to prevent max_t()
* from treating it as a negative value.
*/
val = min_t(int, val, INT_MAX / 2);
sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
/*
* We double it on the way in to account for
* "struct sk_buff" etc. overhead. Applications
* assume that the SO_RCVBUF setting they make will
* allow that much actual data to be received on that
* socket.
*
* Applications are unaware that "struct sk_buff" and
* other overheads allocate from the receive buffer
* during socket buffer allocation.
*
* And after considering the possible alternatives,
* returning the value we actually used in getsockopt
* is the most desirable behavior.
*/
sk->sk_rcvbuf = max_t(int, val * 2, SOCK_MIN_RCVBUF);