Signed-off-by: Chuan Zheng <[email protected]>
---
migration/multifd.c | 6 +++++
migration/multifd.h | 5 ++++
migration/rdma.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 82 insertions(+)
diff --git a/migration/multifd.c b/migration/multifd.c
index cb1fc01..4820702 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -1232,6 +1232,12 @@ MultiFDSetup *multifd_setup_ops_init(void)
{
MultiFDSetup *ops;
+#ifdef CONFIG_RDMA
+ if (migrate_use_rdma()) {
+ ops = &multifd_rdma_ops;
+ return ops;
+ }
+#endif
ops = &multifd_socket_ops;
return ops;
}
diff --git a/migration/multifd.h b/migration/multifd.h
index 1d2dc90..e3ab4b0 100644
--- a/migration/multifd.h
+++ b/migration/multifd.h
@@ -173,6 +173,11 @@ typedef struct {
void (*recv_channel_setup)(QIOChannel *ioc, MultiFDRecvParams *p);
} MultiFDSetup;
+#ifdef CONFIG_RDMA
+extern MultiFDSetup multifd_rdma_ops;
+#endif
+MultiFDSetup *multifd_setup_ops_init(void);
+
void multifd_register_ops(int method, MultiFDMethods *ops);
#endif
diff --git a/migration/rdma.c b/migration/rdma.c
index 00eac34..e0ea86d 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -19,6 +19,7 @@
#include "qemu/cutils.h"
#include "rdma.h"
#include "migration.h"
+#include "multifd.h"
#include "qemu-file.h"
#include "ram.h"
#include "qemu-file-channel.h"
@@ -4139,3 +4140,73 @@ err:
g_free(rdma);
g_free(rdma_return_path);
}
+
+static void *multifd_rdma_send_thread(void *opaque)
+{
+ MultiFDSendParams *p = opaque;
+
+ while (true) {
+ WITH_QEMU_LOCK_GUARD(&p->mutex) {
+ if (p->quit) {
+ break;
+ }
+ }
+ qemu_sem_wait(&p->sem);
+ }
+
+ WITH_QEMU_LOCK_GUARD(&p->mutex) {
+ p->running = false;
+ }
+
+ return NULL;
+}
+
+static void multifd_rdma_send_channel_setup(MultiFDSendParams *p)
+{
+ Error *local_err = NULL;
+
+ if (p->quit) {
+ error_setg(&local_err, "multifd: send id %d already quit", p->id);
+ return ;
+ }
+ p->running = true;
+
+ qemu_thread_create(&p->thread, p->name, multifd_rdma_send_thread, p,
+ QEMU_THREAD_JOINABLE);
+}
+
+static void *multifd_rdma_recv_thread(void *opaque)
+{
+ MultiFDRecvParams *p = opaque;
+
+ while (true) {
+ WITH_QEMU_LOCK_GUARD(&p->mutex) {
+ if (p->quit) {
+ break;
+ }
+ }
+ qemu_sem_wait(&p->sem_sync);
+ }
+
+ WITH_QEMU_LOCK_GUARD(&p->mutex) {
+ p->running = false;
+ }
+
+ return NULL;
+}
+
+static void multifd_rdma_recv_channel_setup(QIOChannel *ioc,
+ MultiFDRecvParams *p)
+{
+ QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(ioc);
+
+ p->file = rioc->file;
+ return;
+}
+
+MultiFDSetup multifd_rdma_ops = {
+ .send_thread = multifd_rdma_send_thread,
+ .recv_thread = multifd_rdma_recv_thread,
+ .send_channel_setup = multifd_rdma_send_channel_setup,
+ .recv_channel_setup = multifd_rdma_recv_channel_setup
+};
--
1.8.3.1