net: tcp: Avoid SWS for the sender
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 17 Jul 2017 20:15:53 +0000 (16:15 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 21 Jul 2017 15:56:27 +0000 (11:56 -0400)
RFC 813.  Note that if you just did usable < MSS, but didn't look at
snd.wnd, then you might get what qemu's user networking did to me.  A
usable < MSS, but because the application didn't drain the queue yet.
Everything was acked.  In that case, you'd stop short and never send that
last packet.

I don't know if that's the receiver's fault or not, but we (the sender
here) should be defensive.  After all, maybe we'll interact with a Plan 9
machine!

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/src/net/tcp.c

index 1655d78..eab581b 100644 (file)
@@ -3094,6 +3094,21 @@ static bool throttle_ssize(struct conv *s, Tcpctl *tcb, uint32_t *ssize_p,
                        usable -= tcb->snd.in_flight;
                else
                        usable = 0;
+               /* Avoid Silly Window Syndrome.  This is a little different thant RFC
+                * 813.  I took their additional enhancement of "< MSS" as an AND, not
+                * an OR.  25% of a large snd.wnd is pretty large, and our main goal is
+                * to avoid packets smaller than MSS.  I still use the 25% threshold,
+                * because it is important that there is *some* data in_flight.  If
+                * usable < MSS because snd.wnd is very small (but not 0), we might
+                * never get an ACK and would need to set up a timer.
+                *
+                * Also, I'm using 'ssize' as a proxy for a PSH point.  If there's just
+                * a small blob in the qio (or retrans!), then we might as well just
+                * send it. */
+               if ((usable < tcb->typical_mss) && (usable < tcb->snd.wnd >> 2)
+                   && (usable < ssize)) {
+                       return FALSE;
+               }
        }
        if (ssize && usable < 2)
                netlog(s->p->f, Logtcpverbose,