Blame SOURCES/kvm-block-Avoid-unnecessary-aio_poll-in-AIO_WAIT_WHILE.patch

26ba25
From 4f12612c2c25fb3093d1afa45030e424477344c7 Mon Sep 17 00:00:00 2001
26ba25
From: Kevin Wolf <kwolf@redhat.com>
26ba25
Date: Wed, 10 Oct 2018 20:08:40 +0100
26ba25
Subject: [PATCH 09/49] block: Avoid unnecessary aio_poll() in AIO_WAIT_WHILE()
26ba25
26ba25
RH-Author: Kevin Wolf <kwolf@redhat.com>
26ba25
Message-id: <20181010200843.6710-7-kwolf@redhat.com>
26ba25
Patchwork-id: 82586
26ba25
O-Subject: [RHEL-8 qemu-kvm PATCH 06/44] block: Avoid unnecessary aio_poll() in AIO_WAIT_WHILE()
26ba25
Bugzilla: 1637976
26ba25
RH-Acked-by: Max Reitz <mreitz@redhat.com>
26ba25
RH-Acked-by: John Snow <jsnow@redhat.com>
26ba25
RH-Acked-by: Thomas Huth <thuth@redhat.com>
26ba25
26ba25
Commit 91af091f923 added an additional aio_poll() to BDRV_POLL_WHILE()
26ba25
in order to make sure that all pending BHs are executed on drain. This
26ba25
was the wrong place to make the fix, as it is useless overhead for all
26ba25
other users of the macro and unnecessarily complicates the mechanism.
26ba25
26ba25
This patch effectively reverts said commit (the context has changed a
26ba25
bit and the code has moved to AIO_WAIT_WHILE()) and instead polls in the
26ba25
loop condition for drain.
26ba25
26ba25
The effect is probably hard to measure in any real-world use case
26ba25
because actual I/O will dominate, but if I run only the initialisation
26ba25
part of 'qemu-img convert' where it calls bdrv_block_status() for the
26ba25
whole image to find out how much data there is copy, this phase actually
26ba25
needs only roughly half the time after this patch.
26ba25
26ba25
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26ba25
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
26ba25
(cherry picked from commit 1cc8e54ada97f7ac479554e15ca9e426c895b158)
26ba25
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26ba25
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
26ba25
---
26ba25
 block/io.c               | 11 ++++++++++-
26ba25
 include/block/aio-wait.h | 22 ++++++++--------------
26ba25
 2 files changed, 18 insertions(+), 15 deletions(-)
26ba25
26ba25
diff --git a/block/io.c b/block/io.c
26ba25
index e5fc42c..4d332c3 100644
26ba25
--- a/block/io.c
26ba25
+++ b/block/io.c
26ba25
@@ -181,13 +181,22 @@ static void bdrv_drain_invoke(BlockDriverState *bs, bool begin)
26ba25
     BDRV_POLL_WHILE(bs, !data.done);
26ba25
 }
26ba25
 
26ba25
+/* Returns true if BDRV_POLL_WHILE() should go into a blocking aio_poll() */
26ba25
+static bool bdrv_drain_poll(BlockDriverState *bs)
26ba25
+{
26ba25
+    /* Execute pending BHs first and check everything else only after the BHs
26ba25
+     * have executed. */
26ba25
+    while (aio_poll(bs->aio_context, false));
26ba25
+    return atomic_read(&bs->in_flight);
26ba25
+}
26ba25
+
26ba25
 static bool bdrv_drain_recurse(BlockDriverState *bs)
26ba25
 {
26ba25
     BdrvChild *child, *tmp;
26ba25
     bool waited;
26ba25
 
26ba25
     /* Wait for drained requests to finish */
26ba25
-    waited = BDRV_POLL_WHILE(bs, atomic_read(&bs->in_flight) > 0);
26ba25
+    waited = BDRV_POLL_WHILE(bs, bdrv_drain_poll(bs));
26ba25
 
26ba25
     QLIST_FOREACH_SAFE(child, &bs->children, next, tmp) {
26ba25
         BlockDriverState *bs = child->bs;
26ba25
diff --git a/include/block/aio-wait.h b/include/block/aio-wait.h
26ba25
index 8c90a2e..783d367 100644
26ba25
--- a/include/block/aio-wait.h
26ba25
+++ b/include/block/aio-wait.h
26ba25
@@ -73,29 +73,23 @@ typedef struct {
26ba25
  */
26ba25
 #define AIO_WAIT_WHILE(wait, ctx, cond) ({                         \
26ba25
     bool waited_ = false;                                          \
26ba25
-    bool busy_ = true;                                             \
26ba25
     AioWait *wait_ = (wait);                                       \
26ba25
     AioContext *ctx_ = (ctx);                                      \
26ba25
     if (in_aio_context_home_thread(ctx_)) {                        \
26ba25
-        while ((cond) || busy_) {                                  \
26ba25
-            busy_ = aio_poll(ctx_, (cond));                        \
26ba25
-            waited_ |= !!(cond) | busy_;                           \
26ba25
+        while ((cond)) {                                           \
26ba25
+            aio_poll(ctx_, true);                                  \
26ba25
+            waited_ = true;                                        \
26ba25
         }                                                          \
26ba25
     } else {                                                       \
26ba25
         assert(qemu_get_current_aio_context() ==                   \
26ba25
                qemu_get_aio_context());                            \
26ba25
         /* Increment wait_->num_waiters before evaluating cond. */ \
26ba25
         atomic_inc(&wait_->num_waiters);                           \
26ba25
-        while (busy_) {                                            \
26ba25
-            if ((cond)) {                                          \
26ba25
-                waited_ = busy_ = true;                            \
26ba25
-                aio_context_release(ctx_);                         \
26ba25
-                aio_poll(qemu_get_aio_context(), true);            \
26ba25
-                aio_context_acquire(ctx_);                         \
26ba25
-            } else {                                               \
26ba25
-                busy_ = aio_poll(ctx_, false);                     \
26ba25
-                waited_ |= busy_;                                  \
26ba25
-            }                                                      \
26ba25
+        while ((cond)) {                                           \
26ba25
+            aio_context_release(ctx_);                             \
26ba25
+            aio_poll(qemu_get_aio_context(), true);                \
26ba25
+            aio_context_acquire(ctx_);                             \
26ba25
+            waited_ = true;                                        \
26ba25
         }                                                          \
26ba25
         atomic_dec(&wait_->num_waiters);                           \
26ba25
     }                                                              \
26ba25
-- 
26ba25
1.8.3.1
26ba25