@@ -1397,6 +1397,11 @@ void migrate_set_state(MigrationStatus *state, MigrationStatus old_state,
}
}
+static void migration_cleanup_json_writer(MigrationState *s)
+{
+ g_clear_pointer(&s->vmdesc, json_writer_free);
+}
+
static void migrate_fd_cleanup(MigrationState *s)
{
MigrationEventType type;
@@ -1404,11 +1409,11 @@ static void migrate_fd_cleanup(MigrationState *s)
trace_migrate_fd_cleanup();
+ migration_cleanup_json_writer(s);
+
g_free(s->hostname);
s->hostname = NULL;
- g_clear_pointer(&s->vmdesc, json_writer_free);
-
qemu_savevm_state_cleanup();
close_return_path_on_source(s);
@@ -2501,6 +2506,14 @@ static int postcopy_start(MigrationState *ms, Error **errp)
uint64_t bandwidth = migrate_max_postcopy_bandwidth();
int cur_state = MIGRATION_STATUS_ACTIVE;
+ /*
+ * Now we're 100% sure to switch to postcopy, so JSON writer won't be
+ * useful anymore. Free the resources early if it is there. Clearing
+ * the vmdesc also means any follow up vmstate_save()s will start to
+ * skip all JSON operations, which can shrink postcopy downtime.
+ */
+ migration_cleanup_json_writer(ms);
+
if (migrate_postcopy_preempt()) {
migration_wait_main_channel(ms);
if (postcopy_preempt_establish_channel(ms)) {
postcopy_start() is the entry function that postcopy is destined to start. It also means QEMU source will not dump VM description, aka, the JSON writer is garbage now. We can leave that to be cleaned up when migration completes, however when with the JSON writer object being present, vmstate_save() will still try to construct the JSON objects for the VM descriptions, even though it'll never be used later if it's postcopy. To save those cycles, release the JSON writer earlier for postcopy. Then vmstate_save() later will be smart enough to skip the JSON object constructions completely. It can logically reduce downtime because all such JSON constructions happen during postcopy blackout. Signed-off-by: Peter Xu <peterx@redhat.com> --- migration/migration.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)