diff --git a/sys/netinet/cc/cc.c b/sys/netinet/cc/cc.c --- a/sys/netinet/cc/cc.c +++ b/sys/netinet/cc/cc.c @@ -454,8 +454,7 @@ 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 @@ } 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 --- a/sys/netinet/cc/cc_cubic.c +++ b/sys/netinet/cc/cc_cubic.c @@ -420,7 +420,7 @@ 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_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 --- a/sys/netinet/cc/cc_dctcp.c +++ b/sys/netinet/cc/cc_dctcp.c @@ -240,7 +240,7 @@ 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_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 --- a/sys/netinet/cc/cc_htcp.c +++ b/sys/netinet/cc/cc_htcp.c @@ -281,7 +281,7 @@ 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 @@ 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 --- a/sys/netinet/cc/cc_newreno.c +++ b/sys/netinet/cc/cc_newreno.c @@ -366,8 +366,7 @@ 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 @@ } 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 --- a/sys/netinet/tcp_stacks/rack.c +++ b/sys/netinet/tcp_stacks/rack.c @@ -5948,8 +5948,11 @@ 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);