]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Enable for vCPUs on hotplug
authorMichal Privoznik <mprivozn@redhat.com>
Thu, 11 Aug 2022 10:12:35 +0000 (12:12 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Thu, 20 Oct 2022 07:01:21 +0000 (09:01 +0200)
As advertised in the previous commit, QEMU_SCHED_CORE_VCPUS case
is implemented for hotplug case. The implementation is very
similar to the cold boot case, except here we fork off for every
vCPU (because the implementation is done in
qemuProcessSetupVcpu() which is also the function that's called
from hotplug code). But that's okay because our hotplug APIs
allow hotplugging one device at the time.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2074559
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
src/qemu/qemu_hotplug.c
src/qemu/qemu_process.c
src/qemu/qemu_process.h

index f5d12b4fb3561d54a76a45c70ccf10a48c1cf857..da92ced2f4443dde3e7a7aba3479540a30d79e06 100644 (file)
@@ -6246,7 +6246,7 @@ qemuDomainHotplugAddVcpu(virQEMUDriver *driver,
         vcpuinfo->online = true;
 
         if (vcpupriv->tid > 0 &&
-            qemuProcessSetupVcpu(vm, i) < 0)
+            qemuProcessSetupVcpu(vm, i, true) < 0)
             return -1;
     }
 
index 6395694e7b5c7488546d163aabc7516fb3ec16e0..f405326312cb74373ab6a1f6cd5627988c7fd03a 100644 (file)
@@ -5797,10 +5797,40 @@ qemuProcessNetworkPrepareDevices(virQEMUDriver *driver,
 }
 
 
+struct qemuProcessSetupVcpuSchedCoreHelperData {
+    pid_t vcpupid;
+    pid_t dummypid;
+};
+
+static int
+qemuProcessSetupVcpuSchedCoreHelper(pid_t ppid G_GNUC_UNUSED,
+                                    void *opaque)
+{
+    struct qemuProcessSetupVcpuSchedCoreHelperData *data = opaque;
+
+    if (virProcessSchedCoreShareFrom(data->dummypid) < 0) {
+        virReportSystemError(errno,
+                             _("unable to share scheduling cookie from %lld"),
+                             (long long) data->dummypid);
+        return -1;
+    }
+
+    if (virProcessSchedCoreShareTo(data->vcpupid) < 0) {
+        virReportSystemError(errno,
+                             _("unable to share scheduling cookie to %lld"),
+                             (long long) data->vcpupid);
+        return -1;
+    }
+
+    return 0;
+}
+
+
 /**
  * qemuProcessSetupVcpu:
  * @vm: domain object
  * @vcpuid: id of VCPU to set defaults
+ * @schedCore: whether to set scheduling group
  *
  * This function sets resource properties (cgroups, affinity, scheduler) for a
  * vCPU. This function expects that the vCPU is online and the vCPU pids were
@@ -5810,8 +5840,11 @@ qemuProcessNetworkPrepareDevices(virQEMUDriver *driver,
  */
 int
 qemuProcessSetupVcpu(virDomainObj *vm,
-                     unsigned int vcpuid)
+                     unsigned int vcpuid,
+                     bool schedCore)
 {
+    qemuDomainObjPrivate *priv = vm->privateData;
+    g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(priv->driver);
     pid_t vcpupid = qemuDomainGetVcpuPid(vm, vcpuid);
     virDomainVcpuDef *vcpu = virDomainDefGetVcpu(vm->def, vcpuid);
     virDomainResctrlMonDef *mon = NULL;
@@ -5824,6 +5857,30 @@ qemuProcessSetupVcpu(virDomainObj *vm,
                             &vcpu->sched) < 0)
         return -1;
 
+    if (schedCore &&
+        cfg->schedCore == QEMU_SCHED_CORE_VCPUS) {
+        struct qemuProcessSetupVcpuSchedCoreHelperData data = { .vcpupid = vcpupid,
+            .dummypid = -1 };
+
+        for (i = 0; i < virDomainDefGetVcpusMax(vm->def); i++) {
+            pid_t temptid = qemuDomainGetVcpuPid(vm, i);
+
+            if (temptid > 0) {
+                data.dummypid = temptid;
+                break;
+            }
+        }
+
+        if (data.dummypid == -1) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Unable to find a vCPU that is online"));
+            return -1;
+        }
+
+        if (virProcessRunInFork(qemuProcessSetupVcpuSchedCoreHelper, &data) < 0)
+            return -1;
+    }
+
     for (i = 0; i < vm->def->nresctrls; i++) {
         size_t j = 0;
         virDomainResctrlDef *ct = vm->def->resctrls[i];
@@ -5930,7 +5987,7 @@ qemuProcessSetupVcpus(virDomainObj *vm)
         if (!vcpu->online)
             continue;
 
-        if (qemuProcessSetupVcpu(vm, i) < 0)
+        if (qemuProcessSetupVcpu(vm, i, false) < 0)
             return -1;
     }
 
index 421efc601607449c003c2822d9b2d725cfe7d220..4dfb2485c013fa562e8dc08e62a9cdd636ba2e5b 100644 (file)
@@ -187,7 +187,8 @@ int qemuConnectAgent(virQEMUDriver *driver, virDomainObj *vm);
 
 
 int qemuProcessSetupVcpu(virDomainObj *vm,
-                         unsigned int vcpuid);
+                         unsigned int vcpuid,
+                         bool schedCore);
 int qemuProcessSetupIOThread(virDomainObj *vm,
                              virDomainIOThreadIDDef *iothread);