[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PULL for-2.8 13/13] mirror: do not flush every time the di
From: |
Jeff Cody |
Subject: |
[Qemu-block] [PULL for-2.8 13/13] mirror: do not flush every time the disks are synced |
Date: |
Mon, 14 Nov 2016 23:14:51 -0500 |
From: Paolo Bonzini <address@hidden>
This puts a huge strain on the disks when there are many concurrent
migrations. With this patch we only flush twice: just before issuing
the event, and just before pivoting to the destination. If management
will complete the job close to the BLOCK_JOB_READY event, the cost of
the second flush should be small anyway.
Signed-off-by: Paolo Bonzini <address@hidden>
Message-id: address@hidden
Signed-off-by: Jeff Cody <address@hidden>
---
block/mirror.c | 40 +++++++++++++++++++++++++---------------
1 file changed, 25 insertions(+), 15 deletions(-)
diff --git a/block/mirror.c b/block/mirror.c
index 62ac87f..301ba92 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -615,6 +615,20 @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob
*s)
return 0;
}
+/* Called when going out of the streaming phase to flush the bulk of the
+ * data to the medium, or just before completing.
+ */
+static int mirror_flush(MirrorBlockJob *s)
+{
+ int ret = blk_flush(s->target);
+ if (ret < 0) {
+ if (mirror_error_action(s, false, -ret) == BLOCK_ERROR_ACTION_REPORT) {
+ s->ret = ret;
+ }
+ }
+ return ret;
+}
+
static void coroutine_fn mirror_run(void *opaque)
{
MirrorBlockJob *s = opaque;
@@ -727,27 +741,23 @@ static void coroutine_fn mirror_run(void *opaque)
should_complete = false;
if (s->in_flight == 0 && cnt == 0) {
trace_mirror_before_flush(s);
- ret = blk_flush(s->target);
- if (ret < 0) {
- if (mirror_error_action(s, false, -ret) ==
- BLOCK_ERROR_ACTION_REPORT) {
- goto immediate_exit;
+ if (!s->synced) {
+ if (mirror_flush(s) < 0) {
+ /* Go check s->ret. */
+ continue;
}
- } else {
/* We're out of the streaming phase. From now on, if the job
* is cancelled we will actually complete all pending I/O and
* report completion. This way, block-job-cancel will leave
* the target in a consistent state.
*/
- if (!s->synced) {
- block_job_event_ready(&s->common);
- s->synced = true;
- }
-
- should_complete = s->should_complete ||
- block_job_is_cancelled(&s->common);
- cnt = bdrv_get_dirty_count(s->dirty_bitmap);
+ block_job_event_ready(&s->common);
+ s->synced = true;
}
+
+ should_complete = s->should_complete ||
+ block_job_is_cancelled(&s->common);
+ cnt = bdrv_get_dirty_count(s->dirty_bitmap);
}
if (cnt == 0 && should_complete) {
@@ -765,7 +775,7 @@ static void coroutine_fn mirror_run(void *opaque)
bdrv_drained_begin(bs);
cnt = bdrv_get_dirty_count(s->dirty_bitmap);
- if (cnt > 0) {
+ if (cnt > 0 || mirror_flush(s) < 0) {
bdrv_drained_end(bs);
continue;
}
--
2.7.4
- [Qemu-block] [PULL for-2.8 03/13] blockjob: add .start field, (continued)
- [Qemu-block] [PULL for-2.8 03/13] blockjob: add .start field, Jeff Cody, 2016/11/14
- [Qemu-block] [PULL for-2.8 04/13] blockjob: add block_job_start, Jeff Cody, 2016/11/14
- [Qemu-block] [PULL for-2.8 05/13] blockjob: refactor backup_start as backup_job_create, Jeff Cody, 2016/11/14
- [Qemu-block] [PULL for-2.8 06/13] iotests: add transactional failure race test, Jeff Cody, 2016/11/14
- [Qemu-block] [PULL for-2.8 07/13] qemu-iotests: avoid spurious failure on test 109, Jeff Cody, 2016/11/14
- [Qemu-block] [PULL for-2.8 08/13] block/curl: Drop TFTP "support", Jeff Cody, 2016/11/14
- [Qemu-block] [PULL for-2.8 09/13] block/curl: Use BDRV_SECTOR_SIZE, Jeff Cody, 2016/11/14
- [Qemu-block] [PULL for-2.8 10/13] block/curl: Fix return value from curl_read_cb, Jeff Cody, 2016/11/14
- [Qemu-block] [PULL for-2.8 11/13] block/curl: Remember all sockets, Jeff Cody, 2016/11/14
- [Qemu-block] [PULL for-2.8 12/13] block/curl: Do not wait for data beyond EOF, Jeff Cody, 2016/11/14
- [Qemu-block] [PULL for-2.8 13/13] mirror: do not flush every time the disks are synced,
Jeff Cody <=
- Re: [Qemu-block] [PULL for-2.8 00/13] Block patches for 2.8, Stefan Hajnoczi, 2016/11/15