[PULL 2/4] hw/nvme: factor out nvme_sq_cancel_inflight()
Klaus Jensen <[email protected]> Mon, 3 Aug 2026 15:44:33 -0700
| Newsgroups | org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
From: Minwoo Im <[email protected]> Factor the cancel-and-wait loop used by nvme_del_sq() into nvme_sq_cancel_inflight(), so it can be reused to drain queues on controller reset. Cc: [email protected] Signed-off-by: Minwoo Im <[email protected]> Signed-off-by: Klaus Jensen <[email protected]> --- hw/nvme/ctrl.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c index e3eadf3d1dd0..e355c256a561 100644 --- a/hw/nvme/ctrl.c +++ b/hw/nvme/ctrl.c @@ -4826,6 +4826,26 @@ static int nvme_init_sq_ioeventfd(NvmeSQueue *sq) return 0; } +/* + * A pending Async Event Request has no aiocb (nvme_aer() parks it without + * issuing any block I/O), so there is nothing to cancel; just drop it. + */ +static void nvme_sq_cancel_inflight(NvmeSQueue *sq, uint16_t status) +{ + NvmeRequest *r; + + while (!QTAILQ_EMPTY(&sq->out_req_list)) { + r = QTAILQ_FIRST(&sq->out_req_list); + r->status = status; + + if (r->aiocb) { + blk_aio_cancel(r->aiocb); + } else { + QTAILQ_REMOVE(&sq->out_req_list, r, entry); + } + } +} + static void nvme_free_sq(NvmeSQueue *sq, NvmeCtrl *n) { uint16_t offset = sq->sqid << 3; @@ -4860,16 +4880,7 @@ static uint16_t nvme_del_sq(NvmeCtrl *n, NvmeRequest *req) trace_pci_nvme_del_sq(qid); sq = n->sq[qid]; - while (!QTAILQ_EMPTY(&sq->out_req_list)) { - r = QTAILQ_FIRST(&sq->out_req_list); - r->status = NVME_CMD_ABORT_SQ_DEL; - - if (r->aiocb) { - blk_aio_cancel(r->aiocb); - } else { - QTAILQ_REMOVE(&sq->out_req_list, r, entry); - } - } + nvme_sq_cancel_inflight(sq, NVME_CMD_ABORT_SQ_DEL); if (!nvme_check_cqid(n, sq->cqid)) { cq = n->cq[sq->cqid]; -- 2.53.0