Index: head/sys/netinet/cc/cc_cubic.c =================================================================== --- head/sys/netinet/cc/cc_cubic.c +++ head/sys/netinet/cc/cc_cubic.c @@ -264,8 +264,10 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type) { struct cubic *cubic_data; + u_int mss; cubic_data = ccv->cc_data; + mss = tcp_maxseg(ccv->ccvc.tcp); switch (type) { case CC_NDUPACK: @@ -292,6 +294,10 @@ break; case CC_RTO: + CCV(ccv, snd_ssthresh) = max(min(CCV(ccv, snd_wnd), + CCV(ccv, snd_cwnd)) / 2 / mss, + 2) * mss; + CCV(ccv, snd_cwnd) = mss; /* * Grab the current time and record it so we know when the * most recent congestion event was. Only record it when the Index: head/sys/netinet/cc/cc_dctcp.c =================================================================== --- head/sys/netinet/cc/cc_dctcp.c +++ head/sys/netinet/cc/cc_dctcp.c @@ -235,7 +235,7 @@ if (CCV(ccv, t_flags2) & TF2_ECN_PERMIT) { dctcp_data = ccv->cc_data; cwin = CCV(ccv, snd_cwnd); - mss = CCV(ccv, t_maxseg); + mss = tcp_maxseg(ccv->ccvc.tcp); switch (type) { case CC_NDUPACK: @@ -282,6 +282,10 @@ 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; + CCV(ccv, snd_cwnd) = mss; dctcp_update_alpha(ccv); dctcp_data->save_sndnxt += CCV(ccv, t_maxseg); dctcp_data->num_cong_events++; Index: head/sys/netinet/cc/cc_htcp.c =================================================================== --- head/sys/netinet/cc/cc_htcp.c +++ head/sys/netinet/cc/cc_htcp.c @@ -271,8 +271,10 @@ htcp_cong_signal(struct cc_var *ccv, uint32_t type) { struct htcp *htcp_data; + u_int mss; htcp_data = ccv->cc_data; + mss = tcp_maxseg(ccv->ccvc.tcp); switch (type) { case CC_NDUPACK: @@ -311,6 +313,10 @@ break; case CC_RTO: + CCV(ccv, snd_ssthresh) = max(min(CCV(ccv, snd_wnd), + CCV(ccv, snd_cwnd)) / 2 / mss, + 2) * mss; + CCV(ccv, snd_cwnd) = mss; /* * Grab the current time and record it so we know when the * most recent congestion event was. Only record it when the Index: head/sys/netinet/cc/cc_newreno.c =================================================================== --- head/sys/netinet/cc/cc_newreno.c +++ head/sys/netinet/cc/cc_newreno.c @@ -237,7 +237,7 @@ u_int mss; cwin = CCV(ccv, snd_cwnd); - mss = CCV(ccv, t_maxseg); + mss = tcp_maxseg(ccv->ccvc.tcp); nreno = ccv->cc_data; beta = (nreno == NULL) ? V_newreno_beta : nreno->beta; beta_ecn = (nreno == NULL) ? V_newreno_beta_ecn : nreno->beta_ecn; @@ -274,6 +274,12 @@ CCV(ccv, snd_cwnd) = cwin; ENTER_CONGRECOVERY(CCV(ccv, t_flags)); } + break; + case CC_RTO: + CCV(ccv, snd_ssthresh) = max(min(CCV(ccv, snd_wnd), + CCV(ccv, snd_cwnd)) / 2 / mss, + 2) * mss; + CCV(ccv, snd_cwnd) = mss; break; } } Index: head/sys/netinet/tcp_input.c =================================================================== --- head/sys/netinet/tcp_input.c +++ head/sys/netinet/tcp_input.c @@ -429,8 +429,6 @@ void inline cc_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type) { - u_int maxseg; - INP_WLOCK_ASSERT(tp->t_inpcb); #ifdef STATS @@ -460,13 +458,9 @@ } break; case CC_RTO: - maxseg = tcp_maxseg(tp); tp->t_dupacks = 0; tp->t_bytes_acked = 0; EXIT_RECOVERY(tp->t_flags); - tp->snd_ssthresh = max(2, min(tp->snd_wnd, tp->snd_cwnd) / 2 / - maxseg) * maxseg; - tp->snd_cwnd = maxseg; if (tp->t_flags2 & TF2_ECN_PERMIT) tp->t_flags2 |= TF2_ECN_SND_CWR; break;