From 727b03664ca6d57caa7232398290478328d8ba3e Mon Sep 17 00:00:00 2001 Message-Id: <727b03664ca6d57caa7232398290478328d8ba3e@dist-git> From: Peter Krempa 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, "\n"); virBufferAdjustIndent(buf, 2); - for (i = 0; i < nvcpupids; i++) - virBufferAsprintf(buf, "\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, "\n", i, tid); + } virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "\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