M alphapc/devether.c => alphapc/devether.c +2 -2
@@ 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);
M bitsy/devether.c => bitsy/devether.c +2 -2
@@ 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);
M ip/devip.c => ip/devip.c +5 -3
@@ 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;
}
M ip/esp.c => ip/esp.c +1 -1
@@ 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);
}
M ip/gre.c => ip/gre.c +1 -1
@@ 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);
}
M ip/icmp.c => ip/icmp.c +1 -1
@@ 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);
}
M ip/il.c => ip/il.c +1 -1
@@ 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);
}
M ip/ipmux.c => ip/ipmux.c +1 -1
@@ 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;
M ip/loopbackmedium.c => ip/loopbackmedium.c +1 -1
@@ 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);
M ip/rudp.c => ip/rudp.c +1 -1
@@ 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);
}
M ip/tcp.c => ip/tcp.c +48 -22
@@ 534,6 534,12 @@ tcpkick(Conv *s)
}
void
+tcpqkick(void *x)
+{
+ tcpkick((Conv*)x);
+}
+
+void
tcprcvwin(Conv *s) /* Call with tcb locked */
{
int w;
@@ 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;
@@ 1438,6 1429,41 @@ limborexmit(Proto *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
*
* called with proto locked
@@ 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;
M ip/udp.c => ip/udp.c +1 -1
@@ 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);
}
M mtx/devether.c => mtx/devether.c +2 -2
@@ 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);
M mtx/ether2114x.c => mtx/ether2114x.c +1 -1
@@ 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);
}
M pc/devether.c => pc/devether.c +2 -2
@@ 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);
M pc/ether2114x.c => pc/ether2114x.c +1 -1
@@ 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);
}
M pc/ether82557.c => pc/ether82557.c +1 -1
@@ 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));
M pc/vga3dfx.c => pc/vga3dfx.c +1 -0
@@ 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;
M port/allocb.c => port/allocb.c +7 -4
@@ 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));
M port/devcons.c => port/devcons.c +1 -1
@@ 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);
M port/netif.c => port/netif.c +1 -1
@@ 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");
M port/portclock.c => port/portclock.c +4 -8
@@ 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;
M port/portdat.h => port/portdat.h +13 -0
@@ 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
M port/qio.c => port/qio.c +6 -14
@@ 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 */