|
|
@@ -345,17 +345,24 @@ static void tcp_grow_window(struct sock *sk, struct sk_buff *skb)
|
|
|
|
|
|
static void tcp_fixup_rcvbuf(struct sock *sk)
|
|
|
{
|
|
|
- struct tcp_sock *tp = tcp_sk(sk);
|
|
|
- int rcvmem = SKB_TRUESIZE(tp->advmss + MAX_TCP_HEADER);
|
|
|
+ u32 mss = tcp_sk(sk)->advmss;
|
|
|
+ u32 icwnd = TCP_DEFAULT_INIT_RCVWND;
|
|
|
+ int rcvmem;
|
|
|
|
|
|
- /* Try to select rcvbuf so that 4 mss-sized segments
|
|
|
- * will fit to window and corresponding skbs will fit to our rcvbuf.
|
|
|
- * (was 3; 4 is minimum to allow fast retransmit to work.)
|
|
|
+ /* Limit to 10 segments if mss <= 1460,
|
|
|
+ * or 14600/mss segments, with a minimum of two segments.
|
|
|
*/
|
|
|
- while (tcp_win_from_space(rcvmem) < tp->advmss)
|
|
|
+ if (mss > 1460)
|
|
|
+ icwnd = max_t(u32, (1460 * TCP_DEFAULT_INIT_RCVWND) / mss, 2);
|
|
|
+
|
|
|
+ rcvmem = SKB_TRUESIZE(mss + MAX_TCP_HEADER);
|
|
|
+ while (tcp_win_from_space(rcvmem) < mss)
|
|
|
rcvmem += 128;
|
|
|
- if (sk->sk_rcvbuf < 4 * rcvmem)
|
|
|
- sk->sk_rcvbuf = min(4 * rcvmem, sysctl_tcp_rmem[2]);
|
|
|
+
|
|
|
+ rcvmem *= icwnd;
|
|
|
+
|
|
|
+ if (sk->sk_rcvbuf < rcvmem)
|
|
|
+ sk->sk_rcvbuf = min(rcvmem, sysctl_tcp_rmem[2]);
|
|
|
}
|
|
|
|
|
|
/* 4. Try to fixup all. It is made immediately after connection enters
|