ref: ce5f9d8210ff630d24bfc5f392b96964c891673e
parent: ea6fea596b67dea542e7a1994b10473228118400
author: cinap_lenrek <[email protected]>
date: Mon Dec 16 16:39:22 EST 2013
etheryuk: fix problems with yukon2 ep+ rev0, deoptimize
--- a/sys/src/9/pc/etheryuk.c
+++ b/sys/src/9/pc/etheryuk.c
@@ -26,7 +26,6 @@
Fprobe = 1<<0,
Sringcnt = 2048,
Tringcnt = 512,
-// Rringcnt = Nrb,
Rringcnt = 512,
Rringl = Rringcnt - 8,
};
@@ -803,20 +802,6 @@
static int debug;
static Ctlr *ctlrtab[Nctlr];
static int nctlr;
-static struct {
- union {
- struct {
- Lock;
- Block *b;
- uint starve;
- };
- uchar pad[128]; /* cacheline */
- };
- Kproc *k;
- Block *x;
- uint nfast;
- uint nslow;
-} rbtab[Nctlr];
static int
icansleep(void *v)
@@ -841,14 +826,6 @@
k->event = 0;
}
-static Status*
-getslot(Sring *r, Kproc *k)
-{
- if(r->rp + r->m - r->wp & ~r->m)
- starve(k);
- return r->r + (r->wp++ & r->m);
-}
-
static int
getnslot(Sring *r, uint *wp, Status **t, uint n)
{
@@ -861,82 +838,6 @@
return 0;
}
-/* assume allocs come from a single thread; 30*0.999x speedup */
-static Block*
-rballoc(int t)
-{
- Block *b;
-
- if((b = rbtab[t].x) != nil){
- rbtab[t].nfast++;
- rbtab[t].x = b->next;
- b->next = nil;
-b->ref = 1;
- return b;
- }
-
- ilock(&rbtab[t]);
- b = rbtab[t].x = rbtab[t].b;
- rbtab[t].b = nil;
- if(b == nil)
- rbtab[t].starve = 1;
- iunlock(&rbtab[t]);
-
- rbtab[t].nslow++;
- if(b != nil){
- rbtab[t].x = b->next;
- b->next = nil;
-b->ref = 1;
- }
- return b;
-}
-
-static void
-rbfree(Block *b, int t)
-{
- b->rp = b->wp = (uchar*)ROUND((uintptr)b->base, Rbalign);
- b->flag &= ~(Bipck | Budpck | Btcpck | Bpktck);
- ilock(&rbtab[t]);
- b->next = rbtab[t].b;
- if(b->next == nil && rbtab[t].starve){
- rbtab[t].starve = 0;
- unstarve(rbtab[t].k);
- }
- rbtab[t].b = b;
- iunlock(&rbtab[t]);
-}
-
-static void
-rbfree0(Block *b)
-{
- rbfree(b, 0);
-}
-
-static void
-rbfree1(Block *b)
-{
- rbfree(b, 1);
-}
-
-static void
-rbfree2(Block *b)
-{
- rbfree(b, 2);
-}
-
-static void
-rbfree3(Block *b)
-{
- rbfree(b, 3);
-}
-
-static Freefn freetab[Nctlr] = {
- rbfree0,
- rbfree1,
- rbfree2,
- rbfree3,
-};
-
static uint
macread32(Ctlr *c, uint r)
{
@@ -1232,13 +1133,11 @@
Block *b;
Ctlr *c;
Ether *e;
- Kproc *k;
Sring *r;
- Status *t;
+ Status *tab[2], *t;
e = v;
c = e->ctlr;
- k = &c->txmit;
r = &c->tx;
txinit(e);
@@ -1248,14 +1147,17 @@
for(;;){
if((b = qbread(e->oq, 100000)) == nil)
break;
- if(Pciwaddrh(b->rp) != 0){
- t = getslot(r, k);
+ while(getnslot(r, &r->wp, tab, 1 + is64()) == -1)
+ starve(&c->txmit);
+ t = tab[is64()];
+ assert(c->tbring[t - r->r] == nil);
+ c->tbring[t - r->r] = b;
+ if(is64()){
+ Status *t = tab[0];
t->ctl = 0;
t->op = Oaddr64 | Hw;
putle(t->status, Pciwaddrh(b->rp), 4);
}
- t = getslot(r, k);
- c->tbring[t - r->r] = b;
putle(t->status, Pciwaddrl(b->rp), 4);
putle(t->l, BLEN(b), 2);
t->op = Opkt | Hw;
@@ -1270,9 +1172,7 @@
static void
rxinit(Ether *e)
{
- int i;
Ctlr *c;
- Block *b;
Sring *r;
Status *t;
@@ -1281,12 +1181,6 @@
if(c->rxinit == 1)
return;
c->rxinit = 1;
- for(i = 0; i < Nrb; i++){
- b = allocb(c->rbsz + Rbalign);
- b->free = freetab[c->qno];
- freeb(b);
- }
-
qinit(c, Qr);
if(c->type == Yukecu && (c->rev == 2 || c->rev == 3))
qrwrite(c, Qr + Qtest, Qramdis);
@@ -1293,7 +1187,8 @@
pinit(c, Qr, &c->rx);
if((c->flag & Fnewle) == 0){
- t = getslot(r, &c->rxmit);
+ while(getnslot(r, &r->wp, &t, 1) == -1)
+ starve(&c->rxmit);
putle(t->status, 14<<16 | 14, 4);
t->ctl = 0;
t->op = Ock | Hw;
@@ -1325,7 +1220,7 @@
static int
replenish(Ether *e, Ctlr *c)
{
- int req, n, lim;
+ int n, lim;
uint wp;
Block *b;
Sring *r;
@@ -1333,29 +1228,32 @@
r = &c->rx;
wp = r->wp;
- req = 1 + is64();
lim = r->cnt/2;
if(lim > 128)
lim = 128; /* hw limit? */
for(n = 0; n < lim; n++){
- b = rballoc(c->qno);
- if(b == nil || getnslot(r, &wp, tab, req) == -1){
+ b = iallocb(c->rbsz + Rbalign);
+ if(b == nil || getnslot(r, &wp, tab, 1 + is64()) == -1){
freeb(b);
break;
}
- t = tab[0];
+ b->rp = b->wp = (uchar*)ROUND((uintptr)b->base, Rbalign);
+
+ t = tab[is64()];
+ if(rxscrew(e, r, t, wp) == -1){
+ freeb(b);
+ break;
+ }
+ assert(c->rbring[t - r->r] == nil);
+ c->rbring[t - r->r] = b;
+
if(is64()){
+ Status *t = tab[0];
putle(t->status, Pciwaddrh(b->wp), 4);
t->ctl = 0;
t->op = Oaddr64 | Hw;
- t = tab[1];
}
- if(rxscrew(e, r, t, wp) == -1)
- break;
- assert(c->rbring[t - r->r] == nil);
- c->rbring[t - r->r] = b;
-
putle(t->status, Pciwaddrl(b->wp), 4);
putle(t->l, c->rbsz, 2);
t->ctl = 0;
@@ -1367,7 +1265,7 @@
r->wp = wp;
dprint("yuk: replenish %d %ud-%ud [%d-%d]\n", n, r->rp, wp, r->rp&r->m, wp&r->m);
}
- return lim - n == 0;
+ return n == lim;
}
static void
@@ -1375,21 +1273,18 @@
{
Ctlr *c;
Ether *e;
- Kproc *k;
e = v;
c = e->ctlr;
- k = &c->rxmit;
rxinit(e);
linkup(c, Rxen);
while(waserror())
;
- for(;;)
- if(replenish(e, c) == 0){
- starve(k);
- print("yuk: rx unstarve?\n");
- }
+ for(;;){
+ if(replenish(e, c) == 0)
+ starve(&c->rxmit);
+ }
}
static void
@@ -1502,10 +1397,8 @@
if(b != nil)
freeb(b);
}
- if(r->wp - r->rp > 16){ /* BOTCH */
- print("TX unstarve %ud - %ud \n", r->wp, r->rp);
+ if(r->wp - r->rp > 16)
unstarve(&c->txmit);
- }
}
static void
@@ -1519,6 +1412,8 @@
c = e->ctlr;
r = &c->rx;
for(rp = r->rp;;){
+ if(rp == r->wp)
+ return;
i = rp++&r->m;
b = c->rbring[i];
c->rbring[i] = nil;
@@ -1526,13 +1421,12 @@
break;
}
cnt = x>>16 & 0x7fff;
- if(cnt != l || x&Rxerror &&
+ if((cnt != l || x&Rxerror) &&
!(c->type == Yukfep && c->rev == 0)){
print("#l%d: yuk rx error %.4ux\n", e->ctlrno, x&0xffff);
freeb(b);
}else{
b->wp += l;
- b->lim = b->wp; /* lie like a dog */
b->flag |= flag;
etheriq(e, b, 1);
}
@@ -1560,15 +1454,15 @@
c = e->ctlr;
r = &c->status;
- lim = r->rp & r->m;
+ lim = c->reg16[Stathd] & r->m;
p = 0;
for(;;){
- if((r->rp & r->m) == lim){
- lim = c->reg16[Stathd];
- if((r->rp & r->m) == lim)
+ i = r->rp & r->m;
+ if(i == lim){
+ lim = c->reg16[Stathd] & r->m;
+ if(i == lim)
break;
}
- i = r->rp & r->m;
s = r->r + i;
op = s->op;
if((op & Hw) == 0)
@@ -1602,8 +1496,8 @@
s->op = 0;
r->rp++;
}
- while(p && replenish(e, c) != 0)
- ;
+ if(p != 0)
+ unstarve(&c->rxmit);
c->reg[Statctl] = Statirqclr;
}
@@ -1749,15 +1643,13 @@
uint cause, d;
Ether *e;
Ctlr *c;
- Kproc *k;
e = v;
c = e->ctlr;
- k = &c->iproc;
while(waserror())
;
for(;;){
- starve(k);
+ starve(&c->iproc);
cause = c->reg[Eisr];
if(cause & Iphy)
link(e);
@@ -1865,7 +1757,6 @@
p = seprint(p, e, "stat %.4ux ctl %.3ux\n", gmacread(c, Stat), gmacread(c, Ctl));
p = seprint(p, e, "irq %.8ux\n", c->reg[Isrc2]);
p = seprint(p, e, "pref %.8ux %.4ux\n", prread32(c, Qr + Pctl), prread16(c, Qr + Pgetidx));
- p = seprint(p, e, "nfast %ud nslow %ud\n", rbtab[c->qno].nfast, rbtab[c->qno].nslow);
if(debug){
p = dumppci(c, p, e);
p = dumpgmac(c, p, e);
@@ -2311,9 +2202,12 @@
return;
}
c = malloc(sizeof *c);
+ if(c == nil){
+ print("yuk: no memory for Ctlr\n");
+ return;
+ }
c->p = p;
c->qno = nctlr;
- rbtab[c->qno].k = &c->rxmit;
c->rbsz = vtab[i].mtu;
ctlrtab[nctlr++] = c;
}
--- a/sys/src/9/pc/yukdump.h
+++ b/sys/src/9/pc/yukdump.h
@@ -200,25 +200,8 @@
return s;
}
-static int
-nblocktab(int qno)
-{
- uint i;
- Block *b;
-
- ilock(&rbtab[qno]);
- b = rbtab[qno].b;
- for(i = 0;; i++){
- if(b == nil)
- break;
- b = b->next;
- }
- iunlock(&rbtab[qno]);
- return i;
-}
-
static char*
-dumpring(Sring *r, Block **t, int qno, char *p, char *e)
+dumpring(Sring *r, Block **t, char *p, char *e)
{
int m, n;
uint i;
@@ -244,8 +227,7 @@
if(i != m + 1)
p = seprint(p, e, "-%ud ", i-1);
}
- p = seprint(p, e, "n=%d/%d", n, r->cnt);
- return seprint(p, e, " list %d\n", nblocktab(qno));
+ return seprint(p, e, "n=%d/%d", n, r->cnt);
}
/* debug; remove */
@@ -291,6 +273,6 @@
else
print(" %#p %#p (rp)\n", b? b->rp: 0, a? a->rp: 0);
- dumpring(r, bring, c->qno, p, f);
+ dumpring(r, bring, p, f);
print(" %s", buf);
}