]> www.infradead.org Git - qemu-nvme.git/commitdiff
hw/nvme: also start sqs on notify
authorKlaus Jensen <k.jensen@samsung.com>
Tue, 7 Feb 2023 13:37:25 +0000 (14:37 +0100)
committerKlaus Jensen <k.jensen@samsung.com>
Thu, 8 Jun 2023 11:32:05 +0000 (13:32 +0200)
When using ioeventfd for mmio, if the updated completion queue was
previously full, make sure associated submission queues are queued up
for precessing.

Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
hw/nvme/ctrl.c

index 920f7087d30fa79fb086bb0cfe7c0f6950b7ecdc..42955a081e10844533c01820b6f8e57664d1ed9f 100644 (file)
@@ -4466,26 +4466,43 @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeRequest *req)
     return NVME_INVALID_OPCODE | NVME_DNR;
 }
 
-static void nvme_cq_notifier(EventNotifier *e)
+static void nvme_cq_update(NvmeCQueue *cq, bool start_sqs)
 {
-    NvmeCQueue *cq = container_of(e, NvmeCQueue, notifier);
-    NvmeCtrl *n = cq->ctrl;
+    if (start_sqs) {
+        NvmeSQueue *sq;
 
-    if (!event_notifier_test_and_clear(e)) {
-        return;
+        /* cq was full; start processing sqes on affected sqs again */
+        QTAILQ_FOREACH(sq, &cq->sq_list, entry) {
+            qemu_bh_schedule(sq->bh);
+        }
+
+        /* if no sq has pending sqes, make sure any pending cqes are posted */
+        qemu_bh_schedule(cq->bh);
     }
 
-    nvme_update_cq_head(cq);
 
     if (nvme_cq_empty(cq)) {
+        NvmeCtrl *n = cq->ctrl;
+
         if (cq->irq_enabled) {
             n->cq_pending--;
         }
 
         nvme_irq_deassert(n, cq);
     }
+}
 
-    qemu_bh_schedule(cq->bh);
+static void nvme_cq_notifier(EventNotifier *e)
+{
+    NvmeCQueue *cq = container_of(e, NvmeCQueue, notifier);
+    bool start_sqs = nvme_cq_full(cq);
+
+    if (!event_notifier_test_and_clear(e)) {
+        return;
+    }
+
+    nvme_update_cq_head(cq);
+    nvme_cq_update(cq, start_sqs);
 }
 
 static int nvme_init_cq_ioeventfd(NvmeCQueue *cq)
@@ -7636,21 +7653,8 @@ static void nvme_process_db(NvmeCtrl *n, hwaddr addr, int val)
         if (!qid && n->dbbuf_enabled) {
             pci_dma_write(pci, cq->db_addr, &cq->head, sizeof(cq->head));
         }
-        if (start_sqs) {
-            NvmeSQueue *sq;
-            QTAILQ_FOREACH(sq, &cq->sq_list, entry) {
-                qemu_bh_schedule(sq->bh);
-            }
-            qemu_bh_schedule(cq->bh);
-        }
 
-        if (nvme_cq_empty(cq)) {
-            if (cq->irq_enabled) {
-                n->cq_pending--;
-            }
-
-            nvme_irq_deassert(n, cq);
-        }
+        nvme_cq_update(cq, start_sqs);
     } else {
         /* Submission queue doorbell write */