Skip to content

Commit 336c39a

Browse files
yuchungchengdavem330
authored andcommitted
tcp: undo init congestion window on false SYNACK timeout
Linux implements RFC6298 and use an initial congestion window of 1 upon establishing the connection if the SYNACK packet is retransmitted 2 or more times. In cellular networks SYNACK timeouts are often spurious if the wireless radio was dormant or idle. Also some network path is longer than the default SYNACK timeout. In both cases falsely starting with a minimal cwnd are detrimental to performance. This patch avoids doing so when the final ACK's TCP timestamp indicates the original SYNACK was delivered. It remembers the original SYNACK timestamp when SYNACK timeout has occurred and re-uses the function to detect spurious SYN timeout conveniently. Note that a server may receives multiple SYNs from and immediately retransmits SYNACKs without any SYNACK timeout. This often happens on when the client SYNs have timed out due to wireless delay above. In this case since the server will still use the default initial congestion (e.g. 10) because tp->undo_marker is reset in tcp_init_metrics(). This is an intentional design because packets are not lost but delayed. This patch only covers regular TCP passive open. Fast Open is supported in the next patch. Signed-off-by: Yuchung Cheng <[email protected]> Signed-off-by: Neal Cardwell <[email protected]> Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 9e450c1 commit 336c39a

File tree

2 files changed

+7
-0
lines changed

2 files changed

+7
-0
lines changed

net/ipv4/tcp_input.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6101,6 +6101,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb)
61016101
*/
61026102
tcp_rearm_rto(sk);
61036103
} else {
6104+
tcp_try_undo_spurious_syn(sk);
6105+
tp->retrans_stamp = 0;
61046106
tcp_init_transfer(sk, BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB);
61056107
tp->copied_seq = tp->rcv_nxt;
61066108
}

net/ipv4/tcp_minisocks.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,11 @@ struct sock *tcp_create_openreq_child(const struct sock *sk,
522522
newtp->rx_opt.ts_recent_stamp = 0;
523523
newtp->tcp_header_len = sizeof(struct tcphdr);
524524
}
525+
if (req->num_timeout) {
526+
newtp->undo_marker = treq->snt_isn;
527+
newtp->retrans_stamp = div_u64(treq->snt_synack,
528+
USEC_PER_SEC / TCP_TS_HZ);
529+
}
525530
newtp->tsoffset = treq->ts_off;
526531
#ifdef CONFIG_TCP_MD5SIG
527532
newtp->md5sig_info = NULL; /*XXX*/

0 commit comments

Comments
 (0)