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:
parent
6da16e3eb0
commit
f092a3c71c
@ -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;
|
||||
|
||||
|
@ -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) &&
|
||||
|
@ -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) &&
|
||||
|
Loading…
Reference in New Issue
Block a user