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)
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 */