In Collaboration with: Matt Macy <mmacy at nextbsd dot com>

Reviewed by:		    jtl
Sponsored by:		    Limelight Networks
Differential Revision:	    https://reviews.freebsd.org/D8225
This commit is contained in:
Hiren Panchasara 2016-10-25 05:03:33 +00:00
parent 1648616981
commit 95d8236011
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=307899
7 changed files with 94 additions and 31 deletions

View File

@ -431,6 +431,11 @@ static void
cdg_cong_signal(struct cc_var *ccv, uint32_t signal_type)
{
struct cdg *cdg_data = ccv->cc_data;
uint32_t cwin;
u_int mss;
cwin = CCV(ccv, snd_cwnd);
mss = CCV(ccv, t_maxseg);
switch(signal_type) {
case CC_CDG_DELAY:
@ -448,7 +453,7 @@ cdg_cong_signal(struct cc_var *ccv, uint32_t signal_type)
*/
if (IN_CONGRECOVERY(CCV(ccv, t_flags)) ||
cdg_data->queue_state < CDG_Q_FULL) {
CCV(ccv, snd_ssthresh) = CCV(ccv, snd_cwnd);
CCV(ccv, snd_ssthresh) = cwin;
CCV(ccv, snd_recover) = CCV(ccv, snd_max);
} else {
/*
@ -461,13 +466,17 @@ cdg_cong_signal(struct cc_var *ccv, uint32_t signal_type)
cdg_data->shadow_w, RENO_BETA);
CCV(ccv, snd_ssthresh) = max(cdg_data->shadow_w,
cdg_window_decrease(ccv, CCV(ccv, snd_cwnd),
V_cdg_beta_loss));
cdg_window_decrease(ccv, cwin, V_cdg_beta_loss));
CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh);
cdg_data->window_incr = cdg_data->rtt_count = 0;
}
ENTER_RECOVERY(CCV(ccv, t_flags));
break;
case CC_RTO:
CCV(ccv, snd_ssthresh) = max(2*mss, cwin/2);
CCV(ccv, snd_cwnd) = mss;
break;
default:
newreno_cc_algo.cong_signal(ccv, signal_type);
break;

View File

@ -330,10 +330,14 @@ chd_cong_signal(struct cc_var *ccv, uint32_t signal_type)
struct ertt *e_t;
struct chd *chd_data;
int qdly;
uint32_t cwin;
u_int mss;
e_t = khelp_get_osd(CCV(ccv, osd), ertt_id);
chd_data = ccv->cc_data;
qdly = imax(e_t->rtt, chd_data->maxrtt_in_rtt) - e_t->minrtt;
cwin = CCV(ccv, snd_cwnd);
mss = CCV(ccv, t_maxseg);
switch(signal_type) {
case CC_CHD_DELAY:
@ -373,6 +377,10 @@ chd_cong_signal(struct cc_var *ccv, uint32_t signal_type)
}
ENTER_FASTRECOVERY(CCV(ccv, t_flags));
break;
case CC_RTO:
CCV(ccv, snd_ssthresh) = max(2*mss, cwin/2);
CCV(ccv, snd_cwnd) = mss;
break;
default:
newreno_cc_algo.cong_signal(ccv, signal_type);

View File

@ -225,8 +225,12 @@ static void
cubic_cong_signal(struct cc_var *ccv, uint32_t type)
{
struct cubic *cubic_data;
uint32_t cwin;
u_int mss;
cubic_data = ccv->cc_data;
cwin = CCV(ccv, snd_cwnd);
mss = CCV(ccv, t_maxseg);
switch (type) {
case CC_NDUPACK:
@ -235,7 +239,8 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type)
cubic_ssthresh_update(ccv);
cubic_data->num_cong_events++;
cubic_data->prev_max_cwnd = cubic_data->max_cwnd;
cubic_data->max_cwnd = CCV(ccv, snd_cwnd);
cubic_data->max_cwnd = cwin;
CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh);
}
ENTER_RECOVERY(CCV(ccv, t_flags));
}
@ -246,7 +251,7 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type)
cubic_ssthresh_update(ccv);
cubic_data->num_cong_events++;
cubic_data->prev_max_cwnd = cubic_data->max_cwnd;
cubic_data->max_cwnd = CCV(ccv, snd_cwnd);
cubic_data->max_cwnd = cwin;
cubic_data->t_last_cong = ticks;
CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh);
ENTER_CONGRECOVERY(CCV(ccv, t_flags));
@ -261,9 +266,13 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type)
* chance the first one is a false alarm and may not indicate
* congestion.
*/
if (CCV(ccv, t_rxtshift) >= 2)
if (CCV(ccv, t_rxtshift) >= 2) {
cubic_data->num_cong_events++;
cubic_data->t_last_cong = ticks;
cubic_ssthresh_update(ccv);
cubic_data->max_cwnd = cwin;
CCV(ccv, snd_cwnd) = mss;
}
break;
}
}

View File

@ -230,10 +230,11 @@ static void
dctcp_cong_signal(struct cc_var *ccv, uint32_t type)
{
struct dctcp *dctcp_data;
u_int win, mss;
uint32_t cwin;
u_int mss;
dctcp_data = ccv->cc_data;
win = CCV(ccv, snd_cwnd);
cwin = CCV(ccv, snd_cwnd);
mss = CCV(ccv, t_maxseg);
switch (type) {
@ -241,16 +242,16 @@ dctcp_cong_signal(struct cc_var *ccv, uint32_t type)
if (!IN_FASTRECOVERY(CCV(ccv, t_flags))) {
if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
CCV(ccv, snd_ssthresh) = mss *
max(win / 2 / mss, 2);
max(cwin / 2 / mss, 2);
dctcp_data->num_cong_events++;
} else {
/* cwnd has already updated as congestion
* recovery. Reverse cwnd value using
* snd_cwnd_prev and recalculate snd_ssthresh
*/
win = CCV(ccv, snd_cwnd_prev);
cwin = CCV(ccv, snd_cwnd_prev);
CCV(ccv, snd_ssthresh) =
max(win / 2 / mss, 2) * mss;
max(cwin / 2 / mss, 2) * mss;
}
ENTER_RECOVERY(CCV(ccv, t_flags));
}
@ -260,18 +261,18 @@ dctcp_cong_signal(struct cc_var *ccv, uint32_t type)
* Save current snd_cwnd when the host encounters both
* congestion recovery and fast recovery.
*/
CCV(ccv, snd_cwnd_prev) = win;
CCV(ccv, snd_cwnd_prev) = cwin;
if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
if (V_dctcp_slowstart &&
dctcp_data->num_cong_events++ == 0) {
CCV(ccv, snd_ssthresh) =
mss * max(win / 2 / mss, 2);
mss * max(cwin / 2 / mss, 2);
dctcp_data->alpha = MAX_ALPHA_VALUE;
dctcp_data->bytes_ecn = 0;
dctcp_data->bytes_total = 0;
dctcp_data->save_sndnxt = CCV(ccv, snd_nxt);
} else
CCV(ccv, snd_ssthresh) = max((win - ((win *
CCV(ccv, snd_ssthresh) = max((cwin - ((cwin *
dctcp_data->alpha) >> 11)) / mss, 2) * mss;
CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh);
ENTER_CONGRECOVERY(CCV(ccv, t_flags));
@ -284,6 +285,8 @@ dctcp_cong_signal(struct cc_var *ccv, uint32_t type)
dctcp_update_alpha(ccv);
dctcp_data->save_sndnxt += CCV(ccv, t_maxseg);
dctcp_data->num_cong_events++;
CCV(ccv, snd_ssthresh) = max(2 * mss, cwin / 2);
CCV(ccv, snd_cwnd) = mss;
}
break;
}

View File

@ -271,8 +271,12 @@ static void
htcp_cong_signal(struct cc_var *ccv, uint32_t type)
{
struct htcp *htcp_data;
uint32_t cwin;
u_int mss;
htcp_data = ccv->cc_data;
cwin = CCV(ccv, snd_cwnd);
mss = CCV(ccv, t_maxseg);
switch (type) {
case CC_NDUPACK:
@ -287,8 +291,9 @@ htcp_cong_signal(struct cc_var *ccv, uint32_t type)
(htcp_data->maxrtt - htcp_data->minrtt) *
95) / 100;
htcp_ssthresh_update(ccv);
CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh);
htcp_data->t_last_cong = ticks;
htcp_data->prev_cwnd = CCV(ccv, snd_cwnd);
htcp_data->prev_cwnd = cwin;
}
ENTER_RECOVERY(CCV(ccv, t_flags));
}
@ -305,7 +310,7 @@ htcp_cong_signal(struct cc_var *ccv, uint32_t type)
htcp_ssthresh_update(ccv);
CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh);
htcp_data->t_last_cong = ticks;
htcp_data->prev_cwnd = CCV(ccv, snd_cwnd);
htcp_data->prev_cwnd = cwin;
ENTER_CONGRECOVERY(CCV(ccv, t_flags));
}
break;
@ -320,6 +325,8 @@ htcp_cong_signal(struct cc_var *ccv, uint32_t type)
*/
if (CCV(ccv, t_rxtshift) >= 2)
htcp_data->t_last_cong = ticks;
CCV(ccv, snd_ssthresh) = max(2 * mss, cwin / 2);
CCV(ccv, snd_cwnd) = mss;
break;
}
}

View File

@ -182,30 +182,39 @@ newreno_after_idle(struct cc_var *ccv)
static void
newreno_cong_signal(struct cc_var *ccv, uint32_t type)
{
u_int win;
uint32_t cwin;
u_int mss;
cwin = CCV(ccv, snd_cwnd);
mss = CCV(ccv, t_maxseg);
/* Catch algos which mistakenly leak private signal types. */
KASSERT((type & CC_SIGPRIVMASK) == 0,
("%s: congestion signal type 0x%08x is private\n", __func__, type));
win = max(CCV(ccv, snd_cwnd) / 2 / CCV(ccv, t_maxseg), 2) *
CCV(ccv, t_maxseg);
cwin = max(2*mss, cwin/2);
switch (type) {
case CC_NDUPACK:
if (!IN_FASTRECOVERY(CCV(ccv, t_flags))) {
if (!IN_CONGRECOVERY(CCV(ccv, t_flags)))
CCV(ccv, snd_ssthresh) = win;
if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
CCV(ccv, snd_ssthresh) = cwin;
CCV(ccv, snd_cwnd) = cwin;
}
ENTER_RECOVERY(CCV(ccv, t_flags));
}
break;
case CC_ECN:
if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
CCV(ccv, snd_ssthresh) = win;
CCV(ccv, snd_cwnd) = win;
CCV(ccv, snd_ssthresh) = cwin;
CCV(ccv, snd_cwnd) = cwin;
ENTER_CONGRECOVERY(CCV(ccv, t_flags));
}
break;
case CC_RTO:
CCV(ccv, snd_ssthresh) = cwin;
CCV(ccv, snd_cwnd) = mss;
break;
}
}

View File

@ -438,9 +438,15 @@ cc_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type)
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 (CC_ALGO(tp)->cong_signal == NULL) {
/*
* RFC5681 Section 3.1
* ssthresh = max (FlightSize / 2, 2*SMSS) eq (4)
*/
tp->snd_ssthresh =
max((tp->snd_max - tp->snd_una) / 2, 2 * maxseg);
tp->snd_cwnd = maxseg;
}
break;
case CC_RTO_ERR:
TCPSTAT_INC(tcps_sndrexmitbad);
@ -2613,6 +2619,15 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (awnd < tp->snd_ssthresh) {
tp->snd_cwnd += maxseg;
/*
* RFC5681 Section 3.2 talks about cwnd
* inflation on additional dupacks and
* deflation on recovering from loss.
*
* We keep cwnd into check so that
* we don't have to 'deflate' it when we
* get out of recovery.
*/
if (tp->snd_cwnd > tp->snd_ssthresh)
tp->snd_cwnd = tp->snd_ssthresh;
}
@ -2652,19 +2667,22 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
TCPSTAT_INC(
tcps_sack_recovery_episode);
tp->sack_newdata = tp->snd_nxt;
tp->snd_cwnd = maxseg;
if (CC_ALGO(tp)->cong_signal == NULL)
tp->snd_cwnd = maxseg;
(void) tp->t_fb->tfb_tcp_output(tp);
goto drop;
}
tp->snd_nxt = th->th_ack;
tp->snd_cwnd = maxseg;
if (CC_ALGO(tp)->cong_signal == NULL)
tp->snd_cwnd = maxseg;
(void) tp->t_fb->tfb_tcp_output(tp);
KASSERT(tp->snd_limited <= 2,
("%s: tp->snd_limited too big",
__func__));
tp->snd_cwnd = tp->snd_ssthresh +
maxseg *
(tp->t_dupacks - tp->snd_limited);
if (CC_ALGO(tp)->cong_signal == NULL)
tp->snd_cwnd = tp->snd_ssthresh +
maxseg *
(tp->t_dupacks - tp->snd_limited);
if (SEQ_GT(onxt, tp->snd_nxt))
tp->snd_nxt = onxt;
goto drop;