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


Reply via email to