From b713f1dc45727aa14a5eb919ccf809282f805b74 Mon Sep 17 00:00:00 2001 From: Matheus Date: Fri, 10 Feb 2023 01:52:38 -0300 Subject: [PATCH] nvme: fix use of non zero'd admin queue and wrong phase checking --- src/sys/block/nvme.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/sys/block/nvme.c b/src/sys/block/nvme.c index 61bd3540..89932c72 100755 --- a/src/sys/block/nvme.c +++ b/src/sys/block/nvme.c @@ -273,11 +273,13 @@ __attribute__((noreturn)) static void nvme_workerthread(){ ctlrinfo_t* controller = ctlrpass; queuepair_t* queuepair = queuepass; entrypair_t* userentries[256]; + memset(userentries, 0, sizeof(userentries)); int lowestfreepair = 0; compqentry* compq = queuepair->comp.addr; subqentry* subq = queuepair->sub.addr; volatile uint32_t* subqdoorbell = (uint32_t*)((uint8_t*)controller->bar0 + 0x1000 + queuepair->sub.id * 2 * controller->doorbellstride); volatile uint32_t* compqdoorbell = (uint32_t*)((uint8_t*)controller->bar0 + 0x1000 + (queuepair->comp.id*2 + 1) * controller->doorbellstride); + int currphase = 1; while(1){ @@ -313,19 +315,22 @@ __attribute__((noreturn)) static void nvme_workerthread(){ while(1){ - if(compq[queuepair->comp.idx].phase == 0) + if(compq[queuepair->comp.idx].phase == !currphase) break; int pair = compq[queuepair->comp.idx].cmdid; userentries[pair]->comp = compq[queuepair->comp.idx]; + event_signal(&userentries[pair]->completion, false); userentries[pair] = NULL; ++queuepair->comp.idx; queuepair->comp.idx %= queuepair->comp.entrycount; + if(queuepair->comp.idx == 0) + currphase = !currphase; ++processed; @@ -662,7 +667,7 @@ static void nvme_initctlr(pci_enumeration* pci){ cc &= ~CC_AMS_MASK; - // set the config and enable + // set the config bar0->cc = cc; @@ -673,6 +678,8 @@ static void nvme_initctlr(pci_enumeration* pci){ if(!adminqueues) _panic("Out of memory", NULL); + memset(MAKEHHDM(adminqueues), 0, PAGE_SIZE*2); + bar0->asq = (uint64_t)adminqueues; bar0->acq = (uint64_t)adminqueues + PAGE_SIZE; @@ -700,7 +707,7 @@ static void nvme_initctlr(pci_enumeration* pci){ info->maxqueue = (bar0->cap & CAP_QUEUESIZE) + 1; info->doorbellstride = 1 << (2 + ((bar0->cap & CAP_DOORBELL) >> 32)); info->bar0 = bar0; - + info->adminqueue.sub.addr = MAKEHHDM(adminqueues); info->adminqueue.comp.addr = MAKEHHDM(adminqueues + PAGE_SIZE); info->adminqueue.comp.entrycount = PAGE_SIZE / sizeof(compqentry);