So it turns out with the right window scaling you can get the code in all stacks to

always want to do a window update, even when no data can be sent. Now in
cases where you are not pacing thats probably ok, you just send an extra
window update or two. However with bbr (and rack if its paced) every time
the pacer goes off its going to send a "window update".

Also in testing bbr I have found that if we are not responding to
data right away we end up staying in startup but incorrectly holding
a pacing gain of 192 (a loss). This is because the idle window code
does not restict itself to only work with PROBE_BW. In all other
states you dont want it doing a PROBE_BW state change.

Sponsored by:	Netflix Inc.
Differential Revision: 	https://reviews.freebsd.org/D25247
This commit is contained in:
Randall Stewart 2020-06-12 19:56:19 +00:00
parent 6da16e3eb0
commit f092a3c71c
3 changed files with 28 additions and 13 deletions

View File

@ -655,7 +655,10 @@ tcp_output(struct tcpcb *tp)
adv = recwin;
if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt)) {
oldwin = (tp->rcv_adv - tp->rcv_nxt);
adv -= oldwin;
if (adv > oldwin)
adv -= oldwin;
else
adv = 0;
} else
oldwin = 0;

View File

@ -8078,7 +8078,7 @@ bbr_restart_after_idle(struct tcp_bbr *bbr, uint32_t cts, uint32_t idle_time)
bbr->r_ctl.rc_bbr_hptsi_gain = bbr->r_ctl.rc_startup_pg;
bbr->r_ctl.rc_bbr_cwnd_gain = bbr->r_ctl.rc_startup_pg;
bbr_log_type_statechange(bbr, cts, __LINE__);
} else {
} else if (bbr->rc_bbr_state == BBR_STATE_PROBE_BW) {
bbr_substate_change(bbr, cts, __LINE__, 1);
}
}
@ -12000,21 +12000,27 @@ bbr_window_update_needed(struct tcpcb *tp, struct socket *so, uint32_t recwin, i
* "adv" is the amount we could increase the window, taking into
* account that we are limited by TCP_MAXWIN << tp->rcv_scale.
*/
uint32_t adv;
int32_t adv;
int32_t oldwin;
adv = min(recwin, TCP_MAXWIN << tp->rcv_scale);
adv = recwin;
if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt)) {
oldwin = (tp->rcv_adv - tp->rcv_nxt);
adv -= oldwin;
if (adv > oldwin)
adv -= oldwin;
else {
/* We can't increase the window */
adv = 0;
}
} else
oldwin = 0;
/*
* If the new window size ends up being the same as the old size
* when it is scaled, then don't force a window update.
* If the new window size ends up being the same as or less
* than the old size when it is scaled, then don't force
* a window update.
*/
if (oldwin >> tp->rcv_scale == (adv + oldwin) >> tp->rcv_scale)
if (oldwin >> tp->rcv_scale >= (adv + oldwin) >> tp->rcv_scale)
return (0);
if (adv >= (2 * maxseg) &&

View File

@ -12845,18 +12845,24 @@ rack_output(struct tcpcb *tp)
int32_t adv;
int oldwin;
adv = min(recwin, (long)TCP_MAXWIN << tp->rcv_scale);
adv = recwin;
if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt)) {
oldwin = (tp->rcv_adv - tp->rcv_nxt);
adv -= oldwin;
if (adv > oldwin)
adv -= oldwin;
else {
/* We can't increase the window */
adv = 0;
}
} else
oldwin = 0;
/*
* If the new window size ends up being the same as the old
* size when it is scaled, then don't force a window update.
* If the new window size ends up being the same as or less
* than the old size when it is scaled, then don't force
* a window update.
*/
if (oldwin >> tp->rcv_scale == (adv + oldwin) >> tp->rcv_scale)
if (oldwin >> tp->rcv_scale >= (adv + oldwin) >> tp->rcv_scale)
goto dontupdate;
if (adv >= (int32_t)(2 * segsiz) &&