aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.c
diff options
context:
space:
mode:
authorYuchung Cheng <ycheng@google.com>2013-06-11 18:35:32 -0400
committerDavid S. Miller <davem@davemloft.net>2013-06-13 05:46:29 -0400
commit85f16525a2eb66e6092cbd8dcf42371df8334ed0 (patch)
treeadaf85853246f46fc00f9ed4235059650acf7517 /net/ipv4/tcp_input.c
parent8e994402ad5e6ae3d391c0935f9f1dc2eeb92a5e (diff)
tcp: properly send new data in fast recovery in first RTT
Linux sends new unset data during disorder and recovery state if all (suspected) lost packets have been retransmitted ( RFC5681, section 3.2 step 1 & 2, RFC3517 section 4, NexSeg() Rule 2). One requirement is to keep the receive window about twice the estimated sender's congestion window (tcp_rcv_space_adjust()), assuming the fast retransmits repair the losses in the next round trip. But currently it's not the case on the first round trip in either normal or Fast Open connection, beucase the initial receive window is identical to (expected) sender's initial congestion window. The fix is to double it. Signed-off-by: Yuchung Cheng <ycheng@google.com> Acked-by: Neal Cardwell <ncardwell@google.com> Acked-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r--net/ipv4/tcp_input.c13
1 files changed, 2 insertions, 11 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 907311c9a012..46271cdcf088 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -347,22 +347,13 @@ static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb)
347} 347}
348 348
349/* 3. Tuning rcvbuf, when connection enters established state. */ 349/* 3. Tuning rcvbuf, when connection enters established state. */
350
351static void tcp_fixup_rcvbuf(struct sock *sk) 350static void tcp_fixup_rcvbuf(struct sock *sk)
352{ 351{
353 u32 mss = tcp_sk(sk)->advmss; 352 u32 mss = tcp_sk(sk)->advmss;
354 u32 icwnd = TCP_DEFAULT_INIT_RCVWND;
355 int rcvmem; 353 int rcvmem;
356 354
357 /* Limit to 10 segments if mss <= 1460, 355 rcvmem = 2 * SKB_TRUESIZE(mss + MAX_TCP_HEADER) *
358 * or 14600/mss segments, with a minimum of two segments. 356 tcp_default_init_rwnd(mss);
359 */
360 if (mss > 1460)
361 icwnd = max_t(u32, (1460 * TCP_DEFAULT_INIT_RCVWND) / mss, 2);
362
363 rcvmem = 2 * SKB_TRUESIZE(mss + MAX_TCP_HEADER);
364
365 rcvmem *= icwnd;
366 357
367 if (sk->sk_rcvbuf < rcvmem) 358 if (sk->sk_rcvbuf < rcvmem)
368 sk->sk_rcvbuf = min(rcvmem, sysctl_tcp_rmem[2]); 359 sk->sk_rcvbuf = min(rcvmem, sysctl_tcp_rmem[2]);