From 1d4bb27834523e4f5c839bb2c04d03c408d404f7 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 14 Jul 2002 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2002-07-14 --- ip/tcp.c | 2 +- pc/etherga620.c | 171 ++++++++++++++++++++++++++++++++++++++++-------- port/qio.c | 13 +++- 3 files changed, 154 insertions(+), 32 deletions(-) diff --git a/ip/tcp.c b/ip/tcp.c index e14fbc1b1ff6f93e3d627bec784b3e1974ab227e..1ab0ed3d8b0ca10ddced05e97668ca49b02454fc 100644 --- a/ip/tcp.c +++ b/ip/tcp.c @@ -576,7 +576,7 @@ static void tcpcreate(Conv *c) { c->rq = qopen(QMAX, Qcoalesce, tcpacktimer, c); - c->wq = qopen(4*QMAX, Qkick, tcpkick, c); + c->wq = qopen((3*QMAX)/2, Qkick, tcpkick, c); } static void diff --git a/pc/etherga620.c b/pc/etherga620.c index 680eb17f63f9950e845b848b260315cc7a37a6e8..6e286cc17fb43cb5a53a3c84fef8c28e98aa1e11 100644 --- a/pc/etherga620.c +++ b/pc/etherga620.c @@ -24,13 +24,6 @@ #include "etherif.h" #include "etherga620fw.h" -enum { /* Compile-time options */ - DoMhcCheck = 1, - DoCoalUpdateOnly= 1, - DoHardwareCksum = 0, - DoCountTicks = 1, -}; - enum { Mhc = 0x0040, /* Miscellaneous Host Control */ Mlc = 0x0044, /* Miscellaneous Local Control */ @@ -259,9 +252,6 @@ typedef struct Ctlr { uchar ea[Eaddrlen]; - int interrupts; - uvlong ticks; - int* nic; Gib* gib; @@ -284,6 +274,17 @@ typedef struct Ctlr { int epi[2]; /* Event Producer Index */ int rrrpi[2]; /* Receive Return Ring Producer Index */ int sci[3]; /* Send Consumer Index ([2] is host) */ + + int interrupts; /* statistics */ + uvlong ticks; + + int coalupdateonly; /* tuning */ + int hardwarecksum; + int rct; /* Receive Coalesce Ticks */ + int sct; /* Send Coalesce Ticks */ + int st; /* Stat Ticks */ + int smcbd; /* Send Max. Coalesced BDs */ + int rmcbd; /* Receive Max. Coalesced BDs */ } Ctlr; static Ctlr* ctlrhead; @@ -342,7 +343,13 @@ ga620ifstat(Ether* edev, void* a, long n, ulong offset) } l += snprint(p+l, READSTR-l, "interrupts: %ud\n", ctlr->interrupts); - snprint(p+l, READSTR-l, "ticks: %llud\n", ctlr->ticks); + l += snprint(p+l, READSTR-l, "ticks: %llud\n", ctlr->ticks); + l += snprint(p+l, READSTR-l, "coalupdateonly: %d\n", ctlr->coalupdateonly); + l += snprint(p+l, READSTR-l, "hardwarecksum: %d\n", ctlr->hardwarecksum); + l += snprint(p+l, READSTR-l, "rct: %d\n", ctlr->rct); + l += snprint(p+l, READSTR-l, "sct: %d\n", ctlr->sct); + l += snprint(p+l, READSTR-l, "smcbd: %d\n", ctlr->smcbd); + snprint(p+l, READSTR-l, "rmcbd: %d\n", ctlr->rmcbd); n = readstr(offset, a, n, p); free(p); @@ -350,6 +357,111 @@ ga620ifstat(Ether* edev, void* a, long n, ulong offset) return n; } +static long +ga620ctl(Ether* edev, void* buf, long n) +{ + char *p; + Cmdbuf *cb; + Ctlr *ctlr; + int control, i, r; + + ctlr = edev->ctlr; + if(ctlr == nil) + error(Enonexist); + r = 0; + cb = parsecmd(buf, n); + if(cb->nf < 2) + r = -1; + else if(cistrcmp(cb->f[0], "coalupdateonly") == 0){ + if(cistrcmp(cb->f[1], "off") == 0){ + control = ctlr->gib->srcb.control; + control &= ~CoalUpdateOnly; + ctlr->gib->srcb.control = control; + } + else if(cistrcmp(cb->f[1], "on") == 0){ + control = ctlr->gib->srcb.control; + control |= CoalUpdateOnly; + ctlr->gib->srcb.control = control; + } + else + r = -1; + } + else if(cistrcmp(cb->f[0], "hardwarecksum") == 0){ + if(cistrcmp(cb->f[1], "off") == 0){ + control = ctlr->gib->srcb.control; + control &= ~(TcpUdpCksum|NoPseudoHdrCksum); + ctlr->gib->srcb.control = control; + + control = ctlr->gib->rsrcb.control; + control &= ~(TcpUdpCksum|NoPseudoHdrCksum); + ctlr->gib->rsrcb.control = control; + } + else if(cistrcmp(cb->f[1], "on") == 0){ + control = ctlr->gib->srcb.control; + control |= (TcpUdpCksum|NoPseudoHdrCksum); + ctlr->gib->srcb.control = control; + + control = ctlr->gib->rsrcb.control; + control |= (TcpUdpCksum|NoPseudoHdrCksum); + ctlr->gib->rsrcb.control = control; + } + else + r = -1; + } + else if(cistrcmp(cb->f[0], "rct") == 0){ + i = strtol(cb->f[1], &p, 0); + if(i < 0 || p == cb->f[1]) + r = -1; + else{ + ctlr->rct = i; + csr32w(ctlr, Rct, ctlr->rct); + } + } + else if(cistrcmp(cb->f[0], "sct") == 0){ + i = strtol(cb->f[1], &p, 0); + if(i < 0 || p == cb->f[1]) + r = -1; + else{ + ctlr->sct = i; + csr32w(ctlr, Sct, ctlr->sct); + } + } + else if(cistrcmp(cb->f[0], "st") == 0){ + i = strtol(cb->f[1], &p, 0); + if(i < 0 || p == cb->f[1]) + r = -1; + else{ + ctlr->st = i; + csr32w(ctlr, St, ctlr->st); + } + } + else if(cistrcmp(cb->f[0], "smcbd") == 0){ + i = strtol(cb->f[1], &p, 0); + if(i < 0 || p == cb->f[1]) + r = -1; + else{ + ctlr->smcbd = i; + csr32w(ctlr, SmcBD, ctlr->smcbd); + } + } + else if(cistrcmp(cb->f[0], "rmcbd") == 0){ + i = strtol(cb->f[1], &p, 0); + if(i < 0 || p == cb->f[1]) + r = -1; + else{ + ctlr->rmcbd = i; + csr32w(ctlr, RmcBD, ctlr->rmcbd); + } + } + else + r = -1; + + free(cb); + if(r == 0) + return n; + return r; +} + static void ga620transmit(Ether* edev) { @@ -494,12 +606,9 @@ ga620interrupt(Ureg*, void* arg) edev = arg; ctlr = edev->ctlr; - if(DoMhcCheck){ - if(!(csr32r(ctlr, Mhc) & Is)) - return; - } - if(DoCountTicks) - rdtsc(&tsc0); + if(!(csr32r(ctlr, Mhc) & Is)) + return; + rdtsc(&tsc0); ctlr->interrupts++; csr32w(ctlr, Hi, 1); @@ -518,10 +627,8 @@ ga620interrupt(Ureg*, void* arg) csr32w(ctlr, Hi, 0); - if(DoCountTicks){ - rdtsc(&tsc1); - ctlr->ticks += tsc1-tsc0; - } + rdtsc(&tsc1); + ctlr->ticks += tsc1-tsc0; } static void @@ -627,11 +734,11 @@ ga620init(Ether* edev) */ ctlr->sr = malign(sizeof(Sbd)*Nsr); sethost64(&ctlr->gib->srcb.addr, ctlr->sr); - if(DoHardwareCksum) + if(ctlr->hardwarecksum) flags = TcpUdpCksum|NoPseudoHdrCksum|HostRing; else flags = HostRing; - if(DoCoalUpdateOnly) + if(ctlr->coalupdateonly) flags |= CoalUpdateOnly; ctlr->gib->srcb.control = (Nsr<<16)|flags; sethost64(&ctlr->gib->scp, ctlr->sci); @@ -643,7 +750,7 @@ ga620init(Ether* edev) */ ctlr->rsr = malign(sizeof(Rbd)*Nrsr); sethost64(&ctlr->gib->rsrcb.addr, ctlr->rsr); - if(DoHardwareCksum) + if(ctlr->hardwarecksum) flags = TcpUdpCksum|NoPseudoHdrCksum; else flags = 0; @@ -695,11 +802,16 @@ ga620init(Ether* edev) * These defaults are based on the tuning hints in the Alteon * Host/NIC Software Interface Definition and example software. */ - csr32w(ctlr, Rct, 120); - csr32w(ctlr, Sct, 400); - csr32w(ctlr, St, 1000000); - csr32w(ctlr, SmcBD, 60); - csr32w(ctlr, RmcBD, 25); + ctlr->rct = 100; + csr32w(ctlr, Rct, ctlr->rct); + ctlr->sct = 0; + csr32w(ctlr, Sct, ctlr->sct); + ctlr->st = 1000000; + csr32w(ctlr, St, ctlr->st); + ctlr->smcbd = Nsr/4; + csr32w(ctlr, SmcBD, ctlr->smcbd); + ctlr->rmcbd = 6; + csr32w(ctlr, RmcBD, ctlr->rmcbd); /* * Enable DMA Assist Logic. @@ -1064,6 +1176,7 @@ ga620pnp(Ether* edev) edev->transmit = ga620transmit; edev->interrupt = ga620interrupt; edev->ifstat = ga620ifstat; + edev->ctl = ga620ctl; edev->shutdown = ga620shutdown; edev->arg = edev; diff --git a/port/qio.c b/port/qio.c index f9e720a79085ffcda32a9da8d8a5390746e14e4a..58e7fa28180dc4cc08398dc5743a134bbb41c416 100644 --- a/port/qio.c +++ b/port/qio.c @@ -460,8 +460,17 @@ qdiscard(Queue *q, int len) } } - /* if writer flow controlled, restart */ - if((q->state & Qflow) && q->len < q->limit/2){ + /* + * if writer flow controlled, restart + * + * This used to be + * q->len < q->limit/2 + * but it slows down tcp too much for certain write sizes. + * I really don't understand it completely. It may be + * due to the queue draining so fast that the transmission + * stalls waiting for the app to produce more data. - presotto + */ + if((q->state & Qflow) && q->len < q->limit){ q->state &= ~Qflow; dowakeup = 1; } else