git: 32a6df57df3e - main - tcp: calculate ssthresh on RTO according to RFC5681
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 08 Feb 2024 18:55:14 UTC
The branch main has been updated by rscheff: URL: https://cgit.FreeBSD.org/src/commit/?id=32a6df57df3ef5783bc4bb066cce9c476496e7a9 commit 32a6df57df3ef5783bc4bb066cce9c476496e7a9 Author: Richard Scheffenegger <rscheff@FreeBSD.org> AuthorDate: 2024-02-08 18:12:19 +0000 Commit: Richard Scheffenegger <rscheff@FreeBSD.org> CommitDate: 2024-02-08 18:18:26 +0000 tcp: calculate ssthresh on RTO according to RFC5681 per RFC5681, only adjust ssthresh on the initital retransmission timeout. Since RTO often happens during loss recovery, while cwnd no longer tracks all data in flight, calculcate pipe properly. Reviewed By: tuexen, #transport Sponsored by: NetApp, Inc. Differential Revision: https://reviews.freebsd.org/D43768 --- sys/netinet/cc/cc.c | 17 ++++++++++++----- sys/netinet/cc/cc_cubic.c | 14 +++++++++++--- sys/netinet/cc/cc_dctcp.c | 16 ++++++++++++---- sys/netinet/cc/cc_htcp.c | 16 ++++++++++++---- sys/netinet/cc/cc_newreno.c | 19 ++++++++++++++----- sys/netinet/tcp_stacks/rack.c | 7 +++++-- 6 files changed, 66 insertions(+), 23 deletions(-) diff --git a/sys/netinet/cc/cc.c b/sys/netinet/cc/cc.c index ff25b8368cc4..a3d19e31d438 100644 --- a/sys/netinet/cc/cc.c +++ b/sys/netinet/cc/cc.c @@ -454,8 +454,7 @@ newreno_cc_after_idle(struct cc_var *ccv) void newreno_cc_cong_signal(struct cc_var *ccv, uint32_t type) { - uint32_t cwin, factor; - u_int mss; + uint32_t cwin, factor, mss, pipe; cwin = CCV(ccv, snd_cwnd); mss = tcp_fixed_maxseg(ccv->ccvc.tcp); @@ -489,9 +488,17 @@ newreno_cc_cong_signal(struct cc_var *ccv, uint32_t type) } break; case CC_RTO: - CCV(ccv, snd_ssthresh) = max(min(CCV(ccv, snd_wnd), - CCV(ccv, snd_cwnd)) / 2 / mss, - 2) * mss; + if (CCV(ccv, t_rxtshift) == 1) { + if (V_tcp_do_newsack) { + pipe = tcp_compute_pipe(ccv->ccvc.tcp); + } else { + pipe = CCV(ccv, snd_nxt) - + CCV(ccv, snd_fack) + + CCV(ccv, sackhint.sack_bytes_rexmit); + } + CCV(ccv, snd_ssthresh) = max(2, + min(CCV(ccv, snd_wnd), pipe) / 2 / mss) * mss; + } CCV(ccv, snd_cwnd) = mss; break; } diff --git a/sys/netinet/cc/cc_cubic.c b/sys/netinet/cc/cc_cubic.c index 3f7ba630db5d..dcb096af6cbf 100644 --- a/sys/netinet/cc/cc_cubic.c +++ b/sys/netinet/cc/cc_cubic.c @@ -420,7 +420,7 @@ static void cubic_cong_signal(struct cc_var *ccv, uint32_t type) { struct cubic *cubic_data; - u_int mss; + uint32_t mss, pipe; cubic_data = ccv->cc_data; mss = tcp_fixed_maxseg(ccv->ccvc.tcp); @@ -476,12 +476,20 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type) cubic_data->undo_cwnd_prior = cubic_data->cwnd_prior; cubic_data->undo_W_max = cubic_data->W_max; cubic_data->undo_K = cubic_data->K; + if (V_tcp_do_newsack) { + pipe = tcp_compute_pipe(ccv->ccvc.tcp); + } else { + pipe = CCV(ccv, snd_nxt) - + CCV(ccv, snd_fack) + + CCV(ccv, sackhint.sack_bytes_rexmit); + } + CCV(ccv, snd_ssthresh) = max(2, + (((uint64_t)min(CCV(ccv, snd_wnd), pipe) * + CUBIC_BETA) >> CUBIC_SHIFT) / mss) * mss; } cubic_data->flags |= CUBICFLAG_CONG_EVENT | CUBICFLAG_RTO_EVENT; cubic_data->undo_W_max = cubic_data->W_max; cubic_data->num_cong_events++; - CCV(ccv, snd_ssthresh) = ((uint64_t)CCV(ccv, snd_cwnd) * - CUBIC_BETA) >> CUBIC_SHIFT; CCV(ccv, snd_cwnd) = mss; break; diff --git a/sys/netinet/cc/cc_dctcp.c b/sys/netinet/cc/cc_dctcp.c index efb8913ec36c..41db7e0811aa 100644 --- a/sys/netinet/cc/cc_dctcp.c +++ b/sys/netinet/cc/cc_dctcp.c @@ -240,7 +240,7 @@ static void dctcp_cong_signal(struct cc_var *ccv, uint32_t type) { struct dctcp *dctcp_data; - u_int cwin, mss; + uint32_t cwin, mss, pipe; if (CCV(ccv, t_flags2) & TF2_ECN_PERMIT) { dctcp_data = ccv->cc_data; @@ -292,9 +292,17 @@ dctcp_cong_signal(struct cc_var *ccv, uint32_t type) dctcp_data->ece_curr = 1; break; case CC_RTO: - CCV(ccv, snd_ssthresh) = max(min(CCV(ccv, snd_wnd), - CCV(ccv, snd_cwnd)) / 2 / mss, - 2) * mss; + if (CCV(ccv, t_rxtshift) == 1) { + if (V_tcp_do_newsack) { + pipe = tcp_compute_pipe(ccv->ccvc.tcp); + } else { + pipe = CCV(ccv, snd_nxt) - + CCV(ccv, snd_fack) + + CCV(ccv, sackhint.sack_bytes_rexmit); + } + CCV(ccv, snd_ssthresh) = max(2, + min(CCV(ccv, snd_wnd), pipe) / 2 / mss) * mss; + } CCV(ccv, snd_cwnd) = mss; dctcp_update_alpha(ccv); dctcp_data->save_sndnxt += CCV(ccv, t_maxseg); diff --git a/sys/netinet/cc/cc_htcp.c b/sys/netinet/cc/cc_htcp.c index c9304fcfc8e5..7500446d3051 100644 --- a/sys/netinet/cc/cc_htcp.c +++ b/sys/netinet/cc/cc_htcp.c @@ -281,7 +281,7 @@ static void htcp_cong_signal(struct cc_var *ccv, uint32_t type) { struct htcp *htcp_data; - u_int mss; + uint32_t mss, pipe; htcp_data = ccv->cc_data; mss = tcp_fixed_maxseg(ccv->ccvc.tcp); @@ -323,9 +323,17 @@ htcp_cong_signal(struct cc_var *ccv, uint32_t type) break; case CC_RTO: - CCV(ccv, snd_ssthresh) = max(min(CCV(ccv, snd_wnd), - CCV(ccv, snd_cwnd)) / 2 / mss, - 2) * mss; + if (CCV(ccv, t_rxtshift) == 1) { + if (V_tcp_do_newsack) { + pipe = tcp_compute_pipe(ccv->ccvc.tcp); + } else { + pipe = CCV(ccv, snd_nxt) - + CCV(ccv, snd_fack) + + CCV(ccv, sackhint.sack_bytes_rexmit); + } + CCV(ccv, snd_ssthresh) = max(2, + min(CCV(ccv, snd_wnd), pipe) / 2 / mss) * mss; + } CCV(ccv, snd_cwnd) = mss; /* * Grab the current time and record it so we know when the diff --git a/sys/netinet/cc/cc_newreno.c b/sys/netinet/cc/cc_newreno.c index 53d066682a7d..4f55fb7e0f7a 100644 --- a/sys/netinet/cc/cc_newreno.c +++ b/sys/netinet/cc/cc_newreno.c @@ -366,8 +366,7 @@ static void newreno_cong_signal(struct cc_var *ccv, uint32_t type) { struct newreno *nreno; - uint32_t beta, beta_ecn, cwin, factor; - u_int mss; + uint32_t beta, beta_ecn, cwin, factor, mss, pipe; cwin = CCV(ccv, snd_cwnd); mss = tcp_fixed_maxseg(ccv->ccvc.tcp); @@ -428,9 +427,19 @@ newreno_cong_signal(struct cc_var *ccv, uint32_t type) } break; case CC_RTO: - CCV(ccv, snd_ssthresh) = max(min(CCV(ccv, snd_wnd), - CCV(ccv, snd_cwnd)) / 2 / mss, - 2) * mss; + if (CCV(ccv, t_rxtshift) == 1) { + if (V_tcp_do_newsack) { + pipe = tcp_compute_pipe(ccv->ccvc.tcp); + } else { + pipe = CCV(ccv, snd_nxt) - + CCV(ccv, snd_fack) + + CCV(ccv, sackhint.sack_bytes_rexmit); + } + CCV(ccv, snd_ssthresh) = max(2, + ((uint64_t)min(CCV(ccv, snd_wnd), pipe) * + (uint64_t)factor) / + (100ULL * (uint64_t)mss)) * mss; + } CCV(ccv, snd_cwnd) = mss; break; } diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c index 10ab20f00e26..0ec50bb5e5c5 100644 --- a/sys/netinet/tcp_stacks/rack.c +++ b/sys/netinet/tcp_stacks/rack.c @@ -5948,8 +5948,11 @@ rack_cong_signal(struct tcpcb *tp, uint32_t type, uint32_t ack, int line) tp->t_bytes_acked = 0; rack->r_fast_output = 0; EXIT_RECOVERY(tp->t_flags); - tp->snd_ssthresh = max(2, min(tp->snd_wnd, rack->r_ctl.cwnd_to_use) / 2 / - ctf_fixed_maxseg(tp)) * ctf_fixed_maxseg(tp); + if (tp->t_rxtshift == 1) { + tp->snd_ssthresh = max(2, + min(tp->snd_wnd, rack->r_ctl.cwnd_to_use) / 2 / + ctf_fixed_maxseg(tp)) * ctf_fixed_maxseg(tp); + } orig_cwnd = tp->snd_cwnd; tp->snd_cwnd = ctf_fixed_maxseg(tp); rack_log_to_prr(rack, 16, orig_cwnd, line);