[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 41/64] hw/nvme: fix pin-based interrupt behavior (again)
From: |
Michael Roth |
Subject: |
[PATCH 41/64] hw/nvme: fix pin-based interrupt behavior (again) |
Date: |
Tue, 19 Oct 2021 09:09:21 -0500 |
From: Klaus Jensen <k.jensen@samsung.com>
Jakub noticed[1] that, when using pin-based interrupts, the device will
unconditionally deasssert when any CQEs are acknowledged. However, the
pin should not be deasserted if other completion queues still holds
unacknowledged CQEs.
The bug is an artifact of commit ca247d35098d ("hw/block/nvme: fix
pin-based interrupt behavior") which fixed one bug but introduced
another. This is the third time someone tries to fix pin-based
interrupts (see commit 5e9aa92eb1a5 ("hw/block: Fix pin-based interrupt
behaviour of NVMe"))...
Third time's the charm, so fix it, again, by keeping track of how many
CQs have unacknowledged CQEs and only deassert when all are cleared.
[1]: <20210610114624.304681-1-jakub.jermar@kernkonzept.com>
Cc: qemu-stable@nongnu.org
Fixes: ca247d35098d ("hw/block/nvme: fix pin-based interrupt behavior")
Reported-by: Jakub Jermář <jakub.jermar@kernkonzept.com>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
Reviewed-by: Keith Busch <kbusch@kernel.org>
(cherry picked from commit 83d7ed5c570d4c1d5163951b3057cac2ae7da4ff)
*avoid dependency on 88eea45c ("hw/nvme: move nvme emulation out of hw/block")
Signed-off-by: Michael Roth <michael.roth@amd.com>
---
hw/block/nvme.c | 18 +++++++++++++++++-
hw/block/nvme.h | 1 +
2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 8f4e1fc3ac..5b4892489e 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -469,7 +469,9 @@ static void nvme_irq_deassert(NvmeCtrl *n, NvmeCQueue *cq)
return;
} else {
assert(cq->vector < 32);
- n->irq_status &= ~(1 << cq->vector);
+ if (!n->cq_pending) {
+ n->irq_status &= ~(1 << cq->vector);
+ }
nvme_irq_check(n);
}
}
@@ -1262,6 +1264,7 @@ static void nvme_post_cqes(void *opaque)
NvmeCQueue *cq = opaque;
NvmeCtrl *n = cq->ctrl;
NvmeRequest *req, *next;
+ bool pending = cq->head != cq->tail;
int ret;
QTAILQ_FOREACH_SAFE(req, &cq->req_list, entry, next) {
@@ -1291,6 +1294,10 @@ static void nvme_post_cqes(void *opaque)
QTAILQ_INSERT_TAIL(&sq->req_list, req, entry);
}
if (cq->tail != cq->head) {
+ if (cq->irq_enabled && !pending) {
+ n->cq_pending++;
+ }
+
nvme_irq_assert(n, cq);
}
}
@@ -4091,6 +4098,11 @@ static uint16_t nvme_del_cq(NvmeCtrl *n, NvmeRequest
*req)
trace_pci_nvme_err_invalid_del_cq_notempty(qid);
return NVME_INVALID_QUEUE_DEL;
}
+
+ if (cq->irq_enabled && cq->tail != cq->head) {
+ n->cq_pending--;
+ }
+
nvme_irq_deassert(n, cq);
trace_pci_nvme_del_cq(qid);
nvme_free_cq(cq, n);
@@ -5768,6 +5780,10 @@ static void nvme_process_db(NvmeCtrl *n, hwaddr addr,
int val)
}
if (cq->tail == cq->head) {
+ if (cq->irq_enabled) {
+ n->cq_pending--;
+ }
+
nvme_irq_deassert(n, cq);
}
} else {
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
index 5d05ec368f..d216e5674d 100644
--- a/hw/block/nvme.h
+++ b/hw/block/nvme.h
@@ -171,6 +171,7 @@ typedef struct NvmeCtrl {
uint32_t max_q_ents;
uint8_t outstanding_aers;
uint32_t irq_status;
+ int cq_pending;
uint64_t host_timestamp; /* Timestamp sent by the host
*/
uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */
uint64_t starttime_ms;
--
2.25.1
- [PATCH 32/64] migration/tls: Use qcrypto_tls_creds_check_endpoint(), (continued)
- [PATCH 32/64] migration/tls: Use qcrypto_tls_creds_check_endpoint(), Michael Roth, 2021/10/19
- [PATCH 33/64] ui/vnc: Use qcrypto_tls_creds_check_endpoint(), Michael Roth, 2021/10/19
- [PATCH 34/64] crypto: Make QCryptoTLSCreds* structures private, Michael Roth, 2021/10/19
- [PATCH 35/64] yank: Unregister function when using TLS migration, Michael Roth, 2021/10/19
- [PATCH 36/64] tests: acpi: prepare for changing DSDT tables, Michael Roth, 2021/10/19
- [PATCH 37/64] acpi: pc: revert back to v5.2 PCI slot enumeration, Michael Roth, 2021/10/19
- [PATCH 38/64] tests: acpi: pc: update expected DSDT blobs, Michael Roth, 2021/10/19
- [PATCH 39/64] hw/block/nvme: align with existing style, Michael Roth, 2021/10/19
- [PATCH 40/64] hw/nvme: fix missing check for PMR capability, Michael Roth, 2021/10/19
- [PATCH 03/64] docs/system: Document the removal of "compat" property for POWER CPUs, Michael Roth, 2021/10/19
- [PATCH 41/64] hw/nvme: fix pin-based interrupt behavior (again),
Michael Roth <=
- [PATCH 42/64] virtio-balloon: don't start free page hinting if postcopy is possible, Michael Roth, 2021/10/19
- [PATCH 43/64] hw/net/can: sja1000 fix buff2frame_bas and buff2frame_pel when dlc is out of std CAN 8 bytes, Michael Roth, 2021/10/19
- [PATCH 44/64] hw/sd/sdcard: Document out-of-range addresses for SEND_WRITE_PROT, Michael Roth, 2021/10/19
- [PATCH 45/64] hw/sd/sdcard: Fix assertion accessing out-of-range addresses with CMD30, Michael Roth, 2021/10/19
- [PATCH 46/64] audio: Never send migration section, Michael Roth, 2021/10/19
- [PATCH 47/64] target/arm: Don't skip M-profile reset entirely in user mode, Michael Roth, 2021/10/19
- [PATCH 48/64] virtio-net: fix use after unmap/free for sg, Michael Roth, 2021/10/19
- [PATCH 49/64] qemu-nbd: Change default cache mode to writeback, Michael Roth, 2021/10/19
- [PATCH 50/64] hmp: Unbreak "change vnc", Michael Roth, 2021/10/19
- [PATCH 04/64] monitor/qmp: fix race on CHR_EVENT_CLOSED without OOB, Michael Roth, 2021/10/19