etheryuk: fix problems with yukon2 ep+ rev0, deoptimize
This commit is contained in:
parent
ea6fea596b
commit
ce5f9d8210
2 changed files with 49 additions and 173 deletions
|
@ -26,7 +26,6 @@ enum {
|
||||||
Fprobe = 1<<0,
|
Fprobe = 1<<0,
|
||||||
Sringcnt = 2048,
|
Sringcnt = 2048,
|
||||||
Tringcnt = 512,
|
Tringcnt = 512,
|
||||||
// Rringcnt = Nrb,
|
|
||||||
Rringcnt = 512,
|
Rringcnt = 512,
|
||||||
Rringl = Rringcnt - 8,
|
Rringl = Rringcnt - 8,
|
||||||
};
|
};
|
||||||
|
@ -803,20 +802,6 @@ static uchar nilea[Eaddrlen];
|
||||||
static int debug;
|
static int debug;
|
||||||
static Ctlr *ctlrtab[Nctlr];
|
static Ctlr *ctlrtab[Nctlr];
|
||||||
static int 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
|
static int
|
||||||
icansleep(void *v)
|
icansleep(void *v)
|
||||||
|
@ -841,14 +826,6 @@ starve(Kproc *k)
|
||||||
k->event = 0;
|
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
|
static int
|
||||||
getnslot(Sring *r, uint *wp, Status **t, uint n)
|
getnslot(Sring *r, uint *wp, Status **t, uint n)
|
||||||
{
|
{
|
||||||
|
@ -861,82 +838,6 @@ getnslot(Sring *r, uint *wp, Status **t, uint n)
|
||||||
return 0;
|
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
|
static uint
|
||||||
macread32(Ctlr *c, uint r)
|
macread32(Ctlr *c, uint r)
|
||||||
{
|
{
|
||||||
|
@ -1232,13 +1133,11 @@ tproc(void *v)
|
||||||
Block *b;
|
Block *b;
|
||||||
Ctlr *c;
|
Ctlr *c;
|
||||||
Ether *e;
|
Ether *e;
|
||||||
Kproc *k;
|
|
||||||
Sring *r;
|
Sring *r;
|
||||||
Status *t;
|
Status *tab[2], *t;
|
||||||
|
|
||||||
e = v;
|
e = v;
|
||||||
c = e->ctlr;
|
c = e->ctlr;
|
||||||
k = &c->txmit;
|
|
||||||
r = &c->tx;
|
r = &c->tx;
|
||||||
|
|
||||||
txinit(e);
|
txinit(e);
|
||||||
|
@ -1248,14 +1147,17 @@ tproc(void *v)
|
||||||
for(;;){
|
for(;;){
|
||||||
if((b = qbread(e->oq, 100000)) == nil)
|
if((b = qbread(e->oq, 100000)) == nil)
|
||||||
break;
|
break;
|
||||||
if(Pciwaddrh(b->rp) != 0){
|
while(getnslot(r, &r->wp, tab, 1 + is64()) == -1)
|
||||||
t = getslot(r, k);
|
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->ctl = 0;
|
||||||
t->op = Oaddr64 | Hw;
|
t->op = Oaddr64 | Hw;
|
||||||
putle(t->status, Pciwaddrh(b->rp), 4);
|
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->status, Pciwaddrl(b->rp), 4);
|
||||||
putle(t->l, BLEN(b), 2);
|
putle(t->l, BLEN(b), 2);
|
||||||
t->op = Opkt | Hw;
|
t->op = Opkt | Hw;
|
||||||
|
@ -1270,9 +1172,7 @@ tproc(void *v)
|
||||||
static void
|
static void
|
||||||
rxinit(Ether *e)
|
rxinit(Ether *e)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
Ctlr *c;
|
Ctlr *c;
|
||||||
Block *b;
|
|
||||||
Sring *r;
|
Sring *r;
|
||||||
Status *t;
|
Status *t;
|
||||||
|
|
||||||
|
@ -1281,19 +1181,14 @@ rxinit(Ether *e)
|
||||||
if(c->rxinit == 1)
|
if(c->rxinit == 1)
|
||||||
return;
|
return;
|
||||||
c->rxinit = 1;
|
c->rxinit = 1;
|
||||||
for(i = 0; i < Nrb; i++){
|
|
||||||
b = allocb(c->rbsz + Rbalign);
|
|
||||||
b->free = freetab[c->qno];
|
|
||||||
freeb(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
qinit(c, Qr);
|
qinit(c, Qr);
|
||||||
if(c->type == Yukecu && (c->rev == 2 || c->rev == 3))
|
if(c->type == Yukecu && (c->rev == 2 || c->rev == 3))
|
||||||
qrwrite(c, Qr + Qtest, Qramdis);
|
qrwrite(c, Qr + Qtest, Qramdis);
|
||||||
pinit(c, Qr, &c->rx);
|
pinit(c, Qr, &c->rx);
|
||||||
|
|
||||||
if((c->flag & Fnewle) == 0){
|
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);
|
putle(t->status, 14<<16 | 14, 4);
|
||||||
t->ctl = 0;
|
t->ctl = 0;
|
||||||
t->op = Ock | Hw;
|
t->op = Ock | Hw;
|
||||||
|
@ -1325,7 +1220,7 @@ rxscrew(Ether *e, Sring *r, Status *t, uint wp)
|
||||||
static int
|
static int
|
||||||
replenish(Ether *e, Ctlr *c)
|
replenish(Ether *e, Ctlr *c)
|
||||||
{
|
{
|
||||||
int req, n, lim;
|
int n, lim;
|
||||||
uint wp;
|
uint wp;
|
||||||
Block *b;
|
Block *b;
|
||||||
Sring *r;
|
Sring *r;
|
||||||
|
@ -1333,29 +1228,32 @@ replenish(Ether *e, Ctlr *c)
|
||||||
|
|
||||||
r = &c->rx;
|
r = &c->rx;
|
||||||
wp = r->wp;
|
wp = r->wp;
|
||||||
req = 1 + is64();
|
|
||||||
|
|
||||||
lim = r->cnt/2;
|
lim = r->cnt/2;
|
||||||
if(lim > 128)
|
if(lim > 128)
|
||||||
lim = 128; /* hw limit? */
|
lim = 128; /* hw limit? */
|
||||||
for(n = 0; n < lim; n++){
|
for(n = 0; n < lim; n++){
|
||||||
b = rballoc(c->qno);
|
b = iallocb(c->rbsz + Rbalign);
|
||||||
if(b == nil || getnslot(r, &wp, tab, req) == -1){
|
if(b == nil || getnslot(r, &wp, tab, 1 + is64()) == -1){
|
||||||
freeb(b);
|
freeb(b);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
t = tab[0];
|
b->rp = b->wp = (uchar*)ROUND((uintptr)b->base, Rbalign);
|
||||||
if(is64()){
|
|
||||||
putle(t->status, Pciwaddrh(b->wp), 4);
|
t = tab[is64()];
|
||||||
t->ctl = 0;
|
if(rxscrew(e, r, t, wp) == -1){
|
||||||
t->op = Oaddr64 | Hw;
|
freeb(b);
|
||||||
t = tab[1];
|
|
||||||
}
|
|
||||||
if(rxscrew(e, r, t, wp) == -1)
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
assert(c->rbring[t - r->r] == nil);
|
assert(c->rbring[t - r->r] == nil);
|
||||||
c->rbring[t - r->r] = b;
|
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;
|
||||||
|
}
|
||||||
putle(t->status, Pciwaddrl(b->wp), 4);
|
putle(t->status, Pciwaddrl(b->wp), 4);
|
||||||
putle(t->l, c->rbsz, 2);
|
putle(t->l, c->rbsz, 2);
|
||||||
t->ctl = 0;
|
t->ctl = 0;
|
||||||
|
@ -1367,7 +1265,7 @@ replenish(Ether *e, Ctlr *c)
|
||||||
r->wp = wp;
|
r->wp = wp;
|
||||||
dprint("yuk: replenish %d %ud-%ud [%d-%d]\n", n, r->rp, wp, r->rp&r->m, wp&r->m);
|
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
|
static void
|
||||||
|
@ -1375,21 +1273,18 @@ rproc(void *v)
|
||||||
{
|
{
|
||||||
Ctlr *c;
|
Ctlr *c;
|
||||||
Ether *e;
|
Ether *e;
|
||||||
Kproc *k;
|
|
||||||
|
|
||||||
e = v;
|
e = v;
|
||||||
c = e->ctlr;
|
c = e->ctlr;
|
||||||
k = &c->rxmit;
|
|
||||||
|
|
||||||
rxinit(e);
|
rxinit(e);
|
||||||
linkup(c, Rxen);
|
linkup(c, Rxen);
|
||||||
while(waserror())
|
while(waserror())
|
||||||
;
|
;
|
||||||
for(;;)
|
for(;;){
|
||||||
if(replenish(e, c) == 0){
|
if(replenish(e, c) == 0)
|
||||||
starve(k);
|
starve(&c->rxmit);
|
||||||
print("yuk: rx unstarve?\n");
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1502,10 +1397,8 @@ txcleanup(Ctlr *c, uint end)
|
||||||
if(b != nil)
|
if(b != nil)
|
||||||
freeb(b);
|
freeb(b);
|
||||||
}
|
}
|
||||||
if(r->wp - r->rp > 16){ /* BOTCH */
|
if(r->wp - r->rp > 16)
|
||||||
print("TX unstarve %ud - %ud \n", r->wp, r->rp);
|
|
||||||
unstarve(&c->txmit);
|
unstarve(&c->txmit);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1519,6 +1412,8 @@ rx(Ether *e, uint l, uint x, uint flag)
|
||||||
c = e->ctlr;
|
c = e->ctlr;
|
||||||
r = &c->rx;
|
r = &c->rx;
|
||||||
for(rp = r->rp;;){
|
for(rp = r->rp;;){
|
||||||
|
if(rp == r->wp)
|
||||||
|
return;
|
||||||
i = rp++&r->m;
|
i = rp++&r->m;
|
||||||
b = c->rbring[i];
|
b = c->rbring[i];
|
||||||
c->rbring[i] = nil;
|
c->rbring[i] = nil;
|
||||||
|
@ -1526,13 +1421,12 @@ rx(Ether *e, uint l, uint x, uint flag)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cnt = x>>16 & 0x7fff;
|
cnt = x>>16 & 0x7fff;
|
||||||
if(cnt != l || x&Rxerror &&
|
if((cnt != l || x&Rxerror) &&
|
||||||
!(c->type == Yukfep && c->rev == 0)){
|
!(c->type == Yukfep && c->rev == 0)){
|
||||||
print("#l%d: yuk rx error %.4ux\n", e->ctlrno, x&0xffff);
|
print("#l%d: yuk rx error %.4ux\n", e->ctlrno, x&0xffff);
|
||||||
freeb(b);
|
freeb(b);
|
||||||
}else{
|
}else{
|
||||||
b->wp += l;
|
b->wp += l;
|
||||||
b->lim = b->wp; /* lie like a dog */
|
|
||||||
b->flag |= flag;
|
b->flag |= flag;
|
||||||
etheriq(e, b, 1);
|
etheriq(e, b, 1);
|
||||||
}
|
}
|
||||||
|
@ -1560,15 +1454,15 @@ sring(Ether *e)
|
||||||
|
|
||||||
c = e->ctlr;
|
c = e->ctlr;
|
||||||
r = &c->status;
|
r = &c->status;
|
||||||
lim = r->rp & r->m;
|
lim = c->reg16[Stathd] & r->m;
|
||||||
p = 0;
|
p = 0;
|
||||||
for(;;){
|
for(;;){
|
||||||
if((r->rp & r->m) == lim){
|
i = r->rp & r->m;
|
||||||
lim = c->reg16[Stathd];
|
if(i == lim){
|
||||||
if((r->rp & r->m) == lim)
|
lim = c->reg16[Stathd] & r->m;
|
||||||
|
if(i == lim)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i = r->rp & r->m;
|
|
||||||
s = r->r + i;
|
s = r->r + i;
|
||||||
op = s->op;
|
op = s->op;
|
||||||
if((op & Hw) == 0)
|
if((op & Hw) == 0)
|
||||||
|
@ -1602,8 +1496,8 @@ sring(Ether *e)
|
||||||
s->op = 0;
|
s->op = 0;
|
||||||
r->rp++;
|
r->rp++;
|
||||||
}
|
}
|
||||||
while(p && replenish(e, c) != 0)
|
if(p != 0)
|
||||||
;
|
unstarve(&c->rxmit);
|
||||||
c->reg[Statctl] = Statirqclr;
|
c->reg[Statctl] = Statirqclr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1749,15 +1643,13 @@ iproc(void *v)
|
||||||
uint cause, d;
|
uint cause, d;
|
||||||
Ether *e;
|
Ether *e;
|
||||||
Ctlr *c;
|
Ctlr *c;
|
||||||
Kproc *k;
|
|
||||||
|
|
||||||
e = v;
|
e = v;
|
||||||
c = e->ctlr;
|
c = e->ctlr;
|
||||||
k = &c->iproc;
|
|
||||||
while(waserror())
|
while(waserror())
|
||||||
;
|
;
|
||||||
for(;;){
|
for(;;){
|
||||||
starve(k);
|
starve(&c->iproc);
|
||||||
cause = c->reg[Eisr];
|
cause = c->reg[Eisr];
|
||||||
if(cause & Iphy)
|
if(cause & Iphy)
|
||||||
link(e);
|
link(e);
|
||||||
|
@ -1865,7 +1757,6 @@ ifstat(Ether *e0, void *a, long n, ulong offset)
|
||||||
p = seprint(p, e, "stat %.4ux ctl %.3ux\n", gmacread(c, Stat), gmacread(c, Ctl));
|
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, "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, "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){
|
if(debug){
|
||||||
p = dumppci(c, p, e);
|
p = dumppci(c, p, e);
|
||||||
p = dumpgmac(c, p, e);
|
p = dumpgmac(c, p, e);
|
||||||
|
@ -2311,9 +2202,12 @@ scan(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
c = malloc(sizeof *c);
|
c = malloc(sizeof *c);
|
||||||
|
if(c == nil){
|
||||||
|
print("yuk: no memory for Ctlr\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
c->p = p;
|
c->p = p;
|
||||||
c->qno = nctlr;
|
c->qno = nctlr;
|
||||||
rbtab[c->qno].k = &c->rxmit;
|
|
||||||
c->rbsz = vtab[i].mtu;
|
c->rbsz = vtab[i].mtu;
|
||||||
ctlrtab[nctlr++] = c;
|
ctlrtab[nctlr++] = c;
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,25 +200,8 @@ rs(uint r)
|
||||||
return s;
|
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*
|
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;
|
int m, n;
|
||||||
uint i;
|
uint i;
|
||||||
|
@ -244,8 +227,7 @@ dumpring(Sring *r, Block **t, int qno, char *p, char *e)
|
||||||
if(i != m + 1)
|
if(i != m + 1)
|
||||||
p = seprint(p, e, "-%ud ", i-1);
|
p = seprint(p, e, "-%ud ", i-1);
|
||||||
}
|
}
|
||||||
p = seprint(p, e, "n=%d/%d", n, r->cnt);
|
return seprint(p, e, "n=%d/%d", n, r->cnt);
|
||||||
return seprint(p, e, " list %d\n", nblocktab(qno));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* debug; remove */
|
/* debug; remove */
|
||||||
|
@ -291,6 +273,6 @@ descriptorfu(Ether *e, uint qoff)
|
||||||
else
|
else
|
||||||
print(" %#p %#p (rp)\n", b? b->rp: 0, a? a->rp: 0);
|
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);
|
print(" %s", buf);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue