M alphapc/ether2114x.c => alphapc/ether2114x.c +6 -2
@@ 579,7 579,9 @@ ctlrinit(Ether* ether)
*/
ctlr->rdr = malloc(ctlr->nrdr*sizeof(Des));
for(des = ctlr->rdr; des < &ctlr->rdr[ctlr->nrdr]; des++){
- des->bp = allocb(Rbsz);
+ des->bp = iallocb(Rbsz);
+ if(des->bp == nil)
+ panic("can't allocate ethernet receive ring");
des->status = Own;
des->control = Rbsz;
des->addr = PCIWADDR(des->bp->rp);
@@ 610,7 612,9 @@ ctlrinit(Ether* ether)
bi[i*4+2] = ether->ea[i*2+1];
bi[i*4+3] = ether->ea[i*2];
}
- bp = allocb(Eaddrlen*2*16);
+ bp = iallocb(Eaddrlen*2*16);
+ if(bp == nil)
+ panic("can't allocate ethernet setup buffer");
memset(bp->rp, 0xFF, sizeof(bi));
for(i = sizeof(bi); i < sizeof(bi)*16; i += sizeof(bi))
memmove(bp->rp+i, bi, sizeof(bi));
M bitsy/devuda1341.c => bitsy/devuda1341.c +1 -1
@@ 902,7 902,7 @@ audioopen(Chan *c, int mode)
}
mxvolume();
qunlock(&audio);
- if (audio.amode == Aread)
+ if (audio.amode & Aread)
sendaudio(&audio.o);
if (debug) print("open done\n");
M ip/tcp.c => ip/tcp.c +3 -1
@@ 559,8 559,10 @@ tcpackproc(void *a)
for(t = timeo; t != nil; t = t->readynext) {
if(loop++ > 10000)
panic("tcpackproc2");
- if(t->state == TimerDONE && t->func != nil)
+ if(t->state == TimerDONE && t->func != nil && !waserror()){
(*t->func)(t->arg);
+ poperror();
+ }
}
}
}
M mpc/devether.c => mpc/devether.c +1 -1
@@ 243,7 243,7 @@ static long
etherwrite(Chan* chan, void* buf, long n, vlong)
{
Ether *ether;
- Block *bp;
+ Block *volatile bp;
ether = etherxx[chan->dev];
if(NETTYPE(chan->qid.path) != Ndataqid)
M mpc/etherelnk3.c => mpc/etherelnk3.c +14 -5
@@ 465,7 465,9 @@ init905(Ctlr* ctlr)
for(pd = &ctlr->upr[ctlr->nup-1]; pd >= ctlr->upr; pd--){
pd->np = PADDR(&prev->np);
pd->control = 0;
- bp = allocb(sizeof(Etherpkt));
+ bp = iallocb(sizeof(Etherpkt));
+ if(bp == nil)
+ panic("can't allocate ethernet receive ring");
pd->addr = PADDR(bp->rp);
pd->len = updnLastFrag|sizeof(Etherpkt);
@@ 1194,7 1196,9 @@ tcmadapter(int port, int irq, int tbdf)
Block *bp;
Adapter *ap;
- bp = allocb(sizeof(Adapter));
+ bp = iallocb(sizeof(Adapter));
+ if(bp == nil)
+ return;
ap = (Adapter*)bp->rp;
ap->port = port;
ap->irq = irq;
@@ 1809,13 1813,18 @@ XCVRDEBUG("\n");
ctlr->ndn = Ndn;
init905(ctlr);
}
- else
- ctlr->rbp = rbpalloc(allocb);
+ else{
+ ctlr->rbp = rbpalloc(iallocb);
+ if(ctlr->rbp == nil)
+ panic("can't reset ethernet: out of memory");
+ }
outl(port+TxFreeThresh, HOWMANY(ETHERMAXTU, 256));
break;
default:
- ctlr->rbp = rbpalloc(allocb);
+ ctlr->rbp = rbpalloc(iallocb);
+ if(ctlr->rbp == nil)
+ panic("can't reset ethernet: out of memory");
break;
}
M mpc/etherwavelan.c => mpc/etherwavelan.c +3 -1
@@ 867,7 867,9 @@ reset(Ether* ether)
print("#l%dWaveLAN: slot %d, port 0x%ulX irq %ld type %s\n", ether->ctlrno, slot, ether->port, ether->irq, ether->type);
/* create a receive buffer */
- ctlr->rbp = rbpalloc(allocb);
+ ctlr->rbp = rbpalloc(iallocb);
+ if(ctlr->rbp == nil)
+ panic("can't reset ethernet: out of memory");
/* map a piece of memory (Attribute memory) first */
m = pcmmap(slot, 0, 0x5000, 1);
M pc/devether.c => pc/devether.c +6 -1
@@ 248,7 248,7 @@ static long
etherwrite(Chan* chan, void* buf, long n, vlong)
{
Ether *ether;
- Block *bp;
+ Block *volatile bp;
int nn;
ether = etherxx[chan->dev];
@@ 269,8 269,13 @@ etherwrite(Chan* chan, void* buf, long n, vlong)
error(Etoosmall);
bp = allocb(n);
+ if(waserror()){
+ freeb(bp);
+ nexterror();
+ }
memmove(bp->rp, buf, n);
memmove(bp->rp+Eaddrlen, ether->ea, Eaddrlen);
+ poperror();
bp->wp += n;
return etheroq(ether, bp);
M pc/devusb.c => pc/devusb.c +1 -16
@@ 718,8 718,8 @@ qrcv(Endpt *e)
QH *qh;
int vf;
- t = alloctde(e, TokIN, e->maxpkt);
b = allocb(e->maxpkt);
+ t = alloctde(e, TokIN, e->maxpkt);
t->bp = b;
t->buffer = PADDR(b->wp);
ub = &ubus;
@@ 734,21 734,6 @@ qrcv(Endpt *e)
return qh;
}
-static Block *
-usbreq(int type, int req, int value, int offset, int count)
-{
- Block *b;
-
- b = allocb(8);
- b->wp[0] = type;
- b->wp[1] = req;
- PUT2(b->wp+2, value);
- PUT2(b->wp+4, offset);
- PUT2(b->wp+6, count);
- b->wp += 8;
- return b;
-}
-
/*
* return smallest power of 2 >= n
*/
M pc/ether2114x.c => pc/ether2114x.c +6 -2
@@ 576,7 576,9 @@ ctlrinit(Ether* ether)
*/
ctlr->rdr = malloc(ctlr->nrdr*sizeof(Des));
for(des = ctlr->rdr; des < &ctlr->rdr[ctlr->nrdr]; des++){
- des->bp = allocb(Rbsz);
+ des->bp = iallocb(Rbsz);
+ if(des->bp == nil)
+ panic("can't allocate ethernet receive ring");
des->status = Own;
des->control = Rbsz;
des->addr = PADDR(des->bp->rp);
@@ 607,7 609,9 @@ ctlrinit(Ether* ether)
bi[i*4+2] = ether->ea[i*2+1];
bi[i*4+3] = ether->ea[i*2];
}
- bp = allocb(Eaddrlen*2*16);
+ bp = iallocb(Eaddrlen*2*16);
+ if(bp == nil)
+ panic("can't allocate ethernet setup buffer");
memset(bp->rp, 0xFF, sizeof(bi));
for(i = sizeof(bi); i < sizeof(bi)*16; i += sizeof(bi))
memmove(bp->rp+i, bi, sizeof(bi));
M pc/ether79c970.c => pc/ether79c970.c +3 -1
@@ 430,7 430,9 @@ amd79c970adapter(Block** bpp, int port, int irq, int tbdf)
Block *bp;
Adapter *ap;
- bp = allocb(sizeof(Adapter));
+ bp = iallocb(sizeof(Adapter));
+ if(bp == nil)
+ return;
ap = (Adapter*)bp->rp;
ap->port = port;
ap->irq = irq;
M pc/etherelnk3.c => pc/etherelnk3.c +14 -5
@@ 467,7 467,9 @@ init905(Ctlr* ctlr)
for(pd = &ctlr->upr[ctlr->nup-1]; pd >= ctlr->upr; pd--){
pd->np = PADDR(&prev->np);
pd->control = 0;
- bp = allocb(sizeof(Etherpkt));
+ bp = iallocb(sizeof(Etherpkt));
+ if(bp == nil)
+ panic("can't allocate ethernet receive ring");
pd->addr = PADDR(bp->rp);
pd->len = updnLastFrag|sizeof(Etherpkt);
@@ 1227,7 1229,9 @@ tcmadapter(int port, int irq, int tbdf)
Block *bp;
Adapter *ap;
- bp = allocb(sizeof(Adapter));
+ bp = iallocb(sizeof(Adapter));
+ if(bp == nil)
+ return;
ap = (Adapter*)bp->rp;
ap->port = port;
ap->irq = irq;
@@ 2013,13 2017,18 @@ etherelnk3reset(Ether* ether)
ctlr->ndn = Ndn;
init905(ctlr);
}
- else
- ctlr->rbp = rbpalloc(allocb);
+ else {
+ ctlr->rbp = rbpalloc(iallocb);
+ if(ctlr->rbp == nil)
+ panic("can't reset ethernet: out of memory");
+ }
outl(port+TxFreeThresh, HOWMANY(ETHERMAXTU, 256));
break;
default:
- ctlr->rbp = rbpalloc(allocb);
+ ctlr->rbp = rbpalloc(iallocb);
+ if(ctlr->rbp == nil)
+ panic("can't reset ethernet: out of memory");
break;
}
M pc/etherwavelan.c => pc/etherwavelan.c +1 -1
@@ 29,7 29,7 @@
#define DEBUG if(1)print
-#define SEEKEYS 1
+#define SEEKEYS 0
typedef struct Ctlr Ctlr;
typedef struct Wltv Wltv;
M port/allocb.c => port/allocb.c +29 -40
@@ 18,21 18,19 @@ struct
ulong bytes;
} ialloc;
-/*
- * allocate blocks, round the data base up to a multiple of BLOCKALIGN.
- */
-Block*
-allocb(int size)
+static Block*
+_allocb(int size)
{
Block *b;
ulong addr;
- int n;
- n = sizeof(Block) + size;
- b = malloc(n+Hdrspc);
- if(b == 0)
- exhausted("Blocks");
- memset(b, 0, sizeof(Block));
+ if((b = mallocz(sizeof(Block)+size+Hdrspc, 0)) == nil)
+ return nil;
+
+ b->next = nil;
+ b->list = nil;
+ b->free = 0;
+ b->flag = 0;
/* align start of data portion by rounding up */
addr = (ulong)b;
@@ 48,22 46,34 @@ allocb(int size)
/* leave sluff at beginning for added headers */
b->rp = b->lim - ROUND(size, BLOCKALIGN);
if(b->rp < b->base)
- panic("allocb");
+ panic("_allocb");
b->wp = b->rp;
+
+ return b;
+}
+
+Block*
+allocb(int size)
+{
+ Block *b;
+
+ /*
+ * Check in a process and wait until successful.
+ * Can still error out of here, though.
+ */
+ if(up == nil)
+ panic("allocb without up: %uX\n", getcallerpc(&size));
+ if((b = _allocb(size)) == nil)
+ panic("allocb: no memory\n");
setmalloctag(b, getcallerpc(&size));
return b;
}
-/*
- * interrupt time allocation
- */
Block*
iallocb(int size)
{
Block *b;
- ulong addr;
- int n;
if(ialloc.bytes > conf.ialloc){
print("iallocb: limited %lud/%lud\n",
@@ 71,38 81,17 @@ iallocb(int size)
return 0;
}
- n = sizeof(Block) + size;
- b = malloc(n+Hdrspc);
- if(b == 0){
+ if((b = _allocb(size)) == nil){
print("iallocb: no memory %lud/%lud\n",
ialloc.bytes, conf.ialloc);
return nil;
}
- memset(b, 0, sizeof(Block));
-
- /* align start of data portion by rounding up */
- addr = (ulong)b;
- addr = ROUND(addr + sizeof(Block), BLOCKALIGN);
- b->base = (uchar*)addr;
-
- /* align end of data portion by rounding down */
- b->lim = ((uchar*)b) + msize(b);
- addr = (ulong)(b->lim);
- addr = addr & ~(BLOCKALIGN-1);
- b->lim = (uchar*)addr;
-
- /* leave sluff at beginning for added headers */
- b->rp = b->lim - ROUND(size, BLOCKALIGN);
- if(b->rp < b->base)
- panic("allocb");
- b->wp = b->rp;
-
+ setmalloctag(b, getcallerpc(&size));
b->flag = BINTR;
ilock(&ialloc);
ialloc.bytes += b->lim - b->base;
iunlock(&ialloc);
- setmalloctag(b, getcallerpc(&size));
return b;
}
M port/chan.c => port/chan.c +1 -1
@@ 195,7 195,7 @@ cclose(Chan *c)
return;
if(waserror()){
- print("cclose error: type %C; error %s\n", devtab[c->type]->dc, up!=nil? up->error : "no user"); //BUG
+// print("cclose error: type %C; error %s\n", devtab[c->type]->dc, up!=nil? up->error : "no user");
chanfree(c);
return;
}
M port/devloopback.c => port/devloopback.c +6 -1
@@ 559,18 559,23 @@ loopbackwrite(Chan *c, void *va, long n, vlong off)
}
static long
-loopoput(Loop *lb, Link *link, Block *bp)
+loopoput(Loop *lb, Link *link, Block *volatile bp)
{
long n;
n = BLEN(bp);
/* make it a single block with space for the loopback timing header */
+ if(waserror()){
+ freeb(bp);
+ nexterror();
+ }
bp = padblock(bp, Tmsize);
if(bp->next)
bp = concatblock(bp);
if(BLEN(bp) < lb->minmtu)
bp = adjustblock(bp, lb->minmtu);
+ poperror();
ptime(bp->rp, fastticks(nil));
link->packets++;
M port/devssl.c => port/devssl.c +8 -6
@@ 502,11 502,11 @@ qremove(Block **l, int n, int discard)
}
/*
- * We can't let Eintr's lose data since the program
- * doing the read may be able to handle it. The only
- * places Eintr is possible is during the read's in consume.
- * Therefore, we make sure we can always put back the bytes
- * consumed before the last ensure.
+ * We can't let Eintrs lose data, since doing so will get
+ * us out of sync with the sender and break the reliablity
+ * of the channel. Eintr only happens during the reads in
+ * consume. Therefore we put back any bytes consumed before
+ * the last call to ensure.
*/
static Block*
sslbread(Chan *c, long n, ulong)
@@ 525,8 525,10 @@ sslbread(Chan *c, long n, ulong)
nconsumed = 0;
if(waserror()){
- if(strcmp(up->error, Eintr) == 0)
+ if(strcmp(up->error, Eintr) == 0 && !waserror()){
regurgitate(s.s, consumed, nconsumed);
+ poperror();
+ }
qunlock(&s.s->in.q);
nexterror();
}
M port/devtls.c => port/devtls.c +45 -64
@@ 671,51 671,32 @@ regurgitate(TlsRec *s, uchar *p, int n)
}
/*
- * remove at most n bytes from the queue, if discard is set
+ * remove at most n bytes from the queue in a single block, if discard is set
* dump the remainder
*/
static Block*
-qremove(Block **l, int n, int discard)
+qgrab(Block **l, int n)
{
- Block *nb, *b, *first;
+ Block *bb, *b;
int i;
- first = *l;
- for(b = first; b; b = b->next){
- i = BLEN(b);
- if(i == n){
- if(discard){
- freeblist(b->next);
- *l = 0;
- } else
- *l = b->next;
- b->next = 0;
- return first;
- } else if(i > n){
- i -= n;
- if(discard){
- freeblist(b->next);
- b->wp -= i;
- *l = 0;
- } else {
- nb = allocb(i);
- memmove(nb->wp, b->rp+n, i);
- nb->wp += i;
- b->wp -= i;
- nb->next = b->next;
- *l = nb;
- }
- b->next = 0;
- if(BLEN(b) < 0)
- panic("qremove");
- return first;
- } else
- n -= i;
- if(BLEN(b) < 0)
- panic("qremove");
+ b = *l;
+ if(BLEN(b) == n){
+ *l = b->next;
+ b->next = nil;
+ return b;
}
- *l = 0;
- return first;
+
+ i = 0;
+ for(bb = b; bb != nil && i < n; bb = bb->next)
+ i += BLEN(bb);
+ if(i > n)
+ i = n;
+
+ bb = allocb(i);
+ consume(l, bb->wp, i);
+ bb->wp += i;
+ return bb;
}
static void
@@ 731,8 712,13 @@ tlsclosed(TlsRec *tr, int new)
}
/*
- * read and process one tls record layer message
- * must be called with tr->in.io held
+ * read and process one tls record layer message
+ * must be called with tr->in.io held
+ * We can't let Eintrs lose data, since doing so will get
+ * us out of sync with the sender and break the reliablity
+ * of the channel. Eintr only happens during the reads in
+ * consume. Therefore we put back any bytes consumed before
+ * the last call to ensure.
*/
static void
tlsrecread(TlsRec *tr)
@@ 745,9 731,10 @@ tlsrecread(TlsRec *tr)
nconsumed = 0;
if(waserror()){
- if(strcmp(up->error, Eintr) == 0)
+ if(strcmp(up->error, Eintr) == 0 && !waserror()){
regurgitate(tr, header, nconsumed);
- else
+ poperror();
+ }else
tlsError(tr, "channel error");
nexterror();
}
@@ 778,7 765,7 @@ tlsrecread(TlsRec *tr)
tlsError(tr, "channel error");
nexterror();
}
- b = qremove(&tr->unprocessed, len, 0);
+ b = qgrab(&tr->unprocessed, len);
in = &tr->in;
if(waserror()){
@@ 786,7 773,6 @@ tlsrecread(TlsRec *tr)
nexterror();
}
qlock(&in->seclock);
- b = pullupblock(b, len);
p = b->rp;
if(in->sec != nil) {
len = (*in->sec->dec)(in->sec, p, len);
@@ 874,8 860,10 @@ tlsrecread(TlsRec *tr)
b = nil;
poperror();
dechandq(tr);
- }else if(tr->verset && tr->version != SSL3Version)
+ }else if(tr->verset && tr->version != SSL3Version && !waserror()){
sendAlert(tr, ENoRenegotiation);
+ poperror();
+ }
break;
case RApplication:
if(!tr->opened)
@@ 938,7 926,7 @@ rcvError(TlsRec *tr, int err, char *fmt, ...)
static void
alertHand(TlsRec *tr, char *msg)
{
- Block *volatile b;
+ Block *b;
int n;
lock(&tr->hqlock);
@@ 950,10 938,7 @@ alertHand(TlsRec *tr, char *msg)
unlock(&tr->hqlock);
n = strlen(msg);
- b = nil;
if(waserror()){
- if(b != nil)
- freeb(b);
dechandq(tr);
nexterror();
}
@@ 995,13 980,6 @@ checkstate(TlsRec *tr, int ishand, int ok)
error("tls improperly configured");
}
-/*
- * We can't let Eintr's lose data since the program
- * doing the read may be able to handle it. The only
- * places Eintr is possible is during the read's in consume.
- * Therefore, we make sure we can always put back the bytes
- * consumed before the last ensure.
- */
static Block*
tlsbread(Chan *c, long n, ulong offset)
{
@@ 1031,7 1009,7 @@ tlsbread(Chan *c, long n, ulong offset)
tlsrecread(tr);
/* return at most what was asked for */
- b = qremove(&tr->processed, n, 0);
+ b = qgrab(&tr->processed, n);
qunlock(&tr->in.io);
poperror();
tr->datain += BLEN(b);
@@ 1064,7 1042,7 @@ tlsbread(Chan *c, long n, ulong offset)
}
tr->hprocessed = b;
}
- b = qremove(&tr->hprocessed, n, 0);
+ b = qgrab(&tr->hprocessed, n);
poperror();
qunlock(&tr->hqread);
tr->handin += BLEN(b);
@@ 1729,12 1707,15 @@ sendAlert(TlsRec *tr, int err)
}
}
- b = allocb(2);
- *b->wp++ = fatal + 1;
- *b->wp++ = err;
- if(fatal)
- tlsSetState(tr, SAlert, SOpen|SHandshake|SRClose);
- tlsrecwrite(tr, RAlert, b);
+ if(!waserror()){
+ b = allocb(2);
+ *b->wp++ = fatal + 1;
+ *b->wp++ = err;
+ if(fatal)
+ tlsSetState(tr, SAlert, SOpen|SHandshake|SRClose);
+ tlsrecwrite(tr, RAlert, b);
+ poperror();
+ }
if(fatal)
tlsError(tr, msg);
}
M port/qio.c => port/qio.c +4 -2
@@ 1185,7 1185,9 @@ qiwrite(Queue *q, void *vp, int len)
if(n > Maxatomic)
n = Maxatomic;
- b = allocb(n);
+ b = iallocb(n);
+ if(b == nil)
+ break;
memmove(b->wp, p+sofar, n);
b->wp += n;
@@ 1216,7 1218,7 @@ qiwrite(Queue *q, void *vp, int len)
sofar += n;
} while(sofar < len && (q->state & Qmsg) == 0);
- return len;
+ return sofar;
}
/*