Like in the normal ram_load() path, put the received pages into the
colo cache and mark the pages in the bitmap so that they will be
flushed to the guest later.

Signed-off-by: Lukas Straub <lukasstra...@web.de>
---
 migration/multifd-colo.c | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/migration/multifd-colo.c b/migration/multifd-colo.c
index c035d15e87..305a1b7000 100644
--- a/migration/multifd-colo.c
+++ b/migration/multifd-colo.c
@@ -15,13 +15,41 @@
 #include "ram.h"
 #include "multifd.h"
 #include "io/channel-socket.h"
+#include "migration/colo.h"
 
 #define MULTIFD_INTERNAL
 #include "multifd-internal.h"
 
 static int multifd_colo_recv_pages(MultiFDRecvParams *p, Error **errp)
 {
-    return multifd_recv_state->ops->recv_pages(p, errp);
+    int ret = 0;
+
+    /*
+     * While we're still in precopy mode, we copy received pages to both guest
+     * and cache. No need to set dirty bits, since guest and cache memory are
+     * in sync.
+     */
+    if (migration_incoming_in_colo_state()) {
+        colo_record_bitmap(p->block, p->normal, p->normal_num);
+    }
+
+    p->host = p->block->colo_cache;
+    ret = multifd_recv_state->ops->recv_pages(p, errp);
+    if (ret != 0) {
+        p->host = p->block->host;
+        return ret;
+    }
+
+    if (!migration_incoming_in_colo_state()) {
+        for (int i = 0; i < p->normal_num; i++) {
+            void *guest = p->block->host + p->normal[i];
+            void *cache = p->host + p->normal[i];
+            memcpy(guest, cache, p->page_size);
+        }
+    }
+
+    p->host = p->block->host;
+    return ret;
 }
 
 int multifd_colo_load_setup(Error **errp)
-- 
2.39.2

Attachment: pgplE9D31XYvU.pgp
Description: OpenPGP digital signature

Reply via email to