From ab966b9d315a1e81b65525553831cc8806dd7e20 Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Thu, 11 Aug 2022 12:12:35 +0200 Subject: [PATCH] qemu: Enable for vCPUs on hotplug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As advertised in the previous commit, QEMU_SCHED_CORE_VCPUS case is implemented for hotplug case. The implementation is very similar to the cold boot case, except here we fork off for every vCPU (because the implementation is done in qemuProcessSetupVcpu() which is also the function that's called from hotplug code). But that's okay because our hotplug APIs allow hotplugging one device at the time. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2074559 Signed-off-by: Michal Privoznik Reviewed-by: Daniel P. Berrangé --- src/qemu/qemu_hotplug.c | 2 +- src/qemu/qemu_process.c | 61 +++++++++++++++++++++++++++++++++++++++-- src/qemu/qemu_process.h | 3 +- 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index f5d12b4fb3..da92ced2f4 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -6246,7 +6246,7 @@ qemuDomainHotplugAddVcpu(virQEMUDriver *driver, vcpuinfo->online = true; if (vcpupriv->tid > 0 && - qemuProcessSetupVcpu(vm, i) < 0) + qemuProcessSetupVcpu(vm, i, true) < 0) return -1; } diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 6395694e7b..f405326312 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -5797,10 +5797,40 @@ qemuProcessNetworkPrepareDevices(virQEMUDriver *driver, } +struct qemuProcessSetupVcpuSchedCoreHelperData { + pid_t vcpupid; + pid_t dummypid; +}; + +static int +qemuProcessSetupVcpuSchedCoreHelper(pid_t ppid G_GNUC_UNUSED, + void *opaque) +{ + struct qemuProcessSetupVcpuSchedCoreHelperData *data = opaque; + + if (virProcessSchedCoreShareFrom(data->dummypid) < 0) { + virReportSystemError(errno, + _("unable to share scheduling cookie from %lld"), + (long long) data->dummypid); + return -1; + } + + if (virProcessSchedCoreShareTo(data->vcpupid) < 0) { + virReportSystemError(errno, + _("unable to share scheduling cookie to %lld"), + (long long) data->vcpupid); + return -1; + } + + return 0; +} + + /** * qemuProcessSetupVcpu: * @vm: domain object * @vcpuid: id of VCPU to set defaults + * @schedCore: whether to set scheduling group * * This function sets resource properties (cgroups, affinity, scheduler) for a * vCPU. This function expects that the vCPU is online and the vCPU pids were @@ -5810,8 +5840,11 @@ qemuProcessNetworkPrepareDevices(virQEMUDriver *driver, */ int qemuProcessSetupVcpu(virDomainObj *vm, - unsigned int vcpuid) + unsigned int vcpuid, + bool schedCore) { + qemuDomainObjPrivate *priv = vm->privateData; + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(priv->driver); pid_t vcpupid = qemuDomainGetVcpuPid(vm, vcpuid); virDomainVcpuDef *vcpu = virDomainDefGetVcpu(vm->def, vcpuid); virDomainResctrlMonDef *mon = NULL; @@ -5824,6 +5857,30 @@ qemuProcessSetupVcpu(virDomainObj *vm, &vcpu->sched) < 0) return -1; + if (schedCore && + cfg->schedCore == QEMU_SCHED_CORE_VCPUS) { + struct qemuProcessSetupVcpuSchedCoreHelperData data = { .vcpupid = vcpupid, + .dummypid = -1 }; + + for (i = 0; i < virDomainDefGetVcpusMax(vm->def); i++) { + pid_t temptid = qemuDomainGetVcpuPid(vm, i); + + if (temptid > 0) { + data.dummypid = temptid; + break; + } + } + + if (data.dummypid == -1) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unable to find a vCPU that is online")); + return -1; + } + + if (virProcessRunInFork(qemuProcessSetupVcpuSchedCoreHelper, &data) < 0) + return -1; + } + for (i = 0; i < vm->def->nresctrls; i++) { size_t j = 0; virDomainResctrlDef *ct = vm->def->resctrls[i]; @@ -5930,7 +5987,7 @@ qemuProcessSetupVcpus(virDomainObj *vm) if (!vcpu->online) continue; - if (qemuProcessSetupVcpu(vm, i) < 0) + if (qemuProcessSetupVcpu(vm, i, false) < 0) return -1; } diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index 421efc6016..4dfb2485c0 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -187,7 +187,8 @@ int qemuConnectAgent(virQEMUDriver *driver, virDomainObj *vm); int qemuProcessSetupVcpu(virDomainObj *vm, - unsigned int vcpuid); + unsigned int vcpuid, + bool schedCore); int qemuProcessSetupIOThread(virDomainObj *vm, virDomainIOThreadIDDef *iothread);