From 4b1281075aacc2e968e2e35bd8a81f3199faef7d Mon Sep 17 00:00:00 2001
From: zhengchuan <zhengchuan@huawei.com>
Date: Wed, 30 Nov 2022 15:01:12 +0800
Subject: [PATCH] migration/migration-pin: add migrationpin for migration
 parameters

Add a migrationpin to the migration parameters of live migration to bind cores
to the migration thread during VM migration.

Signed-off-by:zhengchuan<zhengchuan@huawei.com>
---
 include/libvirt/libvirt-domain.h |  9 +++++++++
 src/qemu/qemu_domain.c           |  1 +
 src/qemu/qemu_domain.h           |  1 +
 src/qemu/qemu_migration.c        |  2 ++
 src/qemu/qemu_migration.h        |  1 +
 src/qemu/qemu_migration_params.c | 22 ++++++++++++++++++++++
 src/qemu/qemu_migration_params.h |  4 ++++
 src/qemu/qemu_monitor.c          |  9 +++------
 src/qemu/qemu_monitor.h          |  9 ++++-----
 src/qemu/qemu_monitor_json.c     |  6 +++---
 10 files changed, 50 insertions(+), 14 deletions(-)

diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index a1902546bb..26bf60ce34 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -1312,6 +1312,15 @@ typedef enum {
  */
 # define VIR_MIGRATE_PARAM_COMPRESSION_MT_DTHREADS "compression.mt.dthreads"
 
+/**
+ * VIR_MIGRATE_PARAM_MIGRATIONPIN:
+ *
+ * virDomainMigrate* params field: the pin of migration threads for
+ * migration as VIR_TYPED_PARAM_STRING.
+ * Since: 6.2.0
+ */
+# define VIR_MIGRATE_PARAM_MIGRATIONPIN "migration.pin"
+
 /**
  * VIR_MIGRATE_PARAM_COMPRESSION_XBZRLE_CACHE:
  *
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 6b09c15f7a..f8a6c43797 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1880,6 +1880,7 @@ qemuDomainObjPrivateFree(void *data)
     g_free(priv->lockState);
     g_free(priv->origname);
     VIR_FREE(priv->migrationPids);
+    VIR_FREE(priv->migrationThreadPinList);
     virBitmapFree(priv->pcpumap);
 
     VIR_FREE(priv->migrationMultiFdPids);
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 0eff9eab72..7074023229 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -147,6 +147,7 @@ struct _qemuDomainObjPrivate {
                                                it was changed for the current
                                                migration job. */
     char *migrationPids;
+    char *migrationThreadPinList;
     char *migrationMultiFdPids;
     unsigned int migrationMultiFdCount;
     virChrdevs *devs;
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index b13f2e0c24..00dfd46ae7 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -4838,6 +4838,8 @@ qemuMigrationSrcRun(virQEMUDriver *driver,
                                   priv->migMaxBandwidth * 1024 * 1024) < 0)
         goto error;
 
+    qemuMigrationMigrationParamsToVM(migParams, vm);
+
     if (qemuMigrationParamsApply(vm, VIR_ASYNC_JOB_MIGRATION_OUT,
                                  migParams, flags) < 0)
         goto error;
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index ed62fd4a91..1f309bbdc2 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -89,6 +89,7 @@
     VIR_MIGRATE_PARAM_COMPRESSION_ZLIB_LEVEL, VIR_TYPED_PARAM_INT, \
     VIR_MIGRATE_PARAM_COMPRESSION_ZSTD_LEVEL, VIR_TYPED_PARAM_INT, \
     VIR_MIGRATE_PARAM_TLS_DESTINATION, VIR_TYPED_PARAM_STRING, \
+    VIR_MIGRATE_PARAM_MIGRATIONPIN,    VIR_TYPED_PARAM_STRING, \
     VIR_MIGRATE_PARAM_DISKS_URI,     VIR_TYPED_PARAM_STRING, \
     NULL
 
diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c
index 79fe6e97c8..5c75fa4d8e 100644
--- a/src/qemu/qemu_migration_params.c
+++ b/src/qemu/qemu_migration_params.c
@@ -121,6 +121,7 @@ VIR_ENUM_IMPL(qemuMigrationParam,
               "multifd-compression",
               "multifd-zlib-level",
               "multifd-zstd-level",
+              "migrationpin",
 );
 
 typedef struct _qemuMigrationParamsAlwaysOnItem qemuMigrationParamsAlwaysOnItem;
@@ -243,6 +244,10 @@ static const qemuMigrationParamsTPMapItem qemuMigrationParamsTPMap[] = {
     {.typedParam = VIR_MIGRATE_PARAM_TLS_DESTINATION,
      .param = QEMU_MIGRATION_PARAM_TLS_HOSTNAME,
      .party = QEMU_MIGRATION_SOURCE},
+
+    {.typedParam = VIR_MIGRATE_PARAM_MIGRATIONPIN,
+     .param = QEMU_MIGRATION_PARAM_MIGRATIONPIN,
+     .party = QEMU_MIGRATION_SOURCE},
 };
 
 static const qemuMigrationParamInfoItem qemuMigrationParamInfo[] = {
@@ -295,6 +300,9 @@ static const qemuMigrationParamInfoItem qemuMigrationParamInfo[] = {
     [QEMU_MIGRATION_PARAM_MULTIFD_ZSTD_LEVEL] = {
         .type = QEMU_MIGRATION_PARAM_TYPE_INT,
     },
+    [QEMU_MIGRATION_PARAM_MIGRATIONPIN] = {
+        .type = QEMU_MIGRATION_PARAM_TYPE_STRING,
+    }
 };
 G_STATIC_ASSERT(G_N_ELEMENTS(qemuMigrationParamInfo) == QEMU_MIGRATION_PARAM_LAST);
 
@@ -651,6 +659,16 @@ qemuMigrationParamsSetCompression(virTypedParameterPtr params,
 }
 
 
+void
+qemuMigrationMigrationParamsToVM(const qemuMigrationParams *migParams, const virDomainObj *vm)
+{
+    if (migParams && migParams->params[QEMU_MIGRATION_PARAM_MIGRATIONPIN].set) {
+        qemuDomainObjPrivate *priv = vm->privateData;
+        priv->migrationThreadPinList = g_strdup(migParams->params[QEMU_MIGRATION_PARAM_MIGRATIONPIN].value.s);
+    }
+}
+
+
 void
 qemuMigrationParamsSetBlockDirtyBitmapMapping(qemuMigrationParams *migParams,
                                               virJSONValue **params)
@@ -870,6 +888,10 @@ qemuMigrationParamsToJSON(qemuMigrationParams *migParams,
         if (!pv->set)
             continue;
 
+        if (i == QEMU_MIGRATION_PARAM_MIGRATIONPIN) {
+            continue;
+        }
+
         if (postcopyResume && !qemuMigrationParamInfo[i].applyOnPostcopyResume)
             continue;
 
diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h
index 5857673227..5df4d3738e 100644
--- a/src/qemu/qemu_migration_params.h
+++ b/src/qemu/qemu_migration_params.h
@@ -62,6 +62,7 @@ typedef enum {
     QEMU_MIGRATION_PARAM_MULTIFD_COMPRESSION,
     QEMU_MIGRATION_PARAM_MULTIFD_ZLIB_LEVEL,
     QEMU_MIGRATION_PARAM_MULTIFD_ZSTD_LEVEL,
+    QEMU_MIGRATION_PARAM_MIGRATIONPIN,
 
     QEMU_MIGRATION_PARAM_LAST
 } qemuMigrationParam;
@@ -77,6 +78,9 @@ typedef enum {
 virBitmap *
 qemuMigrationParamsGetAlwaysOnCaps(qemuMigrationParty party);
 
+void
+qemuMigrationMigrationParamsToVM(const qemuMigrationParams *migParams, const virDomainObj *vm);
+
 qemuMigrationParams *
 qemuMigrationParamsFromFlags(virTypedParameterPtr params,
                              int nparams,
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index c2ab9b0070..1d5d47ea22 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1401,15 +1401,12 @@ qemuMonitorEmitPRManagerStatusChanged(qemuMonitor *mon,
 }
 
 
-int
-qemuMonitorEmitMigrationPid(qemuMonitorPtr mon,
+void
+qemuMonitorEmitMigrationPid(qemuMonitor *mon,
                             int mpid)
 {
-    int ret = -1;
     VIR_DEBUG("mon=%p, pass=%d", mon, mpid);
-    QEMU_MONITOR_CALLBACK(mon, ret, domainMigrationPid, mon->vm, mpid);
-
-    return ret;
+    QEMU_MONITOR_CALLBACK(mon, domainMigrationPid, mon->vm, mpid);
 }
 
 
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 44eaa00cd8..646e97a8e6 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -328,10 +328,9 @@ typedef void (*qemuMonitorDomainRdmaGidStatusChangedCallback)(qemuMonitor *mon,
 typedef void (*qemuMonitorDomainGuestCrashloadedCallback)(qemuMonitor *mon,
                                                           virDomainObj *vm);
 
-typedef int (*qemuMonitorDomainMigrationPidCallback)(qemuMonitorPtr mon,
-                                                     virDomainObjPtr vm,
-                                                     int mcpid,
-                                                     void *opaque);
+typedef void (*qemuMonitorDomainMigrationPidCallback)(qemuMonitor *mon,
+                                                      virDomainObj *vm,
+                                                      int mcpid);
 
 typedef enum {
     QEMU_MONITOR_MEMORY_FAILURE_RECIPIENT_HYPERVISOR,
@@ -511,7 +510,7 @@ void qemuMonitorEmitMigrationStatus(qemuMonitor *mon,
 void qemuMonitorEmitMigrationPass(qemuMonitor *mon,
                                   int pass);
 
-int qemuMonitorEmitMigrationPid(qemuMonitorPtr mon, int mpid);
+void qemuMonitorEmitMigrationPid(qemuMonitor *mon, int mpid);
 
 void qemuMonitorEmitAcpiOstInfo(qemuMonitor *mon,
                                 const char *alias,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 167fb7356a..4c1b8c9eb7 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -84,7 +84,7 @@ static void qemuMonitorJSONHandleRdmaGidStatusChanged(qemuMonitor *mon, virJSONV
 static void qemuMonitorJSONHandleMemoryFailure(qemuMonitor *mon, virJSONValue *data);
 static void qemuMonitorJSONHandleMemoryDeviceSizeChange(qemuMonitor *mon, virJSONValue *data);
 static void qemuMonitorJSONHandleDeviceUnplugErr(qemuMonitor *mon, virJSONValue *data);
-static void qemuMonitorJSONHandleMigrationPid(qemuMonitorPtr mon, virJSONValuePtr data);
+static void qemuMonitorJSONHandleMigrationPid(qemuMonitor *mon, virJSONValue *data);
 static void qemuMonitorJSONHandleNetdevStreamDisconnected(qemuMonitor *mon, virJSONValue *data);
 
 typedef struct {
@@ -133,8 +133,8 @@ static qemuEventHandler eventHandlers[] = {
     /* We use bsearch, so keep this list sorted.  */
 };
 
-static void qemuMonitorJSONHandleMigrationPid(qemuMonitorPtr mon,
-                                              virJSONValuePtr data)
+static void qemuMonitorJSONHandleMigrationPid(qemuMonitor *mon,
+                                              virJSONValue *data)
 {
     int mpid;
 
-- 
2.27.0

