mirror of https://github.com/acidanthera/audk.git
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:
parent
0b9ad0bc03
commit
7607174192
|
@ -672,7 +672,7 @@ ProcessAsyncTaskList (
|
||||||
}
|
}
|
||||||
|
|
||||||
Private->CqHdbl[QueueId].Cqh++;
|
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->CqHdbl[QueueId].Cqh = 0;
|
||||||
Private->Pt[QueueId] ^= 1;
|
Private->Pt[QueueId] ^= 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -452,6 +452,7 @@ NvmExpressPassThru (
|
||||||
NVME_SQ *Sq;
|
NVME_SQ *Sq;
|
||||||
NVME_CQ *Cq;
|
NVME_CQ *Cq;
|
||||||
UINT16 QueueId;
|
UINT16 QueueId;
|
||||||
|
UINT16 QueueSize;
|
||||||
UINT32 Bytes;
|
UINT32 Bytes;
|
||||||
UINT16 Offset;
|
UINT16 Offset;
|
||||||
EFI_EVENT TimerEvent;
|
EFI_EVENT TimerEvent;
|
||||||
|
@ -540,6 +541,7 @@ NvmExpressPassThru (
|
||||||
Prp = NULL;
|
Prp = NULL;
|
||||||
TimerEvent = NULL;
|
TimerEvent = NULL;
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
|
QueueSize = MIN (NVME_ASYNC_CSQ_SIZE, Private->Cap.Mqes) + 1;
|
||||||
|
|
||||||
if (Packet->QueueType == NVME_ADMIN_QUEUE) {
|
if (Packet->QueueType == NVME_ADMIN_QUEUE) {
|
||||||
QueueId = 0;
|
QueueId = 0;
|
||||||
|
@ -552,7 +554,7 @@ NvmExpressPassThru (
|
||||||
//
|
//
|
||||||
// Submission queue full check.
|
// Submission queue full check.
|
||||||
//
|
//
|
||||||
if ((Private->SqTdbl[QueueId].Sqt + 1) % (NVME_ASYNC_CSQ_SIZE + 1) ==
|
if ((Private->SqTdbl[QueueId].Sqt + 1) % QueueSize ==
|
||||||
Private->AsyncSqHead) {
|
Private->AsyncSqHead) {
|
||||||
return EFI_NOT_READY;
|
return EFI_NOT_READY;
|
||||||
}
|
}
|
||||||
|
@ -701,7 +703,7 @@ NvmExpressPassThru (
|
||||||
//
|
//
|
||||||
if ((Event != NULL) && (QueueId != 0)) {
|
if ((Event != NULL) && (QueueId != 0)) {
|
||||||
Private->SqTdbl[QueueId].Sqt =
|
Private->SqTdbl[QueueId].Sqt =
|
||||||
(Private->SqTdbl[QueueId].Sqt + 1) % (NVME_ASYNC_CSQ_SIZE + 1);
|
(Private->SqTdbl[QueueId].Sqt + 1) % QueueSize;
|
||||||
} else {
|
} else {
|
||||||
Private->SqTdbl[QueueId].Sqt ^= 1;
|
Private->SqTdbl[QueueId].Sqt ^= 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue