[libvirt] [PATCH v2 07/21] qemu: Reuse qemuDomainDetectVcpuPids in cpu hot(un)plug

Peter Krempa pkrempa at redhat.com
Fri Jan 29 16:02:02 UTC 2016


Now that qemuDomainDetectVcpuPids is able to refresh the vCPU pid
information it can be reused in the hotplug and hotunplug code paths
rather than open-coding a very similar algorithm.

A slight algoirithm change is necessary for unplug since the vCPU needs
to be marked offline prior to calling the thread detector function and
eventually rolled back if something fails.
---

Notes:
    v2: fix bugs regarding error codes from redetection

 src/qemu/qemu_driver.c | 86 +++++++++++++++++---------------------------------
 1 file changed, 29 insertions(+), 57 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 9dce1b2..b8a60d8 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4765,11 +4765,10 @@ qemuDomainHotplugAddVcpu(virQEMUDriverPtr driver,
     int ret = -1;
     int rc;
     int oldvcpus = virDomainDefGetVcpus(vm->def);
-    pid_t *cpupids = NULL;
-    int ncpupids = 0;
     virCgroupPtr cgroup_vcpu = NULL;
     char *mem_mask = NULL;
     virDomainNumatuneMemMode mem_mode;
+    pid_t vcpupid;

     if (!(vcpuinfo = virDomainDefGetVcpu(vm->def, vcpu)))
         return -1;
@@ -4784,9 +4783,6 @@ qemuDomainHotplugAddVcpu(virQEMUDriverPtr driver,

     rc = qemuMonitorSetCPU(priv->mon, vcpu, true);

-    if (rc == 0)
-        ncpupids = qemuMonitorGetCPUInfo(priv->mon, &cpupids);
-
     if (qemuDomainObjExitMonitor(driver, vm) < 0)
         goto cleanup;

@@ -4797,23 +4793,15 @@ qemuDomainHotplugAddVcpu(virQEMUDriverPtr driver,

     vcpuinfo->online = true;

-    if (ncpupids < 0)
-        goto cleanup;
+    if ((rc = qemuDomainDetectVcpuPids(driver, vm, QEMU_ASYNC_JOB_NONE)) <= 0) {
+        /* vcpu pids were not detected, skip setting of affinity */
+        if (rc == 0)
+            ret = 0;

-    /* failure to re-detect vCPU pids after hotplug due to lack of support was
-     * historically deemed not fatal. We need to skip the rest of the steps though. */
-    if (ncpupids == 0) {
-        ret = 0;
         goto cleanup;
     }

-    if (ncpupids != oldvcpus + 1) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("got wrong number of vCPU pids from QEMU monitor. "
-                         "got %d, wanted %d"),
-                       ncpupids, oldvcpus + 1);
-        goto cleanup;
-    }
+    vcpupid = qemuDomainGetVcpuPid(vm, vcpu);

     if (virDomainNumatuneGetMode(vm->def->numa, -1, &mem_mode) == 0 &&
         mem_mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
@@ -4823,11 +4811,9 @@ qemuDomainHotplugAddVcpu(virQEMUDriverPtr driver,
         goto cleanup;

     if (priv->cgroup) {
-        cgroup_vcpu =
-            qemuDomainAddCgroupForThread(priv->cgroup,
-                                         VIR_CGROUP_THREAD_VCPU,
-                                         vcpu, mem_mask,
-                                         cpupids[vcpu]);
+        cgroup_vcpu = qemuDomainAddCgroupForThread(priv->cgroup,
+                                                   VIR_CGROUP_THREAD_VCPU,
+                                                   vcpu, mem_mask, vcpupid);
         if (!cgroup_vcpu)
             goto cleanup;
     }
@@ -4839,26 +4825,20 @@ qemuDomainHotplugAddVcpu(virQEMUDriverPtr driver,
                                     &vm->def->cputune.nvcpupin) < 0)
             goto cleanup;

-        if (qemuDomainHotplugPinThread(vm->def->cpumask, vcpu, cpupids[vcpu],
+        if (qemuDomainHotplugPinThread(vm->def->cpumask, vcpu, vcpupid,
                                        cgroup_vcpu) < 0) {
             goto cleanup;
         }
     }

-    if (qemuProcessSetSchedParams(vcpu, cpupids[vcpu],
+    if (qemuProcessSetSchedParams(vcpu, vcpupid,
                                   vm->def->cputune.nvcpusched,
                                   vm->def->cputune.vcpusched) < 0)
         goto cleanup;

-    priv->nvcpupids = ncpupids;
-    VIR_FREE(priv->vcpupids);
-    priv->vcpupids = cpupids;
-    cpupids = NULL;
-
     ret = 0;

  cleanup:
-    VIR_FREE(cpupids);
     VIR_FREE(mem_mask);
     virCgroupFree(&cgroup_vcpu);
     return ret;
@@ -4875,8 +4855,6 @@ qemuDomainHotplugDelVcpu(virQEMUDriverPtr driver,
     int ret = -1;
     int rc;
     int oldvcpus = virDomainDefGetVcpus(vm->def);
-    pid_t *cpupids = NULL;
-    int ncpupids = 0;

     if (!(vcpuinfo = virDomainDefGetVcpu(vm->def, vcpu)))
         return -1;
@@ -4887,49 +4865,43 @@ qemuDomainHotplugDelVcpu(virQEMUDriverPtr driver,
         return -1;
     }

+    vcpuinfo->online = false;
+
     qemuDomainObjEnterMonitor(driver, vm);

     rc = qemuMonitorSetCPU(priv->mon, vcpu, false);

-    if (rc == 0)
-        ncpupids = qemuMonitorGetCPUInfo(priv->mon, &cpupids);
-
     if (qemuDomainObjExitMonitor(driver, vm) < 0)
         goto cleanup;

-    virDomainAuditVcpu(vm, oldvcpus, oldvcpus - 1, "update",
-                       rc == 0 && ncpupids == oldvcpus -1);
+    if (rc < 0)
+        rc = qemuDomainDetectVcpuPids(driver, vm, QEMU_ASYNC_JOB_NONE);

-    if (rc < 0 || ncpupids < 0)
-        goto cleanup;
+    virDomainAuditVcpu(vm, oldvcpus, oldvcpus - 1, "update", rc >= 0);
+
+    /* Free vcpupin setting */
+    virDomainPinDel(&vm->def->cputune.vcpupin,
+                    &vm->def->cputune.nvcpupin,
+                    vcpu);
+
+    if (rc <= 0) {
+        if (rc == 0)
+            ret = 0;

-    /* check if hotunplug has failed */
-    if (ncpupids != oldvcpus - 1) {
-        virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
-                       _("qemu didn't unplug vCPU '%u' properly"), vcpu);
         goto cleanup;
     }

-    vcpuinfo->online = false;
-
     if (qemuDomainDelCgroupForThread(priv->cgroup,
                                      VIR_CGROUP_THREAD_VCPU, vcpu) < 0)
         goto cleanup;

-    /* Free vcpupin setting */
-    virDomainPinDel(&vm->def->cputune.vcpupin,
-                    &vm->def->cputune.nvcpupin,
-                    vcpu);
-
-    priv->nvcpupids = ncpupids;
-    VIR_FREE(priv->vcpupids);
-    priv->vcpupids = cpupids;
-    cpupids = NULL;
-
     ret = 0;

  cleanup:
-    VIR_FREE(cpupids);
+    /* rollback the cpu state */
+    if (ret < 0)
+        vcpuinfo->online = true;
+
     return ret;
 }

-- 
2.6.2




More information about the libvir-list mailing list