1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-11-27 08:00:11 +00:00

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:
Richard Scheffenegger 2024-02-08 19:12:19 +01:00
parent 72c166696b
commit 32a6df57df
6 changed files with 66 additions and 23 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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);