[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 RESEND] xen: Fix SEGV on domain disconnect
From: |
mark.syms |
Subject: |
[PATCH v2 RESEND] xen: Fix SEGV on domain disconnect |
Date: |
Thu, 20 Apr 2023 12:02:05 +0100 |
From: Mark Syms <mark.syms@citrix.com>
Ensure the PV ring is drained on disconnect. Also ensure all pending
AIO is complete, otherwise AIO tries to complete into a mapping of the
ring which has been torn down.
Signed-off-by: Mark Syms <mark.syms@citrix.com>
---
CC: Stefano Stabellini <sstabellini@kernel.org>
CC: Anthony Perard <anthony.perard@citrix.com>
CC: Paul Durrant <paul@xen.org>
CC: xen-devel@lists.xenproject.org
v2:
* Ensure all inflight requests are completed before teardown
* RESEND to fix formatting
---
hw/block/dataplane/xen-block.c | 31 +++++++++++++++++++++++++------
1 file changed, 25 insertions(+), 6 deletions(-)
diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c
index 734da42ea7..d9da4090bf 100644
--- a/hw/block/dataplane/xen-block.c
+++ b/hw/block/dataplane/xen-block.c
@@ -523,6 +523,10 @@ static bool xen_block_handle_requests(XenBlockDataPlane
*dataplane)
dataplane->more_work = 0;
+ if (dataplane->sring == 0) {
+ return done_something;
+ }
+
rc = dataplane->rings.common.req_cons;
rp = dataplane->rings.common.sring->req_prod;
xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
@@ -666,14 +670,35 @@ void xen_block_dataplane_destroy(XenBlockDataPlane
*dataplane)
void xen_block_dataplane_stop(XenBlockDataPlane *dataplane)
{
XenDevice *xendev;
+ XenBlockRequest *request, *next;
if (!dataplane) {
return;
}
+ /* We're about to drain the ring. We can cancel the scheduling of any
+ * bottom half now */
+ qemu_bh_cancel(dataplane->bh);
+
+ /* Ensure we have drained the ring */
+ aio_context_acquire(dataplane->ctx);
+ do {
+ xen_block_handle_requests(dataplane);
+ } while (dataplane->more_work);
+ aio_context_release(dataplane->ctx);
+
+ /* Now ensure that all inflight requests are complete */
+ while (!QLIST_EMPTY(&dataplane->inflight)) {
+ QLIST_FOREACH_SAFE(request, &dataplane->inflight, list, next) {
+ blk_aio_flush(request->dataplane->blk, xen_block_complete_aio,
+ request);
+ }
+ }
+
xendev = dataplane->xendev;
aio_context_acquire(dataplane->ctx);
+
if (dataplane->event_channel) {
/* Only reason for failure is a NULL channel */
xen_device_set_event_channel_context(xendev, dataplane->event_channel,
@@ -684,12 +709,6 @@ void xen_block_dataplane_stop(XenBlockDataPlane *dataplane)
blk_set_aio_context(dataplane->blk, qemu_get_aio_context(), &error_abort);
aio_context_release(dataplane->ctx);
- /*
- * Now that the context has been moved onto the main thread, cancel
- * further processing.
- */
- qemu_bh_cancel(dataplane->bh);
-
if (dataplane->event_channel) {
Error *local_err = NULL;
--
2.40.0
- [PATCH v2 RESEND] xen: Fix SEGV on domain disconnect,
mark.syms <=