Commit 849ea354dd for qemu.org
commit 849ea354ddc1c9a4c2af03d57f75acf106ff6b45
Author: Minwoo Im <minwoo.im.dev@gmail.com>
Date: Wed Jul 29 19:34:53 2026 +0900
hw/nvme: factor out nvme_sq_cancel_inflight()
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: qemu-stable@nongnu.org
Signed-off-by: Minwoo Im <minwoo.im@samsung.com>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index e3eadf3d1d..e355c256a5 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];