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