ethervirtio: avoid dumping packets in txproc when ring gets full

This commit is contained in:
cinap_lenrek 2014-12-07 15:34:53 +01:00
parent 964dafbdf0
commit aff0dc5e67

View file

@ -197,33 +197,36 @@ txproc(void *v)
q->used->flags &= ~Rnointerrupt; q->used->flags &= ~Rnointerrupt;
while((b = qbread(edev->oq, 1000000)) != nil){ while((b = qbread(edev->oq, 1000000)) != nil){
i = q->avail->idx & (q->qmask >> 1); for(;;){
if(q->block[i] == nil) { /* retire completed packets */
/* slot free, fill in descriptor */ while((i = q->lastused) != q->used->idx){
q->block[i] = b; u = &q->usedent[i & q->qmask];
j = (i << 1) | 1; i = (u->id & q->qmask) >> 1;
q->desc[j].addr = PADDR(b->rp); if(q->block[i] == nil)
q->desc[j].len = BLEN(b); break;
coherence(); freeb(q->block[i]);
q->avail->idx++; q->block[i] = nil;
outs(ctlr->port+Qnotify, Vtxq); q->lastused++;
} else { }
/* transmit ring is full */
freeb(b); /* have free slot? */
i = q->avail->idx & (q->qmask >> 1);
if(q->block[i] == nil)
break;
/* ring full, wait and retry */
if(!vhasroom(q)) if(!vhasroom(q))
sleep(q, vhasroom, q); sleep(q, vhasroom, q);
} }
/* free completed packets */ /* slot is free, fill in descriptor */
while((i = q->lastused) != q->used->idx){ q->block[i] = b;
u = &q->usedent[i & q->qmask]; j = (i << 1) | 1;
i = (u->id & q->qmask) >> 1; q->desc[j].addr = PADDR(b->rp);
if((b = q->block[i]) == nil) q->desc[j].len = BLEN(b);
break; coherence();
q->block[i] = nil; q->avail->idx++;
freeb(b); outs(ctlr->port+Qnotify, Vtxq);
q->lastused++;
}
} }
pexit("ether out queue closed", 1); pexit("ether out queue closed", 1);