From e22fb3b3737ba552e90c10d720d885adc1100ef3 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 11 Jul 2002 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2002-07-11 --- alphapc/devether.c | 4 +-- bitsy/devether.c | 4 +-- ip/devip.c | 8 ++++-- ip/esp.c | 2 +- ip/gre.c | 2 +- ip/icmp.c | 2 +- ip/il.c | 2 +- ip/ipmux.c | 2 +- ip/loopbackmedium.c | 2 +- ip/rudp.c | 2 +- ip/tcp.c | 70 +++++++++++++++++++++++++++++++-------------- ip/udp.c | 2 +- mtx/devether.c | 4 +-- mtx/ether2114x.c | 2 +- pc/devether.c | 4 +-- pc/ether2114x.c | 2 +- pc/ether82557.c | 2 +- pc/vga3dfx.c | 1 + port/allocb.c | 11 ++++--- port/devcons.c | 2 +- port/netif.c | 2 +- port/portclock.c | 12 +++----- port/portdat.h | 13 +++++++++ port/qio.c | 20 ++++--------- 24 files changed, 105 insertions(+), 72 deletions(-) diff --git a/alphapc/devether.c b/alphapc/devether.c index 410b2ce8c23ddf898ac0753b8d80f95abc4119e1..97b6ee3089b6bcd5268f3984c9926552b4c1dcf1 100644 --- a/alphapc/devether.c +++ b/alphapc/devether.c @@ -383,12 +383,12 @@ etherreset(void) if(ether->mbps == 100){ netifinit(ether, name, Ntypes, 256*1024); if(ether->oq == 0) - ether->oq = qopen(256*1024, 1, 0, 0); + ether->oq = qopen(256*1024, Qmsg, 0, 0); } else{ netifinit(ether, name, Ntypes, 65*1024); if(ether->oq == 0) - ether->oq = qopen(65*1024, 1, 0, 0); + ether->oq = qopen(65*1024, Qmsg, 0, 0); } if(ether->oq == 0) panic("etherreset %s", name); diff --git a/bitsy/devether.c b/bitsy/devether.c index 3be71ffd95a405a28ae8dc755e3e4f4a08cd6564..2a75dbdbefbec59ff6b5057f93758eacda3cf9ff 100644 --- a/bitsy/devether.c +++ b/bitsy/devether.c @@ -93,12 +93,12 @@ etherconfig(int on, char *spec, DevConf *cf) if(ether->mbps >= 100){ netifinit(ether, name, Ntypes, 256*1024); if(ether->oq == 0) - ether->oq = qopen(256*1024, 1, 0, 0); + ether->oq = qopen(256*1024, Qmsg, 0, 0); } else{ netifinit(ether, name, Ntypes, 65*1024); if(ether->oq == 0) - ether->oq = qopen(65*1024, 1, 0, 0); + ether->oq = qopen(65*1024, Qmsg, 0, 0); } if(ether->oq == 0) panic("etherreset %s", name); diff --git a/ip/devip.c b/ip/devip.c index b8395459c539e9ebc1f9ef176969a7992fce0b17..7d517cfa566892b80ab03834ad4bc6b3b027c307 100644 --- a/ip/devip.c +++ b/ip/devip.c @@ -1053,7 +1053,8 @@ ipwrite(Chan* ch, void *v, long n, vlong off) error(Eperm); qwrite(c->wq, a, n); - x->kick(c); + if(x->kick != nil) + x->kick(c); break; case Qarp: return arpwrite(f, a, n); @@ -1146,7 +1147,8 @@ ipbwrite(Chan* ch, Block* bp, ulong offset) bp = concatblock(bp); n = BLEN(bp); qbwrite(c->wq, bp); - x->kick(c); + if(x->kick != nil) + x->kick(c); return n; default: return devbwrite(ch, bp, offset); @@ -1241,7 +1243,7 @@ retry: } *pp = c; p->ac++; - c->eq = qopen(1024, 1, 0, 0); + c->eq = qopen(1024, Qmsg, 0, 0); (*p->create)(c); break; } diff --git a/ip/esp.c b/ip/esp.c index ffd14054d8562fd93d467ca98e823b1bced77979..ecc83605540afe4afdc5e477f6769154b5f76511 100644 --- a/ip/esp.c +++ b/ip/esp.c @@ -198,7 +198,7 @@ espstate(Conv *c, char *state, int n) static void espcreate(Conv *c) { - c->rq = qopen(64*1024, 1, 0, 0); + c->rq = qopen(64*1024, Qmsg, 0, 0); c->wq = qopen(64*1024, 0, 0, 0); } diff --git a/ip/gre.c b/ip/gre.c index 1226f27a14581ae89197d70a85d764f8b3b16d9a..d53a0258b8cda10179c0a21c502b0854e0c4fec3 100644 --- a/ip/gre.c +++ b/ip/gre.c @@ -94,7 +94,7 @@ grestate(Conv *c, char *state, int n) static void grecreate(Conv *c) { - c->rq = qopen(64*1024, 1, 0, c); + c->rq = qopen(64*1024, Qmsg, 0, c); c->wq = qopen(64*1024, 0, 0, 0); } diff --git a/ip/icmp.c b/ip/icmp.c index 2dcc05347bd4bbd849da0eae8a4d80c5d353cdad..64c15c39a30736a1276137d035bfc2bfa9e2c1b1 100644 --- a/ip/icmp.c +++ b/ip/icmp.c @@ -127,7 +127,7 @@ icmpstate(Conv *c, char *state, int n) extern void icmpcreate(Conv *c) { - c->rq = qopen(64*1024, 1, 0, c); + c->rq = qopen(64*1024, Qmsg, 0, c); c->wq = qopen(64*1024, 0, 0, 0); } diff --git a/ip/il.c b/ip/il.c index 2437f13a3bad242c00c18953f9c448c635aea3d3..37f131d39e1629d598a5796a012b6fb89f0687f6 100644 --- a/ip/il.c +++ b/ip/il.c @@ -416,7 +416,7 @@ ilkick(Conv *c) static void ilcreate(Conv *c) { - c->rq = qopen(64*1024, 0, 0, c); + c->rq = qopen(64*1024, Qmsg, 0, c); c->wq = qopen(64*1024, 0, 0, 0); } diff --git a/ip/ipmux.c b/ip/ipmux.c index 29ba08ce90c415d6bf77d6f24747a167ae83c190..fdd03e3cc2496a8c2e870209c75f38654dba6d4b 100644 --- a/ip/ipmux.c +++ b/ip/ipmux.c @@ -612,7 +612,7 @@ ipmuxcreate(Conv *c) { Ipmuxrock *r; - c->rq = qopen(64*1024, 1, 0, c); + c->rq = qopen(64*1024, Qmsg, 0, c); c->wq = qopen(64*1024, 0, 0, 0); r = (Ipmuxrock*)(c->ptcl); r->chain = nil; diff --git a/ip/loopbackmedium.c b/ip/loopbackmedium.c index b1b4bb17a8e65b1203fb0021f02983c636e5409f..678189b98ad89b860c94394ba69a815c00825d4c 100644 --- a/ip/loopbackmedium.c +++ b/ip/loopbackmedium.c @@ -29,7 +29,7 @@ loopbackbind(Ipifc *ifc, int, char**) lb = smalloc(sizeof(*lb)); lb->f = ifc->conv->p->f; - lb->q = qopen(128*1024, 1, nil, nil); + lb->q = qopen(128*1024, Qmsg, nil, nil); ifc->arg = lb; kproc("loopbackread", loopbackread, ifc); diff --git a/ip/rudp.c b/ip/rudp.c index c9ad2ef7dd580705d46e9d43ca2d35f6adadeced..89a6d68dff4500847e29a03971235d6b0408e79d 100644 --- a/ip/rudp.c +++ b/ip/rudp.c @@ -263,7 +263,7 @@ rudpannounce(Conv *c, char** argv, int argc) static void rudpcreate(Conv *c) { - c->rq = qopen(64*1024, 1, 0, 0); + c->rq = qopen(64*1024, Qmsg, 0, 0); c->wq = qopen(64*1024, 0, 0, 0); } diff --git a/ip/tcp.c b/ip/tcp.c index 7895d75517c8623883de2f1732f5d2b93047edab..cc7ee1c62e8cd4a2f22fa8a6789753b05bfede8e 100644 --- a/ip/tcp.c +++ b/ip/tcp.c @@ -533,6 +533,12 @@ tcpkick(Conv *s) poperror(); } +void +tcpqkick(void *x) +{ + tcpkick((Conv*)x); +} + void tcprcvwin(Conv *s) /* Call with tcb locked */ { @@ -574,8 +580,8 @@ tcpacktimer(void *v) static void tcpcreate(Conv *c) { - c->rq = qopen(QMAX, -1, tcpacktimer, c); - c->wq = qopen(2*QMAX, 0, 0, 0); + c->rq = qopen(QMAX, Qcoalesce, tcpacktimer, c); + c->wq = qopen(2*QMAX, Qkick, tcpqkick, c); } static void @@ -1312,22 +1318,7 @@ sndsynack(Proto *tcp, Limbo *lp) return 0; } -/* - * hash an address, walk the permutation - */ -static int -limbohash(uchar *perm, uchar *addr) -{ - int i; - uchar x; - - x = 0; - for(i = 0; i < IPaddrlen; i++) - x = perm[(addr[i]+x) & 0xff]; - return x; -} - -#define hashipa(a) ( ( (a)[IPaddrlen-2] + (a)[IPaddrlen-1] )&LHTMASK ) +#define hashipa(a, p) ( ( (a)[IPaddrlen-2] + (a)[IPaddrlen-1] + p )&LHTMASK ) /* * put a call into limbo and respond with a SYN ACK @@ -1342,7 +1333,7 @@ limbo(Conv *s, uchar *source, uchar *dest, Tcp *seg, int version) int h; tpriv = s->p->priv; - h = hashipa(source); + h = hashipa(source, seg->source); for(l = &tpriv->lht[h]; *l != nil; l = &lp->next){ lp = *l; @@ -1437,6 +1428,41 @@ limborexmit(Proto *tcp) qunlock(tcp); } +/* + * lookup call in limbo. if found, throw it out. + * + * called with proto locked + */ +static void +limborst(Conv *s, Tcp *segp, uchar *src, uchar *dst, uchar version) +{ + Limbo *lp, **l; + int h; + Tcppriv *tpriv; + + tpriv = s->p->priv; + + /* find a call in limbo */ + h = hashipa(src, segp->source); + for(l = &tpriv->lht[h]; *l != nil; l = &lp->next){ + lp = *l; + if(lp->lport != segp->dest || lp->rport != segp->source || lp->version != version) + continue; + if(ipcmp(lp->laddr, dst) != 0) + continue; + if(ipcmp(lp->raddr, src) != 0) + continue; + + /* RST can only follow the SYN */ + if(segp->seq == lp->irs+1){ + tpriv->nlimbo--; + *l = lp->next; + free(lp); + } + break; + } +} + /* * lookup call in limbo. if found, create a new conversation * @@ -1461,7 +1487,7 @@ tcpincoming(Conv *s, Tcp *segp, uchar *src, uchar *dst, uchar version) /* find a call in limbo */ lp = nil; - h = hashipa(src); + h = hashipa(src, segp->source); for(l = &tpriv->lht[h]; *l != nil; l = &lp->next){ lp = *l; if(lp->lport != segp->dest || lp->rport != segp->source || lp->version != version) @@ -1800,7 +1826,6 @@ tcpiput(Proto *tcp, Ipifc*, Block *bp) ptclcsum(bp, TCP4_IPLEN, length-TCP4_IPLEN)) { tpriv->stats[CsumErrs]++; tpriv->stats[InErrs]++; -print("cksum is %ux\n", ptclcsum(bp, TCP4_IPLEN, length-TCP4_IPLEN)); netlog(f, Logtcp, "bad tcp proto cksum\n"); freeblist(bp); return; @@ -1884,6 +1909,7 @@ reset: tcb = (Tcpctl*)s->ptcl; if(tcb->state == Listen){ if(seg.flags & RST){ + limborst(s, &seg, source, dest, version); qunlock(tcp); freeblist(bp); return; @@ -2952,7 +2978,7 @@ tcpinit(Fs *fs) tcp = smalloc(sizeof(Proto)); tpriv = tcp->priv = smalloc(sizeof(Tcppriv)); tcp->name = "tcp"; - tcp->kick = tcpkick; + tcp->kick = nil; tcp->connect = tcpconnect; tcp->announce = tcpannounce; tcp->ctl = tcpctl; diff --git a/ip/udp.c b/ip/udp.c index ce89e32790cf6f47a7a877e12df8bfc57c7b6095..7fe9f654854bae438a032c1a52e239112bc84b98 100644 --- a/ip/udp.c +++ b/ip/udp.c @@ -146,7 +146,7 @@ udpannounce(Conv *c, char** argv, int argc) static void udpcreate(Conv *c) { - c->rq = qopen(128*1024, 1, 0, 0); + c->rq = qopen(128*1024, Qmsg, 0, 0); c->wq = qopen(128*1024, 0, 0, 0); } diff --git a/mtx/devether.c b/mtx/devether.c index 27f2c403f322e2c2cda77e2fbdb5c002799e05e3..962c18f6d71c7ea8b4e038c40fe33946639ab4fc 100644 --- a/mtx/devether.c +++ b/mtx/devether.c @@ -403,12 +403,12 @@ etherreset(void) if(ether->mbps >= 100){ netifinit(ether, name, Ntypes, 256*1024); if(ether->oq == 0) - ether->oq = qopen(256*1024, 1, 0, 0); + ether->oq = qopen(256*1024, Qmsg, 0, 0); } else{ netifinit(ether, name, Ntypes, 65*1024); if(ether->oq == 0) - ether->oq = qopen(65*1024, 1, 0, 0); + ether->oq = qopen(65*1024, Qmsg, 0, 0); } if(ether->oq == 0) panic("etherreset %s", name); diff --git a/mtx/ether2114x.c b/mtx/ether2114x.c index 1fd6e25f41d32fe18a299ef034061085c5f7bb5a..b5dbfff068db4c5f4231b99b6b0b7f3c9a3411a5 100644 --- a/mtx/ether2114x.c +++ b/mtx/ether2114x.c @@ -619,7 +619,7 @@ ctlrinit(Ether* ether) bp->wp += sizeof(bi)*16; ctlr->setupbp = bp; - ether->oq = qopen(256*1024, 1, 0, 0); + ether->oq = qopen(256*1024, Qmsg, 0, 0); transmit(ether); } diff --git a/pc/devether.c b/pc/devether.c index 6b2a89cd29fbee135a4f8dc4a00f790e75f4a963..2735ef3e2e84371bec2181bedc1cb3d5ce768708 100644 --- a/pc/devether.c +++ b/pc/devether.c @@ -416,12 +416,12 @@ etherprobe(int cardno, int ctlrno) if(ether->mbps >= 100){ netifinit(ether, name, Ntypes, 512*1024); if(ether->oq == 0) - ether->oq = qopen(256*1024, 1, 0, 0); + ether->oq = qopen(256*1024, Qmsg, 0, 0); } else{ netifinit(ether, name, Ntypes, 128*1024); if(ether->oq == 0) - ether->oq = qopen(128*1024, 1, 0, 0); + ether->oq = qopen(128*1024, Qmsg, 0, 0); } if(ether->oq == 0) panic("etherreset %s", name); diff --git a/pc/ether2114x.c b/pc/ether2114x.c index 06c835b2bfc2c1742263e53866fa472dc86a48f0..bc2d7aa0a5b783b2c14b1ef258203978698cae91 100644 --- a/pc/ether2114x.c +++ b/pc/ether2114x.c @@ -619,7 +619,7 @@ ctlrinit(Ether* ether) bp->wp += sizeof(bi)*16; ctlr->setupbp = bp; - ether->oq = qopen(256*1024, 1, 0, 0); + ether->oq = qopen(256*1024, Qmsg, 0, 0); transmit(ether); } diff --git a/pc/ether82557.c b/pc/ether82557.c index e338bca65ac5639070056c59dfd3570951edda61..985d6e0ebea46aeed99b9819ebc9cc5d8ee37ec3 100644 --- a/pc/ether82557.c +++ b/pc/ether82557.c @@ -1229,7 +1229,7 @@ reset(Ether* ether) * Load the chip configuration and start it off. */ if(ether->oq == 0) - ether->oq = qopen(256*1024, 1, 0, 0); + ether->oq = qopen(256*1024, Qmsg, 0, 0); configure(ether, 0); command(ctlr, CUstart, PADDR(&ctlr->cbr->status)); diff --git a/pc/vga3dfx.c b/pc/vga3dfx.c index d35159dfb8c47aa234d560762cb1c1ea7d13378a..cce271852f61229b51089ed90bfc791a80a610ec 100644 --- a/pc/vga3dfx.c +++ b/pc/vga3dfx.c @@ -43,6 +43,7 @@ tdfxlinear(VGAscr* scr, int* size, int* align) switch(p->did){ case 0x0003: /* Banshee */ case 0x0005: /* Avenger (a.k.a. Voodoo3) */ + case 0x0009: /* Voodoo5 */ aperture = p->mem[1].bar & ~0x0F; *size = p->mem[1].size; break; diff --git a/port/allocb.c b/port/allocb.c index cda4be662d65b08582e4087fa0625171624b508e..9e891e1893f209462047ef2bbaed2a0b4bff9a35 100644 --- a/port/allocb.c +++ b/port/allocb.c @@ -76,16 +76,19 @@ Block* iallocb(int size) { Block *b; + static int m1, m2; if(ialloc.bytes > conf.ialloc){ - print("iallocb: limited %lud/%lud\n", - ialloc.bytes, conf.ialloc); + if((m1++%10000)==0) + print("iallocb: limited %lud/%lud\n", + ialloc.bytes, conf.ialloc); return 0; } if((b = _allocb(size)) == nil){ - print("iallocb: no memory %lud/%lud\n", - ialloc.bytes, conf.ialloc); + if((m2++%10000)==0) + print("iallocb: no memory %lud/%lud\n", + ialloc.bytes, conf.ialloc); return nil; } setmalloctag(b, getcallerpc(&size)); diff --git a/port/devcons.c b/port/devcons.c index c16b6bf38ecd8c88916a4b21c7cea0e7ef62818d..4abbde0a8985a833c70e7fab201d838b3a61da1e 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -603,7 +603,7 @@ consopen(Chan *c, int omode) error(Einuse); } if(kprintoq == nil){ - kprintoq = qopen(8*1024, -1, 0, 0); + kprintoq = qopen(8*1024, Qcoalesce, 0, 0); if(kprintoq == nil){ c->flag &= ~COPEN; error(Enomem); diff --git a/port/netif.c b/port/netif.c index 759cb5f7ae1190222300de7068c75be8078ea8aa..b9b757059e651f30a0a3985c34f3a6cd3dbfde78 100644 --- a/port/netif.c +++ b/port/netif.c @@ -478,7 +478,7 @@ openfile(Netif *nif, int id) f = malloc(sizeof(Netfile)); if(f == 0) exhausted("memory"); - f->in = qopen(nif->limit, 1, 0, 0); + f->in = qopen(nif->limit, Qmsg, 0, 0); if(f->in == nil){ free(f); exhausted("memory"); diff --git a/port/portclock.c b/port/portclock.c index 28c804c277f8a0a9c1a1d7c6ab6169e4c53acd5b..cb2250fc948290960433dcb5d9a5a40b3d17704d 100644 --- a/port/portclock.c +++ b/port/portclock.c @@ -141,13 +141,10 @@ timerintr(Ureg *u, uvlong) Timers *tt; uvlong when, now; int callhzclock; - static int intimer; + ulong pc; + static int sofar; - if(intimer){ - print("!"); - return; - } - intimer = 1; + pc = m->splpc; /* remember last splhi pc for kernel profiling */ intrcount[m->machno]++; callhzclock = 0; @@ -159,9 +156,9 @@ timerintr(Ureg *u, uvlong) if(when > now){ iunlock(tt); timerset(when); + m->splpc = pc; /* for kernel profiling */ if(callhzclock) hzclock(u); - intimer = 0; return; } tt->head = t->next; @@ -179,7 +176,6 @@ timerintr(Ureg *u, uvlong) } } iunlock(tt); - intimer = 0; } uvlong hzperiod; diff --git a/port/portdat.h b/port/portdat.h index 8da75534ea090205dc409c778f9d413e3b3dd288..211a110c4cb546513d3599cab0a8426309de4516 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -860,6 +860,19 @@ struct Edfinterface { void (*edfdeadline)(Proc *p); }; +/* queue state bits, Qmsg, Qcoalesce, and Qkick can be set in qopen */ +enum +{ + /* Queue.state */ + Qstarve = (1<<0), /* consumer starved */ + Qmsg = (1<<1), /* message stream */ + Qclosed = (1<<2), /* queue has been closed/hungup */ + Qflow = (1<<3), /* producer flow controlled */ + Qcoalesce = (1<<4), /* coallesce packets on read */ + Qkick = (1<<5), /* always call the kick routine after qwrite */ +}; + + extern Edfinterface *edf; #define DEVDOTDOT -1 diff --git a/port/qio.c b/port/qio.c index a513e0711c2fb9e4e6eed6a81f57ed2199e64f95..f1b5f4729bab4c5cf979faf5dc323d9d5474f693 100644 --- a/port/qio.c +++ b/port/qio.c @@ -50,13 +50,6 @@ struct Queue enum { - /* Queue.state */ - Qstarve = (1<<0), /* consumer starved */ - Qmsg = (1<<1), /* message stream */ - Qclosed = (1<<2), - Qflow = (1<<3), - Qcoalesce = (1<<4), /* coallesce packets on read */ - Maxatomic = 64*1024, }; @@ -798,11 +791,7 @@ qopen(int limit, int msg, void (*kick)(void*), void *arg) q->limit = q->inilim = limit; q->kick = kick; q->arg = arg; - q->state = 0; - if(msg > 0) - q->state |= Qmsg; - else if(msg < 0) - q->state |= Qcoalesce; + q->state = msg; q->state |= Qstarve; q->eof = 0; @@ -1192,9 +1181,12 @@ qbwrite(Queue *q, Block *b) } iunlock(q); + /* get output going again */ + if(q->kick && (dowakeup || (q->state&Qkick))) + q->kick(q->arg); + + /* wakeup anyone consuming at the other end */ if(dowakeup){ - if(q->kick) - q->kick(q->arg); p = wakeup(&q->rr); /* if we just wokeup a higher priority process, let it run */