[libvirt] [PATCH 15/34] qemu: Reuse qemuDomainDetectVcpuPids in cpu hot(un)plug
John Ferlan
jferlan at redhat.com
Mon Jan 18 14:58:37 UTC 2016
On 01/14/2016 11:27 AM, Peter Krempa wrote:
> 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
s/algoirithm/algorithm/
> to be marked offline prior to calling the thread detector function and
> eventually rolled back if something fails.
> ---
> src/qemu/qemu_driver.c | 72 +++++++++++++-------------------------------------
> 1 file changed, 18 insertions(+), 54 deletions(-)
>
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 3aa49f2..b377738 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -4684,11 +4684,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;
> @@ -4703,9 +4702,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;
>
> @@ -4716,23 +4712,10 @@ qemuDomainHotplugAddVcpu(virQEMUDriverPtr driver,
>
> vcpuinfo->online = true;
>
> - if (ncpupids < 0)
> - goto cleanup;
> -
> - /* 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;
> + if (qemuDomainDetectVcpuPids(driver, vm, QEMU_ASYNC_JOB_NONE) < 0)
> goto cleanup;
> - }
This can still return zero and an empty cpupids array (eg priv->ncpupids
== 0)...
I think you'll need an extra "if (priv->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);
Thus causing this to return 0 in vcpupid...
>
> if (virDomainNumatuneGetMode(vm->def->numa, -1, &mem_mode) == 0 &&
> mem_mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
> @@ -4742,11 +4725,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);
And not doing the right thing here...
> if (!cgroup_vcpu)
> goto cleanup;
> }
> @@ -4758,26 +4739,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,
here...
> cgroup_vcpu) < 0) {
> goto cleanup;
> }
> }
>
> - if (qemuProcessSetSchedParams(vcpu, cpupids[vcpu],
> + if (qemuProcessSetSchedParams(vcpu, vcpupid,
> vm->def->cputune.nvcpusched,
> vm->def->cputune.vcpusched) < 0)
and here...
> 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;
> @@ -4794,8 +4769,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;
> @@ -4806,30 +4779,23 @@ 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);
Similar comments here regarding the 'priv->ncpupids == 0' handling
(e.g., DetectVcpuPids succeeds, but still returns empty cpupids).
Also, why is this call only made when (rc < 0)?
>
> - if (rc < 0 || ncpupids < 0)
> - goto cleanup;
> + virDomainAuditVcpu(vm, oldvcpus, oldvcpus - 1, "update", rc == 0);
This is auditing qemuMonitorGetCPUInfo rather than qemuMonitorSetCPU ?
John
>
> - /* check if hotunplug has failed */
> - if (ncpupids != oldvcpus - 1) {
> - virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
> - _("qemu didn't unplug vCPU '%u' properly"), vcpu);
> + if (rc < 0)
> goto cleanup;
> - }
>
> - vcpuinfo->online = false;
>
> if (qemuDomainDelCgroupForThread(priv->cgroup,
> VIR_CGROUP_THREAD_VCPU, vcpu) < 0)
> @@ -4840,15 +4806,13 @@ qemuDomainHotplugDelVcpu(virQEMUDriverPtr driver,
> &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;
> }
>
More information about the libvir-list
mailing list