[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v5 42/45] postcopy: Wire up loadvm_postcopy_handle_{
From: |
Dr. David Alan Gilbert (git) |
Subject: |
[Qemu-devel] [PATCH v5 42/45] postcopy: Wire up loadvm_postcopy_handle_{run, end} commands |
Date: |
Wed, 25 Feb 2015 16:52:05 +0000 |
From: "Dr. David Alan Gilbert" <address@hidden>
Wire up more of the handlers for the commands on the destination side,
in particular loadvm_postcopy_handle_run now has enough to start the
guest running.
handle_end has to wait for the main thread to finish.
Signed-off-by: Dr. David Alan Gilbert <address@hidden>
---
include/migration/migration.h | 6 +++++
migration/migration.c | 2 ++
savevm.c | 56 ++++++++++++++++++++++++++++++++++++++-----
trace-events | 4 +++-
4 files changed, 61 insertions(+), 7 deletions(-)
diff --git a/include/migration/migration.h b/include/migration/migration.h
index c2af2ef..02376df 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -86,6 +86,12 @@ struct MigrationIncomingState {
PostcopyState postcopy_state;
+ /*
+ * Free at the start of the main state load, set as the main thread
finishes
+ * loading state.
+ */
+ QemuEvent main_thread_load_event;
+
bool have_fault_thread;
QemuThread fault_thread;
QemuSemaphore fault_thread_sem;
diff --git a/migration/migration.c b/migration/migration.c
index c108851..97b86cc 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -84,6 +84,7 @@ MigrationIncomingState
*migration_incoming_state_new(QEMUFile* f)
mis_current->file = f;
QLIST_INIT(&mis_current->loadvm_handlers);
qemu_mutex_init(&mis_current->rp_mutex);
+ qemu_event_init(&mis_current->main_thread_load_event, false);
return mis_current;
}
@@ -91,6 +92,7 @@ MigrationIncomingState
*migration_incoming_state_new(QEMUFile* f)
void migration_incoming_state_destroy(void)
{
postcopy_pmi_destroy(mis_current);
+ qemu_event_destroy(&mis_current->main_thread_load_event);
loadvm_free_handlers(mis_current);
g_free(mis_current);
mis_current = NULL;
diff --git a/savevm.c b/savevm.c
index eb22410..45d46db 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1396,12 +1396,34 @@ static int
loadvm_postcopy_handle_listen(MigrationIncomingState *mis)
static int loadvm_postcopy_handle_run(MigrationIncomingState *mis)
{
PostcopyState ps = postcopy_state_set(mis, POSTCOPY_INCOMING_RUNNING);
+ Error *local_err = NULL;
+
trace_loadvm_postcopy_handle_run();
if (ps != POSTCOPY_INCOMING_LISTENING) {
error_report("CMD_POSTCOPY_RUN in wrong postcopy state (%d)", ps);
return -1;
}
+ /* TODO we should move all of this lot into postcopy_ram.c or a shared code
+ * in migration.c
+ */
+ cpu_synchronize_all_post_init();
+
+ qemu_announce_self();
+
+ /* Make sure all file formats flush their mutable metadata */
+ bdrv_invalidate_cache_all(&local_err);
+ if (local_err) {
+ qerror_report_err(local_err);
+ error_free(local_err);
+ return -1;
+ }
+
+ trace_loadvm_postcopy_handle_run_cpu_sync();
+ cpu_synchronize_all_post_init();
+
+ trace_loadvm_postcopy_handle_run_vmstart();
+
if (autostart) {
/* Hold onto your hats, starting the CPU */
vm_start();
@@ -1410,19 +1432,40 @@ static int
loadvm_postcopy_handle_run(MigrationIncomingState *mis)
runstate_set(RUN_STATE_PAUSED);
}
- return 0;
+ return LOADVM_QUIT_LOOP;
}
-/* The end - with a byte from the source which can tell us to fail. */
-static int loadvm_postcopy_handle_end(MigrationIncomingState *mis)
+/* The end - with a byte from the source which can tell us to fail.
+ * The source sends this either if there is a failure, or if it believes it's
+ * sent everything
+ */
+static int loadvm_postcopy_handle_end(MigrationIncomingState *mis,
+ uint8_t status)
{
PostcopyState ps = postcopy_state_get(mis);
- trace_loadvm_postcopy_handle_end();
+ trace_loadvm_postcopy_handle_end(status);
if (ps == POSTCOPY_INCOMING_NONE) {
error_report("CMD_POSTCOPY_END in wrong postcopy state (%d)", ps);
return -1;
}
- return -1; /* TODO - expecting 1 byte good/fail */
+
+ if (!status) {
+ /*
+ * This looks good, but it's possible that the device loading in the
+ * main thread hasn't finished yet, and so we might not be in 'RUN'
+ * state yet; wait for the end of the main thread.
+ */
+ qemu_event_wait(&mis->main_thread_load_event);
+ }
+
+ if (status) {
+ error_report("CMD_POSTCOPY_END: error on source host (%d)",
+ status);
+ qemu_file_set_error(mis->file, -EPIPE);
+ }
+
+ /* This will cause the listen thread to exit and call cleanup */
+ return LOADVM_QUIT_LOOP;
}
static int loadvm_process_command_simple_lencheck(const char *name,
@@ -1566,7 +1609,7 @@ static int loadvm_process_command(QEMUFile *f)
len, 1)) {
return -1;
}
- return loadvm_postcopy_handle_end(mis);
+ return loadvm_postcopy_handle_end(mis, qemu_get_byte(f));
case MIG_CMD_POSTCOPY_RAM_DISCARD:
return loadvm_postcopy_ram_handle_discard(mis, len);
@@ -1730,6 +1773,7 @@ int qemu_loadvm_state(QEMUFile *f)
}
ret = qemu_loadvm_state_main(f, mis);
+ qemu_event_set(&mis->main_thread_load_event);
trace_qemu_loadvm_state_post_main(ret);
if (mis->have_listen_thread) {
diff --git a/trace-events b/trace-events
index 82b3631..869988b 100644
--- a/trace-events
+++ b/trace-events
@@ -1176,9 +1176,11 @@ loadvm_handle_cmd_packaged(unsigned int length) "%u"
loadvm_handle_cmd_packaged_main(int ret) "%d"
loadvm_handle_cmd_packaged_received(int ret) "%d"
loadvm_postcopy_handle_advise(void) ""
-loadvm_postcopy_handle_end(void) ""
+loadvm_postcopy_handle_end(uint8_t status) "%d"
loadvm_postcopy_handle_listen(void) ""
loadvm_postcopy_handle_run(void) ""
+loadvm_postcopy_handle_run_cpu_sync(void) ""
+loadvm_postcopy_handle_run_vmstart(void) ""
loadvm_postcopy_ram_handle_discard(void) ""
loadvm_postcopy_ram_handle_discard_end(void) ""
loadvm_process_command(uint16_t com, uint16_t len) "com=0x%x len=%d"
--
2.1.0
- [Qemu-devel] [PATCH v5 31/45] Postcopy end in migration_thread, (continued)
- [Qemu-devel] [PATCH v5 31/45] Postcopy end in migration_thread, Dr. David Alan Gilbert (git), 2015/02/25
- [Qemu-devel] [PATCH v5 32/45] Page request: Add MIG_RP_CMD_REQ_PAGES reverse command, Dr. David Alan Gilbert (git), 2015/02/25
- [Qemu-devel] [PATCH v5 33/45] Page request: Process incoming page request, Dr. David Alan Gilbert (git), 2015/02/25
- [Qemu-devel] [PATCH v5 34/45] Page request: Consume pages off the post-copy queue, Dr. David Alan Gilbert (git), 2015/02/25
- [Qemu-devel] [PATCH v5 35/45] postcopy_ram.c: place_page and helpers, Dr. David Alan Gilbert (git), 2015/02/25
- [Qemu-devel] [PATCH v5 36/45] Postcopy: Use helpers to map pages during migration, Dr. David Alan Gilbert (git), 2015/02/25
- [Qemu-devel] [PATCH v5 38/45] Don't sync dirty bitmaps in postcopy, Dr. David Alan Gilbert (git), 2015/02/25
- [Qemu-devel] [PATCH v5 39/45] Host page!=target page: Cleanup bitmaps, Dr. David Alan Gilbert (git), 2015/02/25
- [Qemu-devel] [PATCH v5 37/45] qemu_ram_block_from_host, Dr. David Alan Gilbert (git), 2015/02/25
- [Qemu-devel] [PATCH v5 40/45] Postcopy; Handle userfault requests, Dr. David Alan Gilbert (git), 2015/02/25
- [Qemu-devel] [PATCH v5 42/45] postcopy: Wire up loadvm_postcopy_handle_{run, end} commands,
Dr. David Alan Gilbert (git) <=
- [Qemu-devel] [PATCH v5 41/45] Start up a postcopy/listener thread ready for incoming page data, Dr. David Alan Gilbert (git), 2015/02/25
- [Qemu-devel] [PATCH v5 43/45] End of migration for postcopy, Dr. David Alan Gilbert (git), 2015/02/25
- [Qemu-devel] [PATCH v5 45/45] Inhibit ballooning during postcopy, Dr. David Alan Gilbert (git), 2015/02/25
- [Qemu-devel] [PATCH v5 44/45] Disable mlock around incoming postcopy, Dr. David Alan Gilbert (git), 2015/02/25