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
This commit is contained in:
+12
-5
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user