All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: famz@redhat.com, stefanha@redhat.com
Subject: [Qemu-devel] [PATCH v2 07/16] block: change drain to look only at one child at a time
Date: Wed, 16 Mar 2016 15:16:48 +0100	[thread overview]
Message-ID: <1458137817-15383-8-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1458137817-15383-1-git-send-email-pbonzini@redhat.com>

bdrv_requests_pending is checking children to also wait until internal
requests (such as metadata writes) have completed.  However, checking
children is in general overkill.  Children requests can be of two kinds:

- requests caused by an operation on bs, e.g. a bdrv_aio_write to bs
causing a write to bs->file->bs.  In this case, the parent's in_flight
count will always be incremented by at least one for every request in
the child.

- asynchronous metadata writes or flushes.  Such writes can be started
even if bs's in_flight count is zero, but not after the .bdrv_drain
callback has been invoked.

This patch therefore changes bdrv_drain to finish I/O in the parent
(after which the parent's in_flight will be locked to zero), call
bdrv_drain (after which the parent will not generate I/O on the child
anymore), and then wait for internal I/O in the children to complete.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
	v1->v2: moved bdrv_drain callback after in_flight is 0
	in the parent [from QED drain discussion]
	  
 block/io.c | 25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/block/io.c b/block/io.c
index a9a23a6..db975ab 100644
--- a/block/io.c
+++ b/block/io.c
@@ -237,16 +237,25 @@ bool bdrv_requests_pending(BlockDriverState *bs)
     return false;
 }
 
-static void bdrv_drain_recurse(BlockDriverState *bs)
+static bool bdrv_drain_io_recurse(BlockDriverState *bs)
 {
     BdrvChild *child;
+    bool waited = false;
+
+    while (atomic_read(&bs->in_flight) > 0) {
+        aio_poll(bdrv_get_aio_context(bs), true);
+        waited = true;
+    }
 
     if (bs->drv && bs->drv->bdrv_drain) {
         bs->drv->bdrv_drain(bs);
     }
+
     QLIST_FOREACH(child, &bs->children, next) {
-        bdrv_drain_recurse(child->bs);
+        waited |= bdrv_drain_io_recurse(child->bs);
     }
+
+    return waited;
 }
 
 /*
@@ -264,11 +273,7 @@ void bdrv_drain(BlockDriverState *bs)
 {
     bdrv_no_throttling_begin(bs);
     bdrv_io_unplugged_begin(bs);
-    bdrv_drain_recurse(bs);
-    while (bdrv_requests_pending(bs)) {
-        /* Keep iterating */
-         aio_poll(bdrv_get_aio_context(bs), true);
-    }
+    bdrv_drain_io_recurse(bs);
     bdrv_io_unplugged_end(bs);
     bdrv_no_throttling_end(bs);
 }
@@ -295,7 +300,6 @@ void bdrv_drain_all(void)
         }
         bdrv_no_throttling_begin(bs);
         bdrv_io_unplugged_begin(bs);
-        bdrv_drain_recurse(bs);
         aio_context_release(aio_context);
 
         if (!g_slist_find(aio_ctxs, aio_context)) {
@@ -319,10 +323,7 @@ void bdrv_drain_all(void)
             aio_context_acquire(aio_context);
             while ((bs = bdrv_next(bs))) {
                 if (aio_context == bdrv_get_aio_context(bs)) {
-                    if (bdrv_requests_pending(bs)) {
-                        aio_poll(aio_context, true);
-                        waited = true;
-                    }
+                    waited |= bdrv_drain_io_recurse(bs);
                 }
             }
             aio_context_release(aio_context);
-- 
1.8.3.1

  parent reply	other threads:[~2016-03-16 14:17 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-16 14:16 [Qemu-devel] [PATCH v2 00/16] AioContext fine-grained locking, part 1 of 3, including bdrv_drain rewrite Paolo Bonzini
2016-03-16 14:16 ` [Qemu-devel] [PATCH v2 01/16] block: make bdrv_start_throttled_reqs return void Paolo Bonzini
2016-03-16 14:16 ` [Qemu-devel] [PATCH v2 02/16] block: move restarting of throttled reqs to block/throttle-groups.c Paolo Bonzini
2016-03-17  2:39   ` Fam Zheng
2016-03-16 14:16 ` [Qemu-devel] [PATCH v2 03/16] block: introduce bdrv_no_throttling_begin/end Paolo Bonzini
2016-03-17  2:52   ` Fam Zheng
2016-03-16 14:16 ` [Qemu-devel] [PATCH v2 04/16] block: plug whole tree at once, introduce bdrv_io_unplugged_begin/end Paolo Bonzini
2016-03-16 14:16 ` [Qemu-devel] [PATCH v2 05/16] mirror: use bottom half to re-enter coroutine Paolo Bonzini
2016-03-17  2:23   ` Fam Zheng
2016-03-16 14:16 ` [Qemu-devel] [PATCH v2 06/16] block: add BDS field to count in-flight requests Paolo Bonzini
2016-03-17  2:53   ` Fam Zheng
2016-03-16 14:16 ` Paolo Bonzini [this message]
2016-03-17  3:10   ` [Qemu-devel] [PATCH v2 07/16] block: change drain to look only at one child at a time Fam Zheng
2016-03-16 14:16 ` [Qemu-devel] [PATCH v2 08/16] blockjob: introduce .drain callback for jobs Paolo Bonzini
2016-03-16 14:16 ` [Qemu-devel] [PATCH v2 09/16] block: wait for all pending I/O when doing synchronous requests Paolo Bonzini
2016-03-17  2:55   ` Fam Zheng
2016-03-16 14:16 ` [Qemu-devel] [PATCH v2 10/16] nfs: replace aio_poll with bdrv_drain Paolo Bonzini
2016-03-16 14:16 ` [Qemu-devel] [PATCH v2 11/16] sheepdog: disable dataplane Paolo Bonzini
2016-03-23 10:45   ` Kevin Wolf
2016-03-23 11:07     ` Paolo Bonzini
2016-03-16 14:16 ` [Qemu-devel] [PATCH v2 12/16] aio: introduce aio_context_in_iothread Paolo Bonzini
2016-03-16 14:16 ` [Qemu-devel] [PATCH v2 13/16] block: only call aio_poll from iothread Paolo Bonzini
2016-03-16 14:16 ` [Qemu-devel] [PATCH v2 14/16] iothread: release AioContext around aio_poll Paolo Bonzini
2016-03-16 14:16 ` [Qemu-devel] [PATCH v2 15/16] qemu-thread: introduce QemuRecMutex Paolo Bonzini
2016-03-16 14:16 ` [Qemu-devel] [PATCH v2 16/16] aio: convert from RFifoLock to QemuRecMutex Paolo Bonzini
2016-03-18 16:03 ` [Qemu-devel] [PATCH v2 00/16] AioContext fine-grained locking, part 1 of 3, including bdrv_drain rewrite Stefan Hajnoczi

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=1458137817-15383-8-git-send-email-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=famz@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /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.