ref: bc8cf4979008759a50a4f3bca28df5a791bbd85d
parent: 3c05da0455b90cd377fd72ce614b549158388617
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Mar 30 19:33:46 EDT 2017
sdnvme: don't write completion queue doorbell register when nothing has been processed turns out on real hardware, the front falls off if we write the completion queue doorbell registers without consuming an entry. so only write the register when we have processed something.
--- a/sys/src/9/pc/sdnvme.c
+++ b/sys/src/9/pc/sdnvme.c
@@ -165,7 +165,7 @@
if(cq->base == nil)
continue;
phaseshift = 16 - cq->shift;
- for(;; cq->head++){+ for(;;){e = &cq->base[(cq->head & cq->mask)<<2];
if(((e[3] ^ (cq->head << phaseshift)) & 0x10000) == 0)
break;
@@ -183,11 +183,9 @@
*wp = nil;
wakeup(z);
}
+ ctlr->reg[DBell + ((cq-ctlr->cq)*2+1 << ctlr->dstrd)] = ++cq->head & cq->mask;
}
- ctlr->reg[DBell + ((cq-ctlr->cq)*2+1 << ctlr->dstrd)] = cq->head & cq->mask;
}
- if((ctlr->reg[CSts] & 3) != 1)
- iprint("nvmeintr: fatal controller error\n");ctlr->reg[IntMc] = ctlr->ints;
iunlock(&ctlr->intr);
}
--
⑨