thebeanogamer / rpms / qemu-kvm

Forked from rpms/qemu-kvm 5 months ago
Clone
ed5979
From ad52cb621daad45d3c2a0e2e670d6ca2e16690bd Mon Sep 17 00:00:00 2001
ed5979
From: Kevin Wolf <kwolf@redhat.com>
ed5979
Date: Fri, 18 Nov 2022 18:41:02 +0100
ed5979
Subject: [PATCH 20/31] block: Drain individual nodes during reopen
ed5979
ed5979
RH-Author: Stefano Garzarella <sgarzare@redhat.com>
ed5979
RH-MergeRequest: 135: block: Simplify drain to prevent QEMU from crashing during snapshot
ed5979
RH-Bugzilla: 2155112
ed5979
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
ed5979
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
ed5979
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
ed5979
RH-Commit: [8/16] 5441b6f0ae9102ef40d1093e1db3084eea81e3b0 (sgarzarella/qemu-kvm-c-9-s)
ed5979
ed5979
bdrv_reopen() and friends use subtree drains as a lazy way of covering
ed5979
all the nodes they touch. Turns out that this lazy way is a lot more
ed5979
complicated than just draining the nodes individually, even not
ed5979
accounting for the additional complexity in the drain mechanism itself.
ed5979
ed5979
Simplify the code by switching to draining the individual nodes that are
ed5979
already managed in the BlockReopenQueue anyway.
ed5979
ed5979
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
ed5979
Message-Id: <20221118174110.55183-8-kwolf@redhat.com>
ed5979
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
ed5979
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
ed5979
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
ed5979
(cherry picked from commit d22933acd2f470eeef779e4d444e848f76dcfaf8)
ed5979
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
ed5979
---
ed5979
 block.c             | 16 +++++++++-------
ed5979
 block/replication.c |  6 ------
ed5979
 blockdev.c          | 13 -------------
ed5979
 3 files changed, 9 insertions(+), 26 deletions(-)
ed5979
ed5979
diff --git a/block.c b/block.c
ed5979
index 46df410b07..cb5e96b1cf 100644
ed5979
--- a/block.c
ed5979
+++ b/block.c
ed5979
@@ -4150,7 +4150,7 @@ static bool bdrv_recurse_has_child(BlockDriverState *bs,
ed5979
  * returns a pointer to bs_queue, which is either the newly allocated
ed5979
  * bs_queue, or the existing bs_queue being used.
ed5979
  *
ed5979
- * bs must be drained between bdrv_reopen_queue() and bdrv_reopen_multiple().
ed5979
+ * bs is drained here and undrained by bdrv_reopen_queue_free().
ed5979
  *
ed5979
  * To be called with bs->aio_context locked.
ed5979
  */
ed5979
@@ -4172,12 +4172,10 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
ed5979
     int flags;
ed5979
     QemuOpts *opts;
ed5979
 
ed5979
-    /* Make sure that the caller remembered to use a drained section. This is
ed5979
-     * important to avoid graph changes between the recursive queuing here and
ed5979
-     * bdrv_reopen_multiple(). */
ed5979
-    assert(bs->quiesce_counter > 0);
ed5979
     GLOBAL_STATE_CODE();
ed5979
 
ed5979
+    bdrv_drained_begin(bs);
ed5979
+
ed5979
     if (bs_queue == NULL) {
ed5979
         bs_queue = g_new0(BlockReopenQueue, 1);
ed5979
         QTAILQ_INIT(bs_queue);
ed5979
@@ -4328,6 +4326,12 @@ void bdrv_reopen_queue_free(BlockReopenQueue *bs_queue)
ed5979
     if (bs_queue) {
ed5979
         BlockReopenQueueEntry *bs_entry, *next;
ed5979
         QTAILQ_FOREACH_SAFE(bs_entry, bs_queue, entry, next) {
ed5979
+            AioContext *ctx = bdrv_get_aio_context(bs_entry->state.bs);
ed5979
+
ed5979
+            aio_context_acquire(ctx);
ed5979
+            bdrv_drained_end(bs_entry->state.bs);
ed5979
+            aio_context_release(ctx);
ed5979
+
ed5979
             qobject_unref(bs_entry->state.explicit_options);
ed5979
             qobject_unref(bs_entry->state.options);
ed5979
             g_free(bs_entry);
ed5979
@@ -4475,7 +4479,6 @@ int bdrv_reopen(BlockDriverState *bs, QDict *opts, bool keep_old_opts,
ed5979
 
ed5979
     GLOBAL_STATE_CODE();
ed5979
 
ed5979
-    bdrv_subtree_drained_begin(bs);
ed5979
     queue = bdrv_reopen_queue(NULL, bs, opts, keep_old_opts);
ed5979
 
ed5979
     if (ctx != qemu_get_aio_context()) {
ed5979
@@ -4486,7 +4489,6 @@ int bdrv_reopen(BlockDriverState *bs, QDict *opts, bool keep_old_opts,
ed5979
     if (ctx != qemu_get_aio_context()) {
ed5979
         aio_context_acquire(ctx);
ed5979
     }
ed5979
-    bdrv_subtree_drained_end(bs);
ed5979
 
ed5979
     return ret;
ed5979
 }
ed5979
diff --git a/block/replication.c b/block/replication.c
ed5979
index f1eed25e43..c62f48a874 100644
ed5979
--- a/block/replication.c
ed5979
+++ b/block/replication.c
ed5979
@@ -374,9 +374,6 @@ static void reopen_backing_file(BlockDriverState *bs, bool writable,
ed5979
         s->orig_secondary_read_only = bdrv_is_read_only(secondary_disk->bs);
ed5979
     }
ed5979
 
ed5979
-    bdrv_subtree_drained_begin(hidden_disk->bs);
ed5979
-    bdrv_subtree_drained_begin(secondary_disk->bs);
ed5979
-
ed5979
     if (s->orig_hidden_read_only) {
ed5979
         QDict *opts = qdict_new();
ed5979
         qdict_put_bool(opts, BDRV_OPT_READ_ONLY, !writable);
ed5979
@@ -401,9 +398,6 @@ static void reopen_backing_file(BlockDriverState *bs, bool writable,
ed5979
             aio_context_acquire(ctx);
ed5979
         }
ed5979
     }
ed5979
-
ed5979
-    bdrv_subtree_drained_end(hidden_disk->bs);
ed5979
-    bdrv_subtree_drained_end(secondary_disk->bs);
ed5979
 }
ed5979
 
ed5979
 static void backup_job_cleanup(BlockDriverState *bs)
ed5979
diff --git a/blockdev.c b/blockdev.c
ed5979
index 3f1dec6242..8ffb3d9537 100644
ed5979
--- a/blockdev.c
ed5979
+++ b/blockdev.c
ed5979
@@ -3547,8 +3547,6 @@ fail:
ed5979
 void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp)
ed5979
 {
ed5979
     BlockReopenQueue *queue = NULL;
ed5979
-    GSList *drained = NULL;
ed5979
-    GSList *p;
ed5979
 
ed5979
     /* Add each one of the BDS that we want to reopen to the queue */
ed5979
     for (; reopen_list != NULL; reopen_list = reopen_list->next) {
ed5979
@@ -3585,9 +3583,7 @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp)
ed5979
         ctx = bdrv_get_aio_context(bs);
ed5979
         aio_context_acquire(ctx);
ed5979
 
ed5979
-        bdrv_subtree_drained_begin(bs);
ed5979
         queue = bdrv_reopen_queue(queue, bs, qdict, false);
ed5979
-        drained = g_slist_prepend(drained, bs);
ed5979
 
ed5979
         aio_context_release(ctx);
ed5979
     }
ed5979
@@ -3598,15 +3594,6 @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp)
ed5979
 
ed5979
 fail:
ed5979
     bdrv_reopen_queue_free(queue);
ed5979
-    for (p = drained; p; p = p->next) {
ed5979
-        BlockDriverState *bs = p->data;
ed5979
-        AioContext *ctx = bdrv_get_aio_context(bs);
ed5979
-
ed5979
-        aio_context_acquire(ctx);
ed5979
-        bdrv_subtree_drained_end(bs);
ed5979
-        aio_context_release(ctx);
ed5979
-    }
ed5979
-    g_slist_free(drained);
ed5979
 }
ed5979
 
ed5979
 void qmp_blockdev_del(const char *node_name, Error **errp)
ed5979
-- 
ed5979
2.31.1
ed5979