net: tcp: Fix up the receive window
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 18 Jul 2017 13:36:53 +0000 (09:36 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 21 Jul 2017 15:56:27 +0000 (11:56 -0400)
There are a few things involved:

1) Plan 9 had a bug setting tcb->window.  We need to use rcv.scale, not
snd.scale.

2) QIO limits do nothing for the TCP receive queue.  All that qsetlimit and
qopen business is just tricking us into thinking it does something.

3) Our window scale was based on the bandwidth.  You actually want the BDP,
but you can't know that early on, and it's all heuristics.  Just going with
'7' is fine.  '3' is way too low; it leads to at most 512 KB in flight,
which is practically nothing.  Maybe we'll revisit this.

We're still doing no real management of the maximum receive window.  Plan 9
never really did that either.  The downside to this is that we promise to
receive and buffer that much data in RAM until the application drains it.
If this becomes an issue, we can change or tune it.

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

index eab581b..9a0e2a9 100644 (file)
@@ -702,7 +702,9 @@ void tcpacktimer(void *v)
 
 static void tcpcreate(struct conv *c)
 {
-       c->rq = qopen(QMAX, Qcoalesce, 0, 0);
+       /* We don't use qio limits.  Instead, TCP manages flow control on its own.
+        * We only use qpassnolim().  Note for qio that 0 doesn't mean no limit. */
+       c->rq = qopen(0, Qcoalesce, 0, 0);
        c->wq = qopen(8 * QMAX, Qkick, tcpkick, c);
 }
 
@@ -870,18 +872,9 @@ int tcpmtu(struct Proto *tcp, uint8_t * addr, int version, int *scale,
                        break;
        }
        *flags &= ~TSO;
-
-       if (ifc != NULL) {
-               if (ifc->mbps > 100)
-                       *scale = HaveWS | 3;
-               else if (ifc->mbps > 10)
-                       *scale = HaveWS | 1;
-               else
-                       *scale = HaveWS | 0;
-               if (ifc->feat & NETF_TSO)
-                       *flags |= TSO;
-       } else
-               *scale = HaveWS | 0;
+       if (ifc && (ifc->feat & NETF_TSO))
+               *flags |= TSO;
+       *scale = HaveWS | 7;
 
        return mtu;
 }
@@ -954,7 +947,6 @@ void inittcpctl(struct conv *s, int mode)
        tcb->rcv.wnd = QMAX;
        tcb->rcv.scale = 0;
        tcb->snd.scale = 0;
-       qsetlimit(s->rq, QMAX);
 }
 
 /*
@@ -4070,12 +4062,10 @@ tcpsetscale(struct conv *s, Tcpctl * tcb, uint16_t rcvscale, uint16_t sndscale)
        if (rcvscale) {
                tcb->rcv.scale = rcvscale & 0xff;
                tcb->snd.scale = sndscale & 0xff;
-               tcb->window = QMAX << tcb->snd.scale;
-               qsetlimit(s->rq, tcb->window);
+               tcb->window = QMAX << tcb->rcv.scale;
        } else {
                tcb->rcv.scale = 0;
                tcb->snd.scale = 0;
                tcb->window = QMAX;
-               qsetlimit(s->rq, tcb->window);
        }
 }