--- /sys/src/9/port/devaoe.c Fri Jul 12 22:09:55 2013 +++ /sys/src/9/port/devaoe.c Thu Sep 5 20:37:09 2013 @@ -160,6 +160,7 @@ struct Srb { Rendez; Srb *next; + int shared; /* Srb shared with kproc (don't free) */ ulong ticksent; ulong len; vlong sector; @@ -267,6 +268,7 @@ error(Enomem); srb->dp = srb->data = srb+1; srb->ticksent = MACHP(0)->ticks; + srb->shared = 0; return srb; } @@ -280,17 +282,24 @@ error(Enomem); srb->dp = srb->data = db; srb->ticksent = MACHP(0)->ticks; + srb->shared = 0; return srb; } -#define srbfree(srb) free(srb) +static void +srbfree(Srb *srb) +{ + while(srb->shared) + sched(); + free(srb); +} static void srberror(Srb *srb, char *s) { srb->error = s; srb->nout--; - if (srb->nout == 0) + if(srb->nout == 0) wakeup(srb); } @@ -1081,7 +1090,7 @@ Srb *s; s = v; - return s->error || (!s->nout && !s->len); + return s->error || (s->nout == 0 && s->len == 0); } static Frame* @@ -1137,6 +1146,7 @@ d->tail = srb; if(d->head == nil) d->head = srb; + srb->shared = 1; work(d); poperror(); qunlock(d); @@ -1399,6 +1409,7 @@ if(s == nil) error(Enomem); memmove(s, db, len); + if(waserror()){ srbfree(srb); free(s); @@ -1415,6 +1426,7 @@ break; poperror(); qunlock(d); + if(waserror()) nexterror(); tsleep(&up->sleep, return0, 0, 100); @@ -1423,8 +1435,16 @@ f->nhdr = AOEQCSZ; memset(f->hdr, 0, f->nhdr); ch = (Aoeqc*)f->hdr; - if(hset(d, f, ch, ACconfig) == -1) + if(hset(d, f, ch, ACconfig) == -1) { + /* + * these refer to qlock & waserror in the above for loop. + * there's still the first waserror outstanding. + */ + poperror(); + qunlock(d); return 0; + } + srb->shared = 1; f->srb = srb; f->dp = s; ch->verccmd = AQCfset; @@ -1433,10 +1453,7 @@ srb->nout++; f->dl->npkt++; f->dlen = len; - /* - * these refer to qlock & waserror in the above for loop. - * there's still the first waserror outstanding. - */ + /* these too */ poperror(); qunlock(d); @@ -1706,8 +1723,8 @@ d->flag = Djumbo; d->unit = newunit(); /* bzzt. inaccurate if units removed */ if(d->unit == -1){ - free(d); free(d->frames); + free(d); error("too many units"); } d->dl = d->dltab; @@ -1933,6 +1950,7 @@ memmove(f->dp, ch + 1, cslen); f->srb->nout--; wakeup(f->srb); + f->srb->shared = 0; d->nout--; f->srb = nil; f->tag = Tfree; @@ -2156,8 +2174,10 @@ } } - if(srb && --srb->nout == 0 && srb->len == 0) + if(srb && --srb->nout == 0 && srb->len == 0){ wakeup(srb); + srb->shared = 0; + } f->srb = nil; f->tag = Tfree; d->nout--; --- /sys/src/libc/port/pool.c Fri May 6 20:22:35 2011 +++ /sys/src/libc/port/pool.c Thu Sep 5 23:28:44 2013 @@ -1100,7 +1100,7 @@ return c; } -/* poolspanallocl: allocate as described below; assumes pool locked */ +/* poolallocalignl: allocate as described below; assumes pool locked */ static void* poolallocalignl(Pool *p, ulong dsize, ulong align, long offset, ulong span) {