ref: 731634631ff23a22abc6413ccb0d5151c5dff766
parent: afcf25f9dab81deb2e07fc28959315b3f24c6db3
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Tue Jul 25 17:42:37 EDT 2023
sdnvme: dont make queues largers than MQES field in capability We need completion queue size to be the sum of all submission queue sizes, but all queues (completion and submission) must not exceed the maximum queue size (MQES field).
--- a/sys/src/9/port/sdnvme.c
+++ b/sys/src/9/port/sdnvme.c
@@ -484,21 +484,36 @@
static void
setupqueues(Ctlr *ctlr)
{
- u32int lgsize, st, *e;
+ u32int mqes, lgcqsize, lgsqsize, nsq, st, *e;
CQ *cq;
SQ *sq;
WS ws;
int i;
- /* Overkill */
- lgsize = 12-6+4;
- while(lgsize < 16+4 && lgsize < ctlr->mpsshift && 1<<lgsize < conf.nmach<<12-6+4)
- lgsize++;
+ mqes = 1 + (ctlr->cap & 0xFFFF);
+ if(mqes < 2)
+ mqes = 2;
+ for(lgsqsize = 0; 1<<lgsqsize < mqes; lgsqsize++)
+ ;
+ if(lgsqsize > 12-6)
+ lgsqsize = 12-6;
+ nsq = conf.nmach;
+ while((lgcqsize = lgsqsize) > 0){
+ while(nsq >= 1<<lgcqsize)
+ nsq >>= 1;
+ while(1<<lgcqsize < nsq<<lgsqsize)
+ lgcqsize++;
+ if(1<<lgcqsize <= mqes)
+ break;
+ lgsqsize--;
+ }
+ lgsqsize += 6;
+ lgcqsize += 4;
/* CQID1: shared completion queue */
cq = &ctlr->cq[1];
- cqalloc(ctlr, cq, lgsize);
- e = qcmd(&ws, ctlr, 1, 0x05, 0, cq->base, 1<<lgsize);
+ cqalloc(ctlr, cq, lgcqsize);
+ e = qcmd(&ws, ctlr, 1, 0x05, 0, cq->base, 1<<lgcqsize);
e[10] = (cq - ctlr->cq) | cq->mask<<16;
e[11] = 3; /* IEN | PC */
checkstatus(wcmd(&ws, e), "create completion queue");
@@ -506,10 +521,10 @@
st = 0;
/* SQID[1..nmach]: submission queue per cpu */
- for(i=1; i<=conf.nmach; i++){
+ for(i=1; i<=nsq; i++){
sq = &ctlr->sq[i];
- sqalloc(ctlr, sq, 12);
- e = qcmd(&ws, ctlr, 1, 0x01, 0, sq->base, 0x1000);
+ sqalloc(ctlr, sq, lgsqsize);
+ e = qcmd(&ws, ctlr, 1, 0x01, 0, sq->base, 1<<lgsqsize);
e[10] = i | sq->mask<<16;
e[11] = (cq - ctlr->cq)<<16 | 1; /* CQID<<16 | PC */
st = wcmd(&ws, e);
--
⑨