[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 27/42] migration: Do not construct JSON description if suppressed
From: |
Fabiano Rosas |
Subject: |
[PULL 27/42] migration: Do not construct JSON description if suppressed |
Date: |
Wed, 29 Jan 2025 13:00:44 -0300 |
From: Peter Xu <peterx@redhat.com>
QEMU machine has a property "suppress-vmdesc". When it is enabled, QEMU
will stop attaching JSON VM description at the end of the precopy migration
stream (postcopy is never affected because postcopy never attach that).
However even if it's suppressed by the user, the source QEMU will still
construct the JSON descriptions, which is a complete waste of CPU and
memory resources.
To avoid it, only create the JSON writer object if suppress-vmdesc is not
specified.
Luckily, vmstate_save() already supports vmdesc==NULL, so only a few spots
that are left to be prepared that vmdesc can be NULL now.
When at it, move the init / destroy of the JSON writer object to start /
end of the migration - the JSON writer object is a sub-struct of migration
state, and that looks like the only object that was dynamically allocated /
destroyed within migration process. Make it the same as the rest objects
that migration uses.
Signed-off-by: Peter Xu <peterx@redhat.com>
Tested-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Juraj Marcin <jmarcin@redhat.com>
Link: 20250114230746.3268797-3-peterx@redhat.com">https://lore.kernel.org/r/20250114230746.3268797-3-peterx@redhat.com
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
migration/migration.c | 9 +++++---
migration/migration.h | 1 +
migration/savevm.c | 49 +++++++++++++++++++++++--------------------
3 files changed, 33 insertions(+), 26 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index 88b09914ec..5c335cc30b 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1431,8 +1431,8 @@ static void migrate_fd_cleanup(MigrationState *s)
g_free(s->hostname);
s->hostname = NULL;
- json_writer_free(s->vmdesc);
- s->vmdesc = NULL;
+
+ g_clear_pointer(&s->vmdesc, json_writer_free);
qemu_savevm_state_cleanup();
cpr_state_close();
@@ -1722,7 +1722,10 @@ int migrate_init(MigrationState *s, Error **errp)
s->migration_thread_running = false;
error_free(s->error);
s->error = NULL;
- s->vmdesc = NULL;
+
+ if (should_send_vmdesc()) {
+ s->vmdesc = json_writer_new(false);
+ }
migrate_set_state(&s->state, MIGRATION_STATUS_NONE,
MIGRATION_STATUS_SETUP);
diff --git a/migration/migration.h b/migration/migration.h
index fb1b8f99d3..4c1fafc2b5 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -552,6 +552,7 @@ void migration_bitmap_sync_precopy(bool last_stage);
/* migration/block-dirty-bitmap.c */
void dirty_bitmap_mig_init(void);
+bool should_send_vmdesc(void);
/* migration/block-active.c */
void migration_block_active_setup(bool active);
diff --git a/migration/savevm.c b/migration/savevm.c
index b8859d367f..cfe9dfaf5c 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -1231,8 +1231,7 @@ void qemu_savevm_non_migratable_list(strList **reasons)
void qemu_savevm_state_header(QEMUFile *f)
{
MigrationState *s = migrate_get_current();
-
- s->vmdesc = json_writer_new(false);
+ JSONWriter *vmdesc = s->vmdesc;
trace_savevm_state_header();
qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
@@ -1241,16 +1240,21 @@ void qemu_savevm_state_header(QEMUFile *f)
if (s->send_configuration) {
qemu_put_byte(f, QEMU_VM_CONFIGURATION);
- /*
- * This starts the main json object and is paired with the
- * json_writer_end_object in
- * qemu_savevm_state_complete_precopy_non_iterable
- */
- json_writer_start_object(s->vmdesc, NULL);
+ if (vmdesc) {
+ /*
+ * This starts the main json object and is paired with the
+ * json_writer_end_object in
+ * qemu_savevm_state_complete_precopy_non_iterable
+ */
+ json_writer_start_object(vmdesc, NULL);
+ json_writer_start_object(vmdesc, "configuration");
+ }
- json_writer_start_object(s->vmdesc, "configuration");
- vmstate_save_state(f, &vmstate_configuration, &savevm_state,
s->vmdesc);
- json_writer_end_object(s->vmdesc);
+ vmstate_save_state(f, &vmstate_configuration, &savevm_state, vmdesc);
+
+ if (vmdesc) {
+ json_writer_end_object(vmdesc);
+ }
}
}
@@ -1296,16 +1300,19 @@ int qemu_savevm_state_setup(QEMUFile *f, Error **errp)
{
ERRP_GUARD();
MigrationState *ms = migrate_get_current();
+ JSONWriter *vmdesc = ms->vmdesc;
SaveStateEntry *se;
int ret = 0;
- json_writer_int64(ms->vmdesc, "page_size", qemu_target_page_size());
- json_writer_start_array(ms->vmdesc, "devices");
+ if (vmdesc) {
+ json_writer_int64(vmdesc, "page_size", qemu_target_page_size());
+ json_writer_start_array(vmdesc, "devices");
+ }
trace_savevm_state_setup();
QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {
if (se->vmsd && se->vmsd->early_setup) {
- ret = vmstate_save(f, se, ms->vmdesc, errp);
+ ret = vmstate_save(f, se, vmdesc, errp);
if (ret) {
migrate_set_error(ms, *errp);
qemu_file_set_error(f, ret);
@@ -1424,7 +1431,7 @@ int qemu_savevm_state_iterate(QEMUFile *f, bool postcopy)
return all_finished;
}
-static bool should_send_vmdesc(void)
+bool should_send_vmdesc(void)
{
MachineState *machine = MACHINE(qdev_get_machine());
@@ -1564,21 +1571,17 @@ int
qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f,
/* Postcopy stream will still be going */
qemu_put_byte(f, QEMU_VM_EOF);
- json_writer_end_array(vmdesc);
- json_writer_end_object(vmdesc);
- vmdesc_len = strlen(json_writer_get(vmdesc));
+ if (vmdesc) {
+ json_writer_end_array(vmdesc);
+ json_writer_end_object(vmdesc);
+ vmdesc_len = strlen(json_writer_get(vmdesc));
- if (should_send_vmdesc()) {
qemu_put_byte(f, QEMU_VM_VMDESCRIPTION);
qemu_put_be32(f, vmdesc_len);
qemu_put_buffer(f, (uint8_t *)json_writer_get(vmdesc), vmdesc_len);
}
}
- /* Free it now to detect any inconsistencies. */
- json_writer_free(vmdesc);
- ms->vmdesc = NULL;
-
trace_vmstate_downtime_checkpoint("src-non-iterable-saved");
return 0;
--
2.35.3
- [PULL 34/42] migration: Drop cached migration state in migration_maybe_pause(), (continued)
- [PULL 34/42] migration: Drop cached migration state in migration_maybe_pause(), Fabiano Rosas, 2025/01/29
- [PULL 24/42] migration-test: cpr-transfer, Fabiano Rosas, 2025/01/29
- [PULL 25/42] migration: cpr-transfer documentation, Fabiano Rosas, 2025/01/29
- [PULL 01/42] migration: fix -Werror=maybe-uninitialized, Fabiano Rosas, 2025/01/29
- [PULL 09/42] physmem: preserve ram blocks for cpr, Fabiano Rosas, 2025/01/29
- [PULL 08/42] migration: cpr-state, Fabiano Rosas, 2025/01/29
- [PULL 13/42] migration: incoming channel, Fabiano Rosas, 2025/01/29
- [PULL 19/42] tests/qtest: optimize migrate_set_ports, Fabiano Rosas, 2025/01/29
- [PULL 18/42] migration-test: memory_backend, Fabiano Rosas, 2025/01/29
- [PULL 16/42] migration: cpr-transfer save and load, Fabiano Rosas, 2025/01/29
- [PULL 27/42] migration: Do not construct JSON description if suppressed,
Fabiano Rosas <=
- [PULL 32/42] migration: Adjust postcopy bandwidth during switchover, Fabiano Rosas, 2025/01/29
- [PULL 31/42] migration: Synchronize all CPU states only for non-iterable dump, Fabiano Rosas, 2025/01/29
- [PULL 36/42] migration: Notify COMPLETE once for postcopy, Fabiano Rosas, 2025/01/29
- [PULL 41/42] migration: Trivial cleanup on JSON writer of vmstate_save(), Fabiano Rosas, 2025/01/29
- [PULL 42/42] migration: refactor ram_save_target_page functions, Fabiano Rosas, 2025/01/29
- [PULL 17/42] migration: cpr-transfer mode, Fabiano Rosas, 2025/01/29
- [PULL 35/42] migration: Take BQL slightly longer in postcopy_start(), Fabiano Rosas, 2025/01/29
- [PULL 37/42] migration: Unwrap qemu_savevm_state_complete_precopy() in postcopy, Fabiano Rosas, 2025/01/29
- [PULL 38/42] migration: Cleanup qemu_savevm_state_complete_precopy(), Fabiano Rosas, 2025/01/29
- [PULL 39/42] migration: Always set DEVICE state, Fabiano Rosas, 2025/01/29