-From f18d2aee91bca252a6b90583784f49236ec17d58 Mon Sep 17 00:00:00 2001
+From f255c2a02017dbefc3bcc786762b1de3c5aa5c89 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Tue, 8 Nov 2016 11:13:06 +0100
Subject: [PATCH 46/46] convert savevm-async to threads
---
- savevm-async.c | 149 +++++++++++++++++++++++++++++++++++----------------------
- 1 file changed, 93 insertions(+), 56 deletions(-)
+ savevm-async.c | 143 +++++++++++++++++++++++++++++++++++----------------------
+ 1 file changed, 88 insertions(+), 55 deletions(-)
diff --git a/savevm-async.c b/savevm-async.c
-index 05b5b19..e293a00 100644
+index 05b5b19..c4afc3b 100644
--- a/savevm-async.c
+++ b/savevm-async.c
@@ -48,6 +48,8 @@ static struct SnapshotState {
- if (ret < 0) {
- return ret;
+
++ aio_context = blk_get_aio_context(snap_state.target);
++ aio_context_acquire(aio_context);
+ co = qemu_coroutine_create(&block_state_write_entry, &rwco);
+ qemu_coroutine_enter(co);
-+
-+ aio_context = blk_get_aio_context(snap_state.target);
+ while (rwco.ret == NOT_DONE) {
+ aio_poll(aio_context, true);
}
++ aio_context_release(aio_context);
+
snap_state.bs_pos += qiov.size;
return qiov.size;
{
int ret;
int64_t maxlen;
-+ AioContext *aio_context;
+
MigrationParams params = {
.blk = 0,
.shared = 0
-@@ -193,57 +222,64 @@ static void process_savevm_co(void *opaque)
+@@ -193,14 +222,15 @@ static void process_savevm_co(void *opaque)
snap_state.state = SAVE_STATE_ACTIVE;
+ return NULL;
}
-+ aio_context = bdrv_get_aio_context(blk_bs(snap_state.target));
-+ aio_context_acquire(aio_context);
-+
while (snap_state.state == SAVE_STATE_ACTIVE) {
- uint64_t pending_size, pend_post, pend_nonpost;
-
+@@ -209,41 +239,43 @@ static void process_savevm_co(void *opaque)
qemu_savevm_state_pending(snap_state.file, 0, &pend_nonpost, &pend_post);
pending_size = pend_post + pend_nonpost;
+ maxlen = blk_getlength(snap_state.target) - 30*1024*1024;
+
+ if (pending_size > 400000 && snap_state.bs_pos + pending_size < maxlen) {
++ qemu_mutex_lock_iothread();
+ ret = qemu_savevm_state_iterate(snap_state.file, false);
+ if (ret < 0) {
-+ aio_context_release(aio_context);
+ save_snapshot_error("qemu_savevm_state_iterate error %d", ret);
+ break;
+ }
++ qemu_mutex_unlock_iothread();
+ DPRINTF("savevm inerate pending size %lu ret %d\n", pending_size, ret);
} else {
- DPRINTF("done iterating\n");
- if (store_and_stop())
-+ aio_context_release(aio_context);
+ qemu_mutex_lock_iothread();
+ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
+ ret = global_state_store();
+ if (ret) {
-+ qemu_mutex_unlock_iothread();
+ save_snapshot_error("global_state_store error %d", ret);
+ break;
+ }
+ ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
+ if (ret < 0) {
-+ qemu_mutex_unlock_iothread();
+ save_snapshot_error("vm_stop_force_state error %d", ret);
break;
+ }
+ qemu_savevm_state_cleanup();
DPRINTF("save complete\n");
- save_snapshot_completed();
-+ qemu_mutex_unlock_iothread();
break;
}
-
- if (store_and_stop())
- break;
- }
-- }
--
+ }
+
- if(snap_state.state == SAVE_STATE_CANCELLED) {
- save_snapshot_completed();
- Error *errp = NULL;
- qmp_savevm_end(&errp);
- }
-
+- }
+ qemu_bh_schedule(snap_state.cleanup_bh);
++ qemu_mutex_unlock_iothread();
+
+ rcu_unregister_thread();
+ return NULL;
}
static const QEMUFileOps block_file_ops = {
-@@ -306,8 +342,9 @@ void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
+@@ -306,8 +338,9 @@ void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
error_setg(&snap_state.blocker, "block device is in use by savevm");
blk_op_block_all(snap_state.target, snap_state.blocker);