Hello Peter,
On Sat, 8 Mar 2025 at 04:18, Peter Xu <[email protected]> wrote:
> [1]
> Please move all of them at the entry of postcopy_start().
> I still like the name I provided because it's more generic, above [1].
> Maybe it should be SECTION_PART. So we provide all iterator a chance to
> do something right before switching to postcopy but before VM stop. RAM
> can register.
> Maybe we don't want to run the whole iteration but only flush. I think for
> simplicity we can make a new hook.
> We do not need to account
> Please see above, if that doesn't help you come up with a final version,
> I'll write it.
===
diff --git a/migration/migration.c b/migration/migration.c
index f97bb2777f..9ef8e8ee1d 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -2700,6 +2700,10 @@ static int postcopy_start(MigrationState *ms,
Error **errp)
QIOChannelBuffer *bioc;
QEMUFile *fb;
+ if (migrate_multifd()) {
+ qemu_savevm_state_postcopy_prepare(ms->to_dst_file);
+ }
+
/*
* 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
diff --git a/migration/ram.c b/migration/ram.c
index 6fd88cbf2a..13a8c63660 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1143,6 +1143,15 @@ static int save_zero_page(RAMState *rs,
PageSearchStatus *pss,
return len;
}
+int ram_save_zero_page(QEMUFile *f, void *opaque)
+{
+ RAMState *rs = *(RAMState **)opaque;
+ PageSearchStatus *pss = &rs->pss[RAM_CHANNEL_PRECOPY];
+ ram_addr_t offset = ((ram_addr_t)pss->page) << TARGET_PAGE_BITS;
+
+ return save_zero_page(rs, pss, offset);
+}
+
/*
* @pages: the number of pages written by the control path,
* < 0 - error
diff --git a/migration/ram.h b/migration/ram.h
index 921c39a2c5..425c9ad9fd 100644
--- a/migration/ram.h
+++ b/migration/ram.h
@@ -122,4 +122,5 @@ void ram_write_tracking_prepare(void);
int ram_write_tracking_start(void);
void ram_write_tracking_stop(void);
+int ram_save_zero_page(QEMUFile *f, void *opaque);
#endif
diff --git a/migration/savevm.c b/migration/savevm.c
index ce158c3512..9bb0f03942 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -1676,6 +1676,36 @@ int qemu_savevm_state_complete_precopy(QEMUFile
*f, bool iterable_only)
return qemu_fflush(f);
}
+int qemu_savevm_state_postcopy_prepare(QEMUFile *f)
+{
+ int ret = 0;
+ SaveStateEntry *se;
+
+ QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {
+ if (strcmp(se->idstr, "ram")) {
+ continue;
+ }
+
+ save_section_header(f, se, QEMU_VM_SECTION_PART);
+
+ ram_save_zero_page(f, se->opaque);
+ if ((ret = multifd_ram_flush_and_sync(f)) < 0) {
+ return ret;
+ }
+ qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
+
+ trace_savevm_section_end(se->idstr, se->section_id, ret);
+ save_section_footer(f, se);
+ if (ret < 0) {
+ qemu_file_set_error(f, ret);
+ return -1;
+ }
+ }
+
+ return ret;
+}
+
+
/* Give an estimate of the amount left to be transferred,
* the result is split into the amount for units that can and
* for units that can't do postcopy.
diff --git a/migration/savevm.h b/migration/savevm.h
index 138c39a7f9..7d4ff25ca3 100644
--- a/migration/savevm.h
+++ b/migration/savevm.h
@@ -74,4 +74,5 @@ int
qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f,
bool qemu_loadvm_load_state_buffer(const char *idstr, uint32_t instance_id,
char *buf, size_t len, Error **errp);
+int qemu_savevm_state_postcopy_prepare(QEMUFile *f);
#endif
===
host-1] 63/63 qemu:qtest+qtest-x86_64 / qtest-x86_64/migration-test
OK 139.87s 79 subtests passed
host-2] 63/63 qemu:qtest+qtest-x86_64 / qtest-x86_64/migration-test
OK 137.52s 79 subtests passed
2025-03-13 12:11:01.653+0000: initiating migration
2025-03-13T12:11:01.690247Z qemu-system-x86_64: info:
multifd_ram_flush_and_sync: called: 1, 0
2025-03-13T12:12:05.342194Z qemu-system-x86_64: info:
multifd_ram_flush_and_sync: called: 1, 0
2025-03-13 12:12:54.688+0000: shutting down, reason=migrated
2025-03-13 12:21:10.967+0000: initiating migration
2025-03-13T12:21:10.994878Z qemu-system-x86_64: info:
multifd_ram_flush_and_sync: called: 1, 0
2025-03-13T12:22:15.955266Z qemu-system-x86_64: info:
multifd_ram_flush_and_sync: called: 1, 0
2025-03-13 12:23:02.107+0000: shutting down, reason=migrated
===
* Does this patch look okay?
Thank you.
---
- Prasad