[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 07/16] block: change drain to look only at one child
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PATCH 07/16] block: change drain to look only at one child at a time |
Date: |
Tue, 16 Feb 2016 18:56:19 +0100 |
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 because, apart from this special case,
the parent's in_flight count will always be incremented by at least one
for every request in the child.
Since internal requests are only generated by the parent in the child,
instead visit the tree parent first, and then wait for internal I/O in
the children to complete.
Signed-off-by: Paolo Bonzini <address@hidden>
---
block/io.c | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/block/io.c b/block/io.c
index a9a23a6..e0c9215 100644
--- a/block/io.c
+++ b/block/io.c
@@ -249,6 +249,23 @@ 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;
+ }
+
+ QLIST_FOREACH(child, &bs->children, next) {
+ waited |= bdrv_drain_io_recurse(child->bs);
+ }
+
+ return waited;
+}
+
/*
* Wait for pending requests to complete on a single BlockDriverState subtree,
* and suspend block driver's internal I/O until next request arrives.
@@ -265,10 +282,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);
}
@@ -319,10 +333,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);
--
2.5.0
- [Qemu-devel] [PATCH 00/16] AioContext fine-grained locking, part 1 of 3, including bdrv_drain rewrite, Paolo Bonzini, 2016/02/16
- [Qemu-devel] [PATCH 01/16] block: make bdrv_start_throttled_reqs return void, Paolo Bonzini, 2016/02/16
- [Qemu-devel] [PATCH 03/16] block: introduce bdrv_no_throttling_begin/end, Paolo Bonzini, 2016/02/16
- [Qemu-devel] [PATCH 02/16] block: move restarting of throttled reqs to block/throttle-groups.c, Paolo Bonzini, 2016/02/16
- [Qemu-devel] [PATCH 04/16] block: plug whole tree at once, introduce bdrv_io_unplugged_begin/end, Paolo Bonzini, 2016/02/16
- [Qemu-devel] [PATCH 07/16] block: change drain to look only at one child at a time,
Paolo Bonzini <=
- [Qemu-devel] [PATCH 05/16] mirror: use bottom half to re-enter coroutine, Paolo Bonzini, 2016/02/16
- [Qemu-devel] [PATCH 06/16] block: add BDS field to count in-flight requests, Paolo Bonzini, 2016/02/16
- [Qemu-devel] [PATCH 08/16] blockjob: introduce .drain callback for jobs, Paolo Bonzini, 2016/02/16
- [Qemu-devel] [PATCH 09/16] block: wait for all pending I/O when doing synchronous requests, Paolo Bonzini, 2016/02/16
- [Qemu-devel] [PATCH 10/16] nfs: replace aio_poll with bdrv_drain, Paolo Bonzini, 2016/02/16
- [Qemu-devel] [PATCH 11/16] sheepdog: disable dataplane, Paolo Bonzini, 2016/02/16
- [Qemu-devel] [PATCH 13/16] block: only call aio_poll from iothread, Paolo Bonzini, 2016/02/16
- [Qemu-devel] [PATCH 15/16] qemu-thread: introduce QemuRecMutex, Paolo Bonzini, 2016/02/16
- [Qemu-devel] [PATCH 12/16] aio: introduce aio_context_in_iothread, Paolo Bonzini, 2016/02/16
- [Qemu-devel] [PATCH 14/16] iothread: release AioContext around aio_poll, Paolo Bonzini, 2016/02/16