ref: 5aa8594281946edbf8122d452b71337002f38684
parent: 1d9c31d9f5f539c854aea84056d55ad47995ee48
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);