Skip to content
Snippets Groups Projects
Commit e072be26 authored by Avi Kivity's avatar Avi Kivity
Browse files

net: fix excessive window updates


Backported from FreeBSD r242252.

Improves netperf by about 10%.

Signed-off-by: default avatarAvi Kivity <avi@cloudius-systems.com>
parent f015cd5b
No related branches found
No related tags found
No related merge requests found
......@@ -509,19 +509,38 @@ after_sack_rexmit:
}
/*
* Compare available window to amount of window
* known to peer (as advertised window less
* next expected input). If the difference is at least two
* max size segments, or at least 50% of the maximum possible
* window, then want to send a window update to peer.
* Skip this if the connection is in T/TCP half-open state.
* Don't send pure window updates when the peer has closed
* the connection and won't ever send more data.
* Sending of standalone window updates.
*
* Window updates important when we close our window due to a full
* socket buffer and are opening it again after the application
* reads data from it. Once the window has opened again and the
* remote end starts to send again the ACK clock takes over and
* provides the most current window information.
*
* We must avoid to the silly window syndrome whereas every read
* from the receive buffer, no matter how small, causes a window
* update to be sent. We also should avoid sending a flurry of
* window updates when the socket buffer had queued a lot of data
* and the application is doing small reads.
*
* Prevent a flurry of pointless window updates by only sending
* an update when we can increase the advertized window by more
* than 1/4th of the socket buffer capacity. When the buffer is
* getting full or is very small be more aggressive and send an
* update whenever we can increase by two mss sized segments.
* In all other situations the ACK's to new incoming data will
* carry further window increases.
*
* Don't send an independent window update if a delayed
* ACK is pending (it will get piggy-backed on it) or the
* remote side already has done a half-close and won't send
* more data. Skip this if the connection is in T/TCP
* half-open state.
*/
if (recwin > 0 && !(tp->t_flags & TF_NEEDSYN) &&
!TCPS_HAVERCVDFIN(tp->t_state)) {
/*
* "adv" is the amount we can increase the window,
* "adv" is the amount we could increase the window,
* taking into account that we are limited by
* TCP_MAXWIN << tp->rcv_scale.
*/
......@@ -541,9 +560,11 @@ after_sack_rexmit:
*/
if (oldwin >> tp->rcv_scale == (adv + oldwin) >> tp->rcv_scale)
goto dontupdate;
if (adv >= (long) (2 * tp->t_maxseg))
goto send;
if (2 * adv >= (long) so->so_rcv.sb_hiwat)
if (adv >= (long)(2 * tp->t_maxseg) &&
(adv >= (long)(so->so_rcv.sb_hiwat / 4) ||
recwin <= (long)(so->so_rcv.sb_hiwat / 8) ||
so->so_rcv.sb_hiwat <= 8 * tp->t_maxseg))
goto send;
}
dontupdate:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment