Blob Blame History Raw
From 727b03664ca6d57caa7232398290478328d8ba3e Mon Sep 17 00:00:00 2001
Message-Id: <727b03664ca6d57caa7232398290478328d8ba3e@dist-git>
From: Peter Krempa <pkrempa@redhat.com>
Date: Wed, 24 Aug 2016 16:10:52 -0400
Subject: [PATCH] qemu: Store vCPU thread ids in vcpu private data objects

https://bugzilla.redhat.com/show_bug.cgi?id=1097930
https://bugzilla.redhat.com/show_bug.cgi?id=1224341

Rather than storing them in an external array store them directly.

(cherry picked from commit 5184f398b40a5e0d7d84b86182edcb2b48ab04ba)
---
 src/qemu/qemu_domain.c  | 116 ++++++++++++++++++++++++++++--------------------
 src/qemu/qemu_domain.h  |   7 +--
 src/qemu/qemu_process.c |   2 -
 3 files changed, 71 insertions(+), 54 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index c27129e..38225b5 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1327,7 +1327,6 @@ qemuDomainObjPrivateFree(void *data)
     virDomainUSBAddressSetFree(priv->usbaddrs);
     virDomainChrSourceDefFree(priv->monConfig);
     qemuDomainObjFreeJob(priv);
-    VIR_FREE(priv->vcpupids);
     VIR_FREE(priv->lockState);
     VIR_FREE(priv->origname);
 
@@ -1356,19 +1355,25 @@ qemuDomainObjPrivateFree(void *data)
 
 static void
 qemuDomainObjPrivateXMLFormatVcpus(virBufferPtr buf,
-                                   int *vcpupids,
-                                   int nvcpupids)
+                                   virDomainDefPtr def)
 {
     size_t i;
-
-    if (!nvcpupids)
-        return;
+    size_t maxvcpus = virDomainDefGetVcpusMax(def);
+    virDomainVcpuDefPtr vcpu;
+    pid_t tid;
 
     virBufferAddLit(buf, "<vcpus>\n");
     virBufferAdjustIndent(buf, 2);
 
-    for (i = 0; i < nvcpupids; i++)
-        virBufferAsprintf(buf, "<vcpu id='%zu' pid='%d'/>\n", i, vcpupids[i]);
+    for (i = 0; i < maxvcpus; i++) {
+        vcpu = virDomainDefGetVcpu(def, i);
+        tid = QEMU_DOMAIN_VCPU_PRIVATE(vcpu)->tid;
+
+        if (!vcpu->online || tid == 0)
+            continue;
+
+        virBufferAsprintf(buf, "<vcpu id='%zu' pid='%d'/>\n", i, tid);
+    }
 
     virBufferAdjustIndent(buf, -2);
     virBufferAddLit(buf, "</vcpus>\n");
@@ -1402,7 +1407,7 @@ qemuDomainObjPrivateXMLFormat(virBufferPtr buf,
                           virDomainChrTypeToString(priv->monConfig->type));
     }
 
-    qemuDomainObjPrivateXMLFormatVcpus(buf, priv->vcpupids, priv->nvcpupids);
+    qemuDomainObjPrivateXMLFormatVcpus(buf, vm->def);
 
     if (priv->qemuCaps) {
         size_t i;
@@ -1495,27 +1500,31 @@ qemuDomainObjPrivateXMLFormat(virBufferPtr buf,
 static int
 qemuDomainObjPrivateXMLParseVcpu(xmlNodePtr node,
                                  unsigned int idx,
-                                 qemuDomainObjPrivatePtr priv)
+                                 virDomainDefPtr def)
 {
+    virDomainVcpuDefPtr vcpu;
     char *idstr;
     char *pidstr;
+    unsigned int tmp;
     int ret = -1;
 
-    if ((idstr = virXMLPropString(node, "id"))) {
-        if (virStrToLong_uip(idstr, NULL, 10, &idx) < 0 ||
-            idx >= priv->nvcpupids) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("invalid vcpu index '%s'"), idstr);
-            goto cleanup;
-        }
+    idstr = virXMLPropString(node, "id");
+
+    if ((idstr && virStrToLong_uip(idstr, NULL, 10, &idx)) < 0 ||
+        !(vcpu = virDomainDefGetVcpu(def, idx))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("invalid vcpu index '%s'"), idstr);
+        goto cleanup;
     }
 
     if (!(pidstr = virXMLPropString(node, "pid")))
         goto cleanup;
 
-    if (virStrToLong_i(pidstr, NULL, 10, &(priv->vcpupids[idx])) < 0)
+    if (virStrToLong_uip(pidstr, NULL, 10, &tmp) < 0)
         goto cleanup;
 
+    QEMU_DOMAIN_VCPU_PRIVATE(vcpu)->tid = tmp;
+
     ret = 0;
 
  cleanup:
@@ -1578,12 +1587,8 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt,
     if ((n = virXPathNodeSet("./vcpus/vcpu", ctxt, &nodes)) < 0)
         goto error;
 
-    priv->nvcpupids = n;
-    if (VIR_REALLOC_N(priv->vcpupids, priv->nvcpupids) < 0)
-        goto error;
-
     for (i = 0; i < n; i++) {
-        if (qemuDomainObjPrivateXMLParseVcpu(nodes[i], i, priv) < 0)
+        if (qemuDomainObjPrivateXMLParseVcpu(nodes[i], i, vm->def) < 0)
             goto error;
     }
     VIR_FREE(nodes);
@@ -5587,9 +5592,18 @@ qemuDomainAdjustMaxMemLock(virDomainObjPtr vm)
 bool
 qemuDomainHasVcpuPids(virDomainObjPtr vm)
 {
-    qemuDomainObjPrivatePtr priv = vm->privateData;
+    size_t i;
+    size_t maxvcpus = virDomainDefGetVcpusMax(vm->def);
+    virDomainVcpuDefPtr vcpu;
 
-    return priv->nvcpupids > 0;
+    for (i = 0; i < maxvcpus; i++) {
+        vcpu = virDomainDefGetVcpu(vm->def, i);
+
+        if (QEMU_DOMAIN_VCPU_PRIVATE(vcpu)->tid > 0)
+            return true;
+    }
+
+    return false;
 }
 
 
@@ -5602,14 +5616,10 @@ qemuDomainHasVcpuPids(virDomainObjPtr vm)
  */
 pid_t
 qemuDomainGetVcpuPid(virDomainObjPtr vm,
-                     unsigned int vcpu)
+                     unsigned int vcpuid)
 {
-    qemuDomainObjPrivatePtr priv = vm->privateData;
-
-    if (vcpu >= priv->nvcpupids)
-        return 0;
-
-    return priv->vcpupids[vcpu];
+    virDomainVcpuDefPtr vcpu = virDomainDefGetVcpu(vm->def, vcpuid);
+    return QEMU_DOMAIN_VCPU_PRIVATE(vcpu)->tid;
 }
 
 
@@ -5629,9 +5639,12 @@ qemuDomainDetectVcpuPids(virQEMUDriverPtr driver,
                          virDomainObjPtr vm,
                          int asyncJob)
 {
+    virDomainVcpuDefPtr vcpu;
+    size_t maxvcpus = virDomainDefGetVcpusMax(vm->def);
     pid_t *cpupids = NULL;
-    int ncpupids = 0;
-    qemuDomainObjPrivatePtr priv = vm->privateData;
+    int ncpupids;
+    size_t i;
+    int ret = -1;
 
     /*
      * Current QEMU *can* report info about host threads mapped
@@ -5662,22 +5675,32 @@ qemuDomainDetectVcpuPids(virQEMUDriverPtr driver,
      * to try to do this hard work.
      */
     if (vm->def->virtType == VIR_DOMAIN_VIRT_QEMU)
-        goto done;
+        return 0;
 
     if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
         return -1;
-    ncpupids = qemuMonitorGetCPUInfo(priv->mon, &cpupids);
+    ncpupids = qemuMonitorGetCPUInfo(qemuDomainGetMonitor(vm), &cpupids);
     if (qemuDomainObjExitMonitor(driver, vm) < 0) {
-        VIR_FREE(cpupids);
-        return -2;
+        ret = -2;
+        goto cleanup;
     }
+
     /* failure to get the VCPU <-> PID mapping or to execute the query
      * command will not be treated fatal as some versions of qemu don't
      * support this command */
     if (ncpupids <= 0) {
         virResetLastError();
-        ncpupids = 0;
-        goto done;
+        ret = 0;
+        goto cleanup;
+    }
+
+    for (i = 0; i < maxvcpus; i++) {
+        vcpu = virDomainDefGetVcpu(vm->def, i);
+
+        if (i < ncpupids)
+            QEMU_DOMAIN_VCPU_PRIVATE(vcpu)->tid = cpupids[i];
+        else
+            QEMU_DOMAIN_VCPU_PRIVATE(vcpu)->tid = 0;
     }
 
     if (ncpupids != virDomainDefGetVcpus(vm->def)) {
@@ -5685,15 +5708,14 @@ qemuDomainDetectVcpuPids(virQEMUDriverPtr driver,
                        _("got wrong number of vCPU pids from QEMU monitor. "
                          "got %d, wanted %d"),
                        ncpupids, virDomainDefGetVcpus(vm->def));
-        VIR_FREE(cpupids);
-        return -1;
+        goto cleanup;
     }
 
- done:
-    VIR_FREE(priv->vcpupids);
-    priv->nvcpupids = ncpupids;
-    priv->vcpupids = cpupids;
-    return ncpupids;
+    ret = ncpupids;
+
+ cleanup:
+    VIR_FREE(cpupids);
+    return ret;
 }
 
 
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 32433cf..06c3fc2 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -184,9 +184,6 @@ struct _qemuDomainObjPrivate {
     bool beingDestroyed;
     char *pidfile;
 
-    int nvcpupids;
-    int *vcpupids;
-
     virDomainPCIAddressSetPtr pciaddrs;
     virDomainCCWAddressSetPtr ccwaddrs;
     virDomainVirtioSerialAddrSetPtr vioserialaddrs;
@@ -319,7 +316,7 @@ typedef qemuDomainVcpuPrivate *qemuDomainVcpuPrivatePtr;
 struct _qemuDomainVcpuPrivate {
     virObject parent;
 
-    int dummy;
+    pid_t tid; /* vcpu thread id */
 };
 
 # define QEMU_DOMAIN_VCPU_PRIVATE(vcpu)    \
@@ -651,7 +648,7 @@ int qemuDomainDefValidateMemoryHotplug(const virDomainDef *def,
                                        const virDomainMemoryDef *mem);
 
 bool qemuDomainHasVcpuPids(virDomainObjPtr vm);
-pid_t qemuDomainGetVcpuPid(virDomainObjPtr vm, unsigned int vcpu);
+pid_t qemuDomainGetVcpuPid(virDomainObjPtr vm, unsigned int vcpuid);
 int qemuDomainDetectVcpuPids(virQEMUDriverPtr driver, virDomainObjPtr vm,
                              int asyncJob);
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 6062f2a..41e401b 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5889,8 +5889,6 @@ void qemuProcessStop(virQEMUDriverPtr driver,
     vm->taint = 0;
     vm->pid = -1;
     virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason);
-    VIR_FREE(priv->vcpupids);
-    priv->nvcpupids = 0;
     for (i = 0; i < vm->def->niothreadids; i++)
         vm->def->iothreadids[i]->thread_id = 0;
     virObjectUnref(priv->qemuCaps);
-- 
2.10.0