MdeModulePkg/NvmExpressDxe: Fix wrong queue size for async IO queues

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2118

When a packet is queued/completed for the asynchronous IO queue, the logic
to roll over to the front of the queue doesn't account for actual size of
the IO Submission/Completion queue.

This causes a device to hang due to doorbell being outside of visible
queue. An example would be if an NVMe drive only supported a queue size of
128 while the driver supports 256.

Cc: Jian J Wang <jian.j.wang@intel.com>
Signed-off-by: Sean Brogan <sean.brogan@microsoft.com>
Signed-off-by: Hao A Wu <hao.a.wu@intel.com>
Acked-by: Ray Ni <ray.ni@intel.com>
This commit is contained in:
Sean Brogan 2019-09-03 16:52:26 -07:00 committed by mergify[bot]
parent 0b9ad0bc03
commit 7607174192
2 changed files with 5 additions and 3 deletions

View File

@ -672,7 +672,7 @@ ProcessAsyncTaskList (
}
Private->CqHdbl[QueueId].Cqh++;
if (Private->CqHdbl[QueueId].Cqh > NVME_ASYNC_CCQ_SIZE) {
if (Private->CqHdbl[QueueId].Cqh > MIN (NVME_ASYNC_CCQ_SIZE, Private->Cap.Mqes)) {
Private->CqHdbl[QueueId].Cqh = 0;
Private->Pt[QueueId] ^= 1;
}

View File

@ -452,6 +452,7 @@ NvmExpressPassThru (
NVME_SQ *Sq;
NVME_CQ *Cq;
UINT16 QueueId;
UINT16 QueueSize;
UINT32 Bytes;
UINT16 Offset;
EFI_EVENT TimerEvent;
@ -540,6 +541,7 @@ NvmExpressPassThru (
Prp = NULL;
TimerEvent = NULL;
Status = EFI_SUCCESS;
QueueSize = MIN (NVME_ASYNC_CSQ_SIZE, Private->Cap.Mqes) + 1;
if (Packet->QueueType == NVME_ADMIN_QUEUE) {
QueueId = 0;
@ -552,7 +554,7 @@ NvmExpressPassThru (
//
// Submission queue full check.
//
if ((Private->SqTdbl[QueueId].Sqt + 1) % (NVME_ASYNC_CSQ_SIZE + 1) ==
if ((Private->SqTdbl[QueueId].Sqt + 1) % QueueSize ==
Private->AsyncSqHead) {
return EFI_NOT_READY;
}
@ -701,7 +703,7 @@ NvmExpressPassThru (
//
if ((Event != NULL) && (QueueId != 0)) {
Private->SqTdbl[QueueId].Sqt =
(Private->SqTdbl[QueueId].Sqt + 1) % (NVME_ASYNC_CSQ_SIZE + 1);
(Private->SqTdbl[QueueId].Sqt + 1) % QueueSize;
} else {
Private->SqTdbl[QueueId].Sqt ^= 1;
}