Blob Blame Raw
From cf6bc30f7b525f0d646db62e49cbf02f3f28a1f2 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <>
Date: Wed, 14 Aug 2019 08:42:29 +0100
Subject: [PATCH 06/10] block: Use normal drain for bdrv_set_aio_context()

RH-Author: Kevin Wolf <>
Message-id: <>
Patchwork-id: 89968
O-Subject: [RHEL-8.1.0 qemu-kvm PATCH 5/5] block: Use normal drain for bdrv_set_aio_context()
Bugzilla: 1716349
RH-Acked-by: Stefan Hajnoczi <>
RH-Acked-by: Max Reitz <>
RH-Acked-by: Paolo Bonzini <>

Now that bdrv_set_aio_context() works inside drained sections, it can
also use the real drain function instead of open coding something

Signed-off-by: Kevin Wolf <>
(cherry picked from commit d70d595429ecd9ac4917e53453dd8979db8e5ffd)

RHEL: This conflicts because we didn't backport the removal of the
polling loop. The conflict is resolved so that the polling loop moves to
above the drain and any requests a BH would spawn would still be
correctly drained afterwards. The changed order alone would have
compensated for the virtio-blk bug and it potentially compensates for
other bugs, too (we know of bugs in the NBD client at least), so leaving
the polling loop in, with the new ordering, feels like the safe way for
a downstream backport.

Signed-off-by: Kevin Wolf <>
Signed-off-by: Danilo C. L. de Paula <>
 block.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/block.c b/block.c
index 9d9b8a9..8f3ceea 100644
--- a/block.c
+++ b/block.c
@@ -4989,18 +4989,18 @@ void bdrv_attach_aio_context(BlockDriverState *bs,
     bs->walking_aio_notifiers = false;
+/* The caller must own the AioContext lock for the old AioContext of bs, but it
+ * must not own the AioContext lock for new_context (unless new_context is
+ * the same as the current context of bs). */
 void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
     AioContext *ctx = bdrv_get_aio_context(bs);
-    aio_disable_external(ctx);
-    bdrv_parent_drained_begin(bs, NULL, false);
-    bdrv_drain(bs); /* ensure there are no in-flight requests */
     while (aio_poll(ctx, false)) {
         /* wait for all bottom halves to execute */
+    bdrv_drained_begin(bs);
     /* This function executes in the old AioContext so acquire the new one in
@@ -5008,8 +5008,7 @@ void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
     bdrv_attach_aio_context(bs, new_context);
-    bdrv_parent_drained_end(bs, NULL, false);
-    aio_enable_external(ctx);
+    bdrv_drained_end(bs);