ether82563: remove buffer pool optimizations

rx pool exhaustion causes the system to deadlock when netbooted.
queue management should (etheroq) already makes sure the systen
can keep up with the data thowing away buffers.
This commit is contained in:
cinap_lenrek 2013-07-27 09:25:36 +02:00
parent 2009d55643
commit b116a9ad33

View file

@ -416,7 +416,6 @@ enum {
Ntd = 128, /* power of two */
Nrb = 512+512, /* private receive buffers per Ctlr */
Rbalign = BY2PG, /* rx buffer alignment */
Npool = 8,
};
/*
@ -492,7 +491,6 @@ struct Ctlr {
Ctlr *next;
int active;
int type;
int pool;
u16int eeprom[0x40];
QLock alock; /* attach */
@ -549,31 +547,11 @@ struct Ctlr {
u32int pba; /* packet buffer allocation */
};
typedef struct Rbpool Rbpool;
struct Rbpool {
union {
struct {
Lock;
Block *b;
uint nstarve;
uint nwakey;
uint starve;
Rendez;
};
uchar pad[128]; /* cacheline */
};
Block *x;
uint nfast;
uint nslow;
};
#define csr32r(c, r) (*((c)->nic+((r)/4)))
#define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
static Ctlr *i82563ctlrhead;
static Ctlr *i82563ctlrtail;
static Rbpool rbtab[Npool];
static char *statistics[Nstatistics] = {
"CRC Error",
@ -664,7 +642,6 @@ i82563ifstat(Ether *edev, void *a, long n, ulong offset)
int i, r;
uvlong tuvl, ruvl;
Ctlr *ctlr;
Rbpool *b;
p = s = smalloc(READSTR);
e = p + READSTR;
@ -717,9 +694,6 @@ i82563ifstat(Ether *edev, void *a, long n, ulong offset)
p = seprint(p, e, "txdctl: %.8ux\n", csr32r(ctlr, Txdctl));
p = seprint(p, e, "pba: %.8ux\n", ctlr->pba);
b = rbtab + ctlr->pool;
p = seprint(p, e, "pool: fast %ud slow %ud nstarve %ud nwakey %ud starve %ud\n",
b->nfast, b->nslow, b->nstarve, b->nwakey, b->starve);
p = seprint(p, e, "speeds: 10:%ud 100:%ud 1000:%ud ?:%ud\n",
ctlr->speeds[0], ctlr->speeds[1], ctlr->speeds[2], ctlr->speeds[3]);
p = seprint(p, e, "type: %s\n", cname(ctlr));
@ -788,138 +762,6 @@ i82563multicast(void *arg, uchar *addr, int on)
csr32w(ctlr, Mta+x*4, ctlr->mta[x]);
}
static int
icansleep(void *v)
{
Rbpool *p;
p = v;
return p->b != nil;
}
static Block*
i82563rballoc(Rbpool *p)
{
Block *b;
for(;;){
if((b = p->x) != nil){
p->nfast++;
p->x = b->next;
b->next = nil;
_xinc(&b->ref);
return b;
}
ilock(p);
b = p->b;
p->b = nil;
if(b == nil){
p->nstarve++;
iunlock(p);
return nil;
}
p->nslow++;
iunlock(p);
p->x = b;
}
}
static void
rbfree(Block *b, int t)
{
Rbpool *p;
p = rbtab + t;
b->rp = b->wp = (uchar*)ROUND((uintptr)b->base, Rbalign);
b->flag &= ~(Bipck | Budpck | Btcpck | Bpktck);
ilock(p);
b->next = p->b;
p->b = b;
if(p->starve){
if(0)
iprint("wakey %d; %d %d\n", t, p->nstarve, p->nwakey);
p->nwakey++;
p->starve = 0;
wakeup(p);
}
iunlock(p);
}
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 void
rbfree4(Block *b)
{
rbfree(b, 4);
}
static void
rbfree5(Block *b)
{
rbfree(b, 5);
}
static void
rbfree6(Block *b)
{
rbfree(b, 6);
}
static void
rbfree7(Block *b)
{
rbfree(b, 7);
}
static Freefn freetab[Npool] = {
rbfree0,
rbfree1,
rbfree2,
rbfree3,
rbfree4,
rbfree5,
rbfree6,
rbfree7,
};
static int
newpool(void)
{
static int seq;
if(seq == nelem(freetab))
return -1;
if(freetab[seq] == nil){
print("82563: bad freetab\n");
return -1;
}
return seq++;
}
static void
i82563im(Ctlr *ctlr, int im)
{
@ -1028,38 +870,22 @@ i82563tproc(void *v)
}
}
static int
i82563replenish(Ctlr *ctlr, int maysleep)
static void
i82563replenish(Ctlr *ctlr)
{
uint rdt, i;
Block *bp;
Rbpool *p;
Rd *rd;
rdt = ctlr->rdt;
p = rbtab + ctlr->pool;
i = 0;
for(; NEXT(rdt, ctlr->nrd) != ctlr->rdh; rdt = NEXT(rdt, ctlr->nrd)){
for(rdt = ctlr->rdt; NEXT(rdt, ctlr->nrd) != ctlr->rdh; rdt = NEXT(rdt, ctlr->nrd)){
rd = &ctlr->rdba[rdt];
if(ctlr->rb[rdt] != nil){
iprint("82563: tx overrun\n");
break;
}
redux:
bp = i82563rballoc(p);
if(bp == nil){
if(rdt - ctlr->rdh >= 16)
break;
print("i82563%d: no rx buffers\n", ctlr->pool);
if(maysleep == 0)
return -1;
ilock(p);
p->starve = 1;
iunlock(p);
sleep(p, icansleep, p);
goto redux;
}
i++;
bp = allocb(ctlr->rbsz + Rbalign);
ctlr->rb[rdt] = bp;
rd->addr[0] = PCIWADDR(bp->rp);
rd->addr[1] = 0;
@ -1071,7 +897,6 @@ i82563replenish(Ctlr *ctlr, int maysleep)
ctlr->rdt = rdt;
csr32w(ctlr, Rdt, rdt);
}
return 0;
}
static void
@ -1160,14 +985,14 @@ i82563rproc(void *arg)
for(;;){
i82563im(ctlr, im);
ctlr->rsleep++;
i82563replenish(ctlr, 1);
i82563replenish(ctlr);
sleep(&ctlr->rrendez, i82563rim, ctlr);
rdh = ctlr->rdh;
for(;;){
rd = &ctlr->rdba[rdh];
rim = ctlr->rim;
ctlr->rim = 0;
rd = &ctlr->rdba[rdh];
if(!(rd->status & Rdd))
break;
@ -1207,12 +1032,10 @@ i82563rproc(void *arg)
} else
freeb(bp);
ctlr->rb[rdh] = nil;
rd->status = 0;
ctlr->rdfree--;
ctlr->rdh = rdh = NEXT(rdh, ctlr->nrd);
if(ctlr->nrd-ctlr->rdfree >= 32 || (rim & Rxdmt0))
if(i82563replenish(ctlr, 0) == -1)
break;
i82563replenish(ctlr);
}
}
}
@ -1460,8 +1283,6 @@ static void
i82563attach(Ether *edev)
{
char name[KNAMELEN];
int i;
Block *bp;
Ctlr *ctlr;
ctlr = edev->ctlr;
@ -1490,10 +1311,6 @@ i82563attach(Ether *edev)
ctlr->tdba = (Td*)(ctlr->rdba + ctlr->nrd);
if(waserror()){
while(bp = i82563rballoc(rbtab + ctlr->pool)){
bp->free = nil;
freeb(bp);
}
free(ctlr->tb);
ctlr->tb = nil;
free(ctlr->rb);
@ -1504,12 +1321,6 @@ i82563attach(Ether *edev)
nexterror();
}
for(i = 0; i < Nrb; i++){
bp = allocb(ctlr->rbsz + Rbalign);
bp->free = freetab[ctlr->pool];
freeb(bp);
}
snprint(name, sizeof name, "#l%dl", edev->ctlrno);
if(csr32r(ctlr, Status) & Tbimode)
kproc(name, serdeslproc, edev); /* mac based serdes */
@ -2037,10 +1848,6 @@ setup(Ctlr *ctlr)
{
Pcidev *p;
if((ctlr->pool = newpool()) == -1){
print("%s: no pool\n", cname(ctlr));
return -1;
}
p = ctlr->pcidev;
ctlr->nic = vmap(ctlr->port, p->mem[0].size);
if(ctlr->nic == nil){