[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 20/20] backup: follow AioContext change gracefully
From: |
Stefan Hajnoczi |
Subject: |
[Qemu-devel] [PULL 20/20] backup: follow AioContext change gracefully |
Date: |
Mon, 20 Jun 2016 15:05:31 +0100 |
Move s->target to the new AioContext when there is an AioContext change.
The backup_run() coroutine does not use asynchronous I/O so there is no
need to wait for in-flight requests in a BlockJobDriver->pause()
callback.
Guest writes are intercepted by the backup job. Treat them as guest
activity and do it even while the job is paused. This is necessary
since the only alternative would be to fail a job that experienced guest
writes during pause once the job is resumed. In practice the guest
writes don't interfere with AioContext switching since bdrv_drain() is
used by bdrv_set_aio_context().
Loops already contain pause points because of block_job_sleep_ns() calls
in the yield_and_check() helper function. It is necessary to convert a
raw qemu_coroutine_yield() to block_job_yield() so the
MIRROR_SYNC_MODE_NONE case can pause.
Signed-off-by: Stefan Hajnoczi <address@hidden>
Reviewed-by: Paolo Bonzini <address@hidden>
Reviewed-by: Fam Zheng <address@hidden>
Message-id: address@hidden
---
block/backup.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/block/backup.c b/block/backup.c
index feeb9f8..581269b 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -246,12 +246,20 @@ static void backup_abort(BlockJob *job)
}
}
+static void backup_attached_aio_context(BlockJob *job, AioContext *aio_context)
+{
+ BackupBlockJob *s = container_of(job, BackupBlockJob, common);
+
+ blk_set_aio_context(s->target, aio_context);
+}
+
static const BlockJobDriver backup_job_driver = {
- .instance_size = sizeof(BackupBlockJob),
- .job_type = BLOCK_JOB_TYPE_BACKUP,
- .set_speed = backup_set_speed,
- .commit = backup_commit,
- .abort = backup_abort,
+ .instance_size = sizeof(BackupBlockJob),
+ .job_type = BLOCK_JOB_TYPE_BACKUP,
+ .set_speed = backup_set_speed,
+ .commit = backup_commit,
+ .abort = backup_abort,
+ .attached_aio_context = backup_attached_aio_context,
};
static BlockErrorAction backup_error_action(BackupBlockJob *job,
@@ -392,9 +400,7 @@ static void coroutine_fn backup_run(void *opaque)
while (!block_job_is_cancelled(&job->common)) {
/* Yield until the job is cancelled. We just let our before_write
* notify callback service CoW requests. */
- job->common.busy = false;
- qemu_coroutine_yield();
- job->common.busy = true;
+ block_job_yield(&job->common);
}
} else if (job->sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {
ret = backup_run_incremental(job);
--
2.5.5
- [Qemu-devel] [PULL 09/20] libqos: add qvirtqueue_cleanup(), (continued)
- [Qemu-devel] [PULL 09/20] libqos: add qvirtqueue_cleanup(), Stefan Hajnoczi, 2016/06/20
- [Qemu-devel] [PULL 11/20] block: fix race in bdrv_co_discard with drive-mirror, Stefan Hajnoczi, 2016/06/20
- [Qemu-devel] [PULL 10/20] block: fixed BdrvTrackedRequest filling in bdrv_co_discard, Stefan Hajnoczi, 2016/06/20
- [Qemu-devel] [PULL 12/20] block: process before_write_notifiers in bdrv_co_discard, Stefan Hajnoczi, 2016/06/20
- [Qemu-devel] [PULL 15/20] blockjob: add pause points, Stefan Hajnoczi, 2016/06/20
- [Qemu-devel] [PULL 14/20] blockjob: rename block_job_is_paused(), Stefan Hajnoczi, 2016/06/20
- [Qemu-devel] [PULL 13/20] blockjob: move iostatus reset out of block_job_enter(), Stefan Hajnoczi, 2016/06/20
- [Qemu-devel] [PULL 16/20] blockjob: add block_job_get_aio_context(), Stefan Hajnoczi, 2016/06/20
- [Qemu-devel] [PULL 17/20] block: use safe iteration over AioContext notifiers, Stefan Hajnoczi, 2016/06/20
- [Qemu-devel] [PULL 18/20] blockjob: add AioContext attached callback, Stefan Hajnoczi, 2016/06/20
- [Qemu-devel] [PULL 20/20] backup: follow AioContext change gracefully,
Stefan Hajnoczi <=
- [Qemu-devel] [PULL 19/20] mirror: follow AioContext change gracefully, Stefan Hajnoczi, 2016/06/20
- Re: [Qemu-devel] [PULL 00/20] Block patches, Peter Maydell, 2016/06/20