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>
Minwoo Im committed
Jul 29, 2026 at 19:34 UTC
849ea354ddc1c9a4c2af03d57f75acf106ff6b45
1 file changed
+21
-10
hw/nvme/ctrl.c
+21
-10
@@ -4826,6 +4826,26 @@ static int nvme_init_sq_ioeventfd(NvmeSQueue *sq)
4826
return 0;
4827
}
4828
4829
+/*
4830
+ * A pending Async Event Request has no aiocb (nvme_aer() parks it without
4831
+ * issuing any block I/O), so there is nothing to cancel; just drop it.
4832
+ */
4833
+static void nvme_sq_cancel_inflight(NvmeSQueue *sq, uint16_t status)
4834
+{
4835
+ NvmeRequest *r;
4836
+
4837
+ while (!QTAILQ_EMPTY(&sq->out_req_list)) {
4838
+ r = QTAILQ_FIRST(&sq->out_req_list);
4839
+ r->status = status;
4840
+
4841
+ if (r->aiocb) {
4842
+ blk_aio_cancel(r->aiocb);
4843
+ } else {
4844
+ QTAILQ_REMOVE(&sq->out_req_list, r, entry);
4845
+ }
4846
+ }
4847
+}
4848
+
4849
static void nvme_free_sq(NvmeSQueue *sq, NvmeCtrl *n)
4850
{
4851
uint16_t offset = sq->sqid << 3;
@@ -4860,16 +4880,7 @@ static uint16_t nvme_del_sq(NvmeCtrl *n, NvmeRequest *req)
4880
trace_pci_nvme_del_sq(qid);
4881
4882
sq = n->sq[qid];
4863
- while (!QTAILQ_EMPTY(&sq->out_req_list)) {
4864
- r = QTAILQ_FIRST(&sq->out_req_list);
4865
- r->status = NVME_CMD_ABORT_SQ_DEL;
4866
-
4867
- if (r->aiocb) {
4868
- blk_aio_cancel(r->aiocb);
4869
- } else {
4870
- QTAILQ_REMOVE(&sq->out_req_list, r, entry);
4871
- }
4872
- }
4883
+ nvme_sq_cancel_inflight(sq, NVME_CMD_ABORT_SQ_DEL);
4884
4885
if (!nvme_check_cqid(n, sq->cqid)) {
4886
cq = n->cq[sq->cqid];