@samitouri / QOSamiQemu / commits / 849ea354dd

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];