This allows to override the behaviour around recv_pages. Think of
it like a "multifd_colo" child class of multifd.

This will be used in the next commits to add colo support to multifd.

Signed-off-by: Lukas Straub <lukasstra...@web.de>
---
 migration/meson.build        |  1 +
 migration/multifd-colo.c     | 39 +++++++++++++++++++++++++++++
 migration/multifd-internal.h |  5 ++++
 migration/multifd.c          | 48 ++++++++++++++++++++++++++++--------
 4 files changed, 83 insertions(+), 10 deletions(-)
 create mode 100644 migration/multifd-colo.c

diff --git a/migration/meson.build b/migration/meson.build
index da1897fadf..22ab6c6d73 100644
--- a/migration/meson.build
+++ b/migration/meson.build
@@ -23,6 +23,7 @@ softmmu_ss.add(files(
   'migration.c',
   'multifd.c',
   'multifd-zlib.c',
+  'multifd-colo.c',
   'options.c',
   'postcopy-ram.c',
   'savevm.c',
diff --git a/migration/multifd-colo.c b/migration/multifd-colo.c
new file mode 100644
index 0000000000..c035d15e87
--- /dev/null
+++ b/migration/multifd-colo.c
@@ -0,0 +1,39 @@
+/*
+ * multifd colo implementation
+ *
+ * Copyright (c) Lukas Straub <lukasstra...@web.de>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "exec/target_page.h"
+#include "exec/ramblock.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+#include "ram.h"
+#include "multifd.h"
+#include "io/channel-socket.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 multifd_colo_load_setup(Error **errp)
+{
+    int ret;
+
+    ret = _multifd_load_setup(errp);
+    if (ret) {
+        return ret;
+    }
+
+    multifd_recv_state->recv_pages = multifd_colo_recv_pages;
+
+    return 0;
+}
diff --git a/migration/multifd-internal.h b/migration/multifd-internal.h
index 6eeaa028e7..82357f1d88 100644
--- a/migration/multifd-internal.h
+++ b/migration/multifd-internal.h
@@ -29,6 +29,11 @@ struct MultiFDRecvState {
     uint64_t packet_num;
     /* multifd ops */
     MultiFDMethods *ops;
+    /* overridable recv method */
+    int (*recv_pages)(MultiFDRecvParams *p, Error **errp);
 };
 
 extern struct MultiFDRecvState *multifd_recv_state;
+
+int _multifd_load_setup(Error **errp);
+int multifd_colo_load_setup(Error **errp);
diff --git a/migration/multifd.c b/migration/multifd.c
index f6bad69b6c..fb5e8859de 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -1126,7 +1126,7 @@ static void *multifd_recv_thread(void *opaque)
         qemu_mutex_unlock(&p->mutex);
 
         if (p->normal_num) {
-            ret = multifd_recv_state->ops->recv_pages(p, &local_err);
+            ret = multifd_recv_state->recv_pages(p, &local_err);
             if (ret != 0) {
                 break;
             }
@@ -1152,20 +1152,12 @@ static void *multifd_recv_thread(void *opaque)
     return NULL;
 }
 
-int multifd_load_setup(Error **errp)
+int _multifd_load_setup(Error **errp)
 {
     int thread_count;
     uint32_t page_count = MULTIFD_PACKET_SIZE / qemu_target_page_size();
     uint8_t i;
 
-    /*
-     * Return successfully if multiFD recv state is already initialised
-     * or multiFD is not enabled.
-     */
-    if (multifd_recv_state || !migrate_multifd()) {
-        return 0;
-    }
-
     thread_count = migrate_multifd_channels();
     multifd_recv_state = g_malloc0(sizeof(*multifd_recv_state));
     multifd_recv_state->params = g_new0(MultiFDRecvParams, thread_count);
@@ -1204,6 +1196,42 @@ int multifd_load_setup(Error **errp)
     return 0;
 }
 
+static int multifd_normal_recv_pages(MultiFDRecvParams *p, Error **errp)
+{
+    return multifd_recv_state->ops->recv_pages(p, errp);
+}
+
+static int multifd_normal_load_setup(Error **errp)
+{
+    int ret;
+
+    ret = _multifd_load_setup(errp);
+    if (ret) {
+        return ret;
+    }
+
+    multifd_recv_state->recv_pages = multifd_normal_recv_pages;
+
+    return 0;
+}
+
+int multifd_load_setup(Error **errp)
+{
+    /*
+     * Return successfully if multiFD recv state is already initialised
+     * or multiFD is not enabled.
+     */
+    if (multifd_recv_state || !migrate_multifd()) {
+        return 0;
+    }
+
+    if (migrate_colo()) {
+        return multifd_colo_load_setup(errp);
+    } else {
+        return multifd_normal_load_setup(errp);
+    }
+}
+
 bool multifd_recv_all_channels_created(void)
 {
     int thread_count = migrate_multifd_channels();
-- 
2.39.2

Attachment: pgpGZXBJHUHgp.pgp
Description: OpenPGP digital signature

Reply via email to