From: Minwoo Im <[email protected]> nvme_del_sq() asserted r->aiocb was always set when canceling a queue's inflight requests. A pending Async Event Request has no aiocb (nvme_aer() parks it without issuing any block I/O), so deleting a queue with an outstanding AER trips the assert instead of just dropping the request.
Cc: [email protected] Signed-off-by: Minwoo Im <[email protected]> Signed-off-by: Klaus Jensen <[email protected]> (cherry picked from commit 1d5e53df1674e0e45be50a4a873e6deede2eecd7) Signed-off-by: Michael Tokarev <[email protected]> diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c index e478e92d505..b17dd752260 100644 --- a/hw/nvme/ctrl.c +++ b/hw/nvme/ctrl.c @@ -4841,12 +4841,14 @@ static uint16_t nvme_del_sq(NvmeCtrl *n, NvmeRequest *req) sq = n->sq[qid]; while (!QTAILQ_EMPTY(&sq->out_req_list)) { r = QTAILQ_FIRST(&sq->out_req_list); - assert(r->aiocb); r->status = NVME_CMD_ABORT_SQ_DEL; - blk_aio_cancel(r->aiocb); - } - assert(QTAILQ_EMPTY(&sq->out_req_list)); + if (r->aiocb) { + blk_aio_cancel(r->aiocb); + } else { + QTAILQ_REMOVE(&sq->out_req_list, r, entry); + } + } if (!nvme_check_cqid(n, sq->cqid)) { cq = n->cq[sq->cqid]; -- 2.47.3
