All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: qemu-block@nongnu.org
Cc: kwolf@redhat.com, qemu-devel@nongnu.org
Subject: [Qemu-devel] [PULL 04/14] block: Make bdrv_drain_invoke() recursive
Date: Wed, 20 Dec 2017 14:19:29 +0100	[thread overview]
Message-ID: <20171220131939.27543-5-kwolf@redhat.com> (raw)
In-Reply-To: <20171220131939.27543-1-kwolf@redhat.com>

This change separates bdrv_drain_invoke(), which calls the BlockDriver
drain callbacks, from bdrv_drain_recurse(). Instead, the function
performs its own recursion now.

One reason for this is that bdrv_drain_recurse() can be called multiple
times by bdrv_drain_all_begin(), but the callbacks may only be called
once. The separation is necessary to fix this bug.

The other reason is that we intend to go to a model where we call all
driver callbacks first, and only then start polling. This is not fully
achieved yet with this patch, as bdrv_drain_invoke() contains a
BDRV_POLL_WHILE() loop for the block driver callbacks, which can still
call callbacks for any unrelated event. It's a step in this direction
anyway.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 block/io.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/block/io.c b/block/io.c
index 6773926fc1..096468b761 100644
--- a/block/io.c
+++ b/block/io.c
@@ -175,8 +175,10 @@ static void coroutine_fn bdrv_drain_invoke_entry(void *opaque)
     bdrv_wakeup(bs);
 }
 
+/* Recursively call BlockDriver.bdrv_co_drain_begin/end callbacks */
 static void bdrv_drain_invoke(BlockDriverState *bs, bool begin)
 {
+    BdrvChild *child, *tmp;
     BdrvCoDrainData data = { .bs = bs, .done = false, .begin = begin};
 
     if (!bs->drv || (begin && !bs->drv->bdrv_co_drain_begin) ||
@@ -187,6 +189,10 @@ static void bdrv_drain_invoke(BlockDriverState *bs, bool begin)
     data.co = qemu_coroutine_create(bdrv_drain_invoke_entry, &data);
     bdrv_coroutine_enter(bs, data.co);
     BDRV_POLL_WHILE(bs, !data.done);
+
+    QLIST_FOREACH_SAFE(child, &bs->children, next, tmp) {
+        bdrv_drain_invoke(child->bs, begin);
+    }
 }
 
 static bool bdrv_drain_recurse(BlockDriverState *bs, bool begin)
@@ -194,9 +200,6 @@ static bool bdrv_drain_recurse(BlockDriverState *bs, bool begin)
     BdrvChild *child, *tmp;
     bool waited;
 
-    /* Ensure any pending metadata writes are submitted to bs->file.  */
-    bdrv_drain_invoke(bs, begin);
-
     /* Wait for drained requests to finish */
     waited = BDRV_POLL_WHILE(bs, atomic_read(&bs->in_flight) > 0);
 
@@ -279,6 +282,7 @@ void bdrv_drained_begin(BlockDriverState *bs)
         bdrv_parent_drained_begin(bs);
     }
 
+    bdrv_drain_invoke(bs, true);
     bdrv_drain_recurse(bs, true);
 }
 
@@ -294,6 +298,7 @@ void bdrv_drained_end(BlockDriverState *bs)
     }
 
     bdrv_parent_drained_end(bs);
+    bdrv_drain_invoke(bs, false);
     bdrv_drain_recurse(bs, false);
     aio_enable_external(bdrv_get_aio_context(bs));
 }
@@ -372,6 +377,8 @@ void bdrv_drain_all_begin(void)
             aio_context_acquire(aio_context);
             for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
                 if (aio_context == bdrv_get_aio_context(bs)) {
+                    /* FIXME Calling this multiple times is wrong */
+                    bdrv_drain_invoke(bs, true);
                     waited |= bdrv_drain_recurse(bs, true);
                 }
             }
@@ -393,6 +400,7 @@ void bdrv_drain_all_end(void)
         aio_context_acquire(aio_context);
         aio_enable_external(aio_context);
         bdrv_parent_drained_end(bs);
+        bdrv_drain_invoke(bs, false);
         bdrv_drain_recurse(bs, false);
         aio_context_release(aio_context);
     }
-- 
2.13.6

  parent reply	other threads:[~2017-12-20 13:20 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-20 13:19 [Qemu-devel] [PULL 00/14] Block layer patches Kevin Wolf
2017-12-20 13:19 ` [Qemu-devel] [PULL 01/14] hw/block/nvme: Convert to realize Kevin Wolf
2017-12-20 13:19 ` [Qemu-devel] [PULL 02/14] block: Formats don't need CONSISTENT_READ with NO_IO Kevin Wolf
2017-12-20 13:19 ` [Qemu-devel] [PULL 03/14] iotests: fix 197 for vpc Kevin Wolf
2017-12-20 13:19 ` Kevin Wolf [this message]
2017-12-20 13:19 ` [Qemu-devel] [PULL 05/14] block: Call .drain_begin only once in bdrv_drain_all_begin() Kevin Wolf
2017-12-20 13:19 ` [Qemu-devel] [PULL 06/14] test-bdrv-drain: Test BlockDriver callbacks for drain Kevin Wolf
2017-12-20 13:19 ` [Qemu-devel] [PULL 07/14] block: bdrv_drain_recurse(): Remove unused begin parameter Kevin Wolf
2017-12-20 13:19 ` [Qemu-devel] [PULL 08/14] block: Don't wait for requests in bdrv_drain*_end() Kevin Wolf
2017-12-20 13:19 ` [Qemu-devel] [PULL 09/14] block: Unify order in drain functions Kevin Wolf
2017-12-20 13:19 ` [Qemu-devel] [PULL 10/14] qemu-img: Document --force-share / -U Kevin Wolf
2017-12-20 13:19 ` [Qemu-devel] [PULL 11/14] block: Don't acquire AioContext in hmp_qemu_io() Kevin Wolf
2017-12-20 13:19 ` [Qemu-devel] [PULL 12/14] qcow2: get rid of qcow2_backing_read1 routine Kevin Wolf
2017-12-20 13:19 ` [Qemu-devel] [PULL 13/14] block: Document that x-blockdev-change breaks quorum children list Kevin Wolf
2017-12-20 13:19 ` [Qemu-devel] [PULL 14/14] nvme: Add tracing Kevin Wolf
2017-12-20 15:30 ` [Qemu-devel] [PULL 00/14] Block layer patches Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171220131939.27543-5-kwolf@redhat.com \
    --to=kwolf@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.