thebeanogamer / rpms / qemu-kvm

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