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

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