From adf009b48f3958c444c71cb7c5e52c11f7208b57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Fri, 29 Nov 2019 10:40:39 +0000 Subject: [PATCH] qemu: use host CPU object directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid grabbing the whole virCapsPtr object when we only need the host CPU information. Reviewed-by: Michal Privoznik Signed-off-by: Daniel P. Berrangé --- src/qemu/qemu_capabilities.c | 3 -- src/qemu/qemu_conf.c | 17 +++++++++ src/qemu/qemu_conf.h | 6 ++++ src/qemu/qemu_driver.c | 6 ++-- src/qemu/qemu_process.c | 68 +++++++++++++++--------------------- tests/domaincapstest.c | 14 +++----- tests/qemucapabilitiestest.c | 9 ++--- tests/qemuxml2argvtest.c | 8 ++--- tests/testutilsqemu.c | 49 +++++++++++--------------- tests/testutilsqemu.h | 5 ++- 10 files changed, 89 insertions(+), 96 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 16c4331b13..1b395a2570 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -1035,9 +1035,6 @@ virQEMUCapsInit(virFileCachePtr cache) if (virCapabilitiesInitCaches(caps) < 0) VIR_WARN("Failed to get host CPU cache info"); - if (!(caps->host.cpu = virCPUProbeHost(caps->host.arch))) - VIR_WARN("Failed to get host CPU"); - /* Add the power management features of the host */ if (virNodeSuspendGetTargetMask(&caps->host.powerMgmt) < 0) VIR_WARN("Failed to get host power management capabilities"); diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index ba3001ccd0..9df4ae1230 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1220,6 +1220,22 @@ virQEMUDriverGetHostNUMACaps(virQEMUDriverPtr driver) } +virCPUDefPtr +virQEMUDriverGetHostCPU(virQEMUDriverPtr driver) +{ + qemuDriverLock(driver); + + if (!driver->hostcpu) + driver->hostcpu = virCPUProbeHost(virArchFromHost()); + + qemuDriverUnlock(driver); + + virCPUDefRef(driver->hostcpu); + + return driver->hostcpu; +} + + virCapsPtr virQEMUDriverCreateCapabilities(virQEMUDriverPtr driver) { size_t i, j; @@ -1272,6 +1288,7 @@ virCapsPtr virQEMUDriverCreateCapabilities(virQEMUDriverPtr driver) } caps->host.numa = virQEMUDriverGetHostNUMACaps(driver); + caps->host.cpu = virQEMUDriverGetHostCPU(driver); return g_steal_pointer(&caps); } diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 2d03df9171..d2e0bd97e1 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -267,6 +267,11 @@ struct _virQEMUDriver { */ virCapsHostNUMAPtr hostnuma; + /* Lazy initialized on first use, immutable thereafter. + * Require lock to get the pointer & do optional initialization + */ + virCPUDefPtr hostcpu; + /* Immutable value */ virArch hostarch; @@ -325,6 +330,7 @@ virQEMUDriverConfigPtr virQEMUDriverGetConfig(virQEMUDriverPtr driver); bool virQEMUDriverIsPrivileged(virQEMUDriverPtr driver); virCapsHostNUMAPtr virQEMUDriverGetHostNUMACaps(virQEMUDriverPtr driver); +virCPUDefPtr virQEMUDriverGetHostCPU(virQEMUDriverPtr driver); virCapsPtr virQEMUDriverCreateCapabilities(virQEMUDriverPtr driver); virCapsPtr virQEMUDriverGetCapabilities(virQEMUDriverPtr driver, bool refresh); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 4941b255fb..a30a27dbab 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -13360,7 +13360,7 @@ qemuConnectCompareCPU(virConnectPtr conn, unsigned int flags) { virQEMUDriverPtr driver = conn->privateData; - g_autoptr(virCaps) caps = NULL; + g_autoptr(virCPUDef) cpu = NULL; bool failIncompatible; virCheckFlags(VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE, @@ -13371,10 +13371,10 @@ qemuConnectCompareCPU(virConnectPtr conn, failIncompatible = !!(flags & VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE); - if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + if (!(cpu = virQEMUDriverGetHostCPU(driver))) return VIR_CPU_COMPARE_ERROR; - return virCPUCompareXML(driver->hostarch, caps->host.cpu, + return virCPUCompareXML(driver->hostarch, cpu, xmlDesc, failIncompatible); } diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 9b1abc39ff..3325a1c47f 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -5291,12 +5291,13 @@ qemuProcessStartValidateDisks(virDomainObjPtr vm, static int -qemuProcessStartValidateTSC(virDomainObjPtr vm, - virCapsPtr caps) +qemuProcessStartValidateTSC(virQEMUDriverPtr driver, + virDomainObjPtr vm) { size_t i; unsigned long long freq = 0; virHostCPUTscInfoPtr tsc; + g_autoptr(virCPUDef) cpu = NULL; for (i = 0; i < vm->def->clock.ntimers; i++) { virDomainTimerDefPtr timer = vm->def->clock.timers[i]; @@ -5313,12 +5314,13 @@ qemuProcessStartValidateTSC(virDomainObjPtr vm, VIR_DEBUG("Requested TSC frequency %llu Hz", freq); - if (!caps->host.cpu || !caps->host.cpu->tsc) { + cpu = virQEMUDriverGetHostCPU(driver); + if (!cpu || !cpu->tsc) { VIR_DEBUG("Host TSC frequency could not be probed"); return 0; } - tsc = caps->host.cpu->tsc; + tsc = cpu->tsc; VIR_DEBUG("Host TSC frequency %llu Hz, scaling %s", tsc->frequency, virTristateBoolTypeToString(tsc->scaling)); @@ -5356,7 +5358,6 @@ static int qemuProcessStartValidate(virQEMUDriverPtr driver, virDomainObjPtr vm, virQEMUCapsPtr qemuCaps, - virCapsPtr caps, unsigned int flags) { if (!(flags & VIR_QEMU_PROCESS_START_PRETEND)) { @@ -5424,7 +5425,7 @@ qemuProcessStartValidate(virQEMUDriverPtr driver, if (qemuProcessStartValidateDisks(vm, qemuCaps) < 0) return -1; - if (qemuProcessStartValidateTSC(vm, caps) < 0) + if (qemuProcessStartValidateTSC(driver, vm) < 0) return -1; VIR_DEBUG("Checking for any possible (non-fatal) issues"); @@ -5555,7 +5556,6 @@ qemuProcessInit(virQEMUDriverPtr driver, bool migration, unsigned int flags) { - virCapsPtr caps = NULL; qemuDomainObjPrivatePtr priv = vm->privateData; int stopFlags; virCPUDefPtr origCPU = NULL; @@ -5572,9 +5572,6 @@ qemuProcessInit(virQEMUDriverPtr driver, goto cleanup; } - if (!(caps = virQEMUDriverGetCapabilities(driver, false))) - goto cleanup; - /* in case when the post parse callback failed we need to re-run it on the * old config prior we start the VM */ if (vm->def->postParseFailed) { @@ -5592,7 +5589,7 @@ qemuProcessInit(virQEMUDriverPtr driver, if (qemuDomainUpdateCPU(vm, updatedCPU, &origCPU) < 0) goto cleanup; - if (qemuProcessStartValidate(driver, vm, priv->qemuCaps, caps, flags) < 0) + if (qemuProcessStartValidate(driver, vm, priv->qemuCaps, flags) < 0) goto cleanup; /* Do this upfront, so any part of the startup process can add @@ -5632,7 +5629,6 @@ qemuProcessInit(virQEMUDriverPtr driver, cleanup: virCPUDefFree(origCPU); - virObjectUnref(caps); return ret; stop: @@ -7805,20 +7801,20 @@ static int qemuProcessRefreshCPU(virQEMUDriverPtr driver, virDomainObjPtr vm) { - virCapsPtr caps = virQEMUDriverGetCapabilities(driver, false); qemuDomainObjPrivatePtr priv = vm->privateData; - virCPUDefPtr host = NULL; - virCPUDefPtr cpu = NULL; - int ret = -1; + g_autoptr(virCPUDef) host = NULL; + g_autoptr(virCPUDef) hostmig = NULL; + g_autoptr(virCPUDef) cpu = NULL; - if (!caps) - return -1; + if (!virQEMUCapsGuestIsNative(driver->hostarch, vm->def->os.arch)) + return 0; - if (!virQEMUCapsGuestIsNative(driver->hostarch, vm->def->os.arch) || - !caps->host.cpu || - !vm->def->cpu) { - ret = 0; - goto cleanup; + if (!vm->def->cpu) + return 0; + + if (!(host = virQEMUDriverGetHostCPU(driver))) { + virResetLastError(); + return 0; } /* If the domain with a host-model CPU was started by an old libvirt @@ -7827,20 +7823,20 @@ qemuProcessRefreshCPU(virQEMUDriverPtr driver, * running domain. */ if (vm->def->cpu->mode == VIR_CPU_MODE_HOST_MODEL) { - if (!(host = virCPUCopyMigratable(caps->host.cpu->arch, caps->host.cpu))) - goto cleanup; + if (!(hostmig = virCPUCopyMigratable(host->arch, host))) + return -1; - if (!(cpu = virCPUDefCopyWithoutModel(host)) || - virCPUDefCopyModelFilter(cpu, host, false, + if (!(cpu = virCPUDefCopyWithoutModel(hostmig)) || + virCPUDefCopyModelFilter(cpu, hostmig, false, virQEMUCapsCPUFilterFeatures, - &caps->host.cpu->arch) < 0) - goto cleanup; + &host->arch) < 0) + return -1; if (virCPUUpdate(vm->def->os.arch, vm->def->cpu, cpu) < 0) - goto cleanup; + return -1; if (qemuProcessUpdateCPU(driver, vm, QEMU_ASYNC_JOB_NONE) < 0) - goto cleanup; + return -1; } else if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION)) { /* We only try to fix CPUs when the libvirt/QEMU combo used to start * the domain did not know about query-cpu-model-expansion in which @@ -7848,16 +7844,10 @@ qemuProcessRefreshCPU(virQEMUDriverPtr driver, * doesn't know about. */ if (qemuDomainFixupCPUs(vm, &priv->origCPU) < 0) - goto cleanup; + return -1; } - ret = 0; - - cleanup: - virCPUDefFree(cpu); - virCPUDefFree(host); - virObjectUnref(caps); - return ret; + return 0; } diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c index 94e5831706..a4a443b1d6 100644 --- a/tests/domaincapstest.c +++ b/tests/domaincapstest.c @@ -54,8 +54,7 @@ fillStringValues(virDomainCapsStringValuesPtr values, ...) # include "testutilshostcpus.h" static int -fakeHostCPU(virCapsPtr caps, - virArch arch) +fakeHostCPU(virArch arch) { virCPUDefPtr cpu; @@ -66,7 +65,7 @@ fakeHostCPU(virCapsPtr caps, return -1; } - qemuTestSetHostCPU(caps, cpu); + qemuTestSetHostCPU(NULL, arch, cpu); return 0; } @@ -80,17 +79,15 @@ fillQemuCaps(virDomainCapsPtr domCaps, { int ret = -1; char *path = NULL; - virCapsPtr caps = NULL; virQEMUCapsPtr qemuCaps = NULL; virDomainCapsLoaderPtr loader = &domCaps->os.loader; virDomainVirtType virtType; - if (!(caps = virCapabilitiesNew(domCaps->arch, false, false)) || - fakeHostCPU(caps, domCaps->arch) < 0) + if (fakeHostCPU(domCaps->arch) < 0) goto cleanup; path = g_strdup_printf("%s/%s.%s.xml", TEST_QEMU_CAPS_PATH, name, arch); - if (!(qemuCaps = qemuTestParseCapabilities(caps, path))) + if (!(qemuCaps = qemuTestParseCapabilitiesArch(domCaps->arch, path))) goto cleanup; if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) @@ -106,7 +103,7 @@ fillQemuCaps(virDomainCapsPtr domCaps, if (!domCaps->machine) domCaps->machine = g_strdup(virQEMUCapsGetPreferredMachine(qemuCaps, virtType)); - if (virQEMUCapsFillDomainCaps(qemuCaps, caps->host.arch, domCaps, + if (virQEMUCapsFillDomainCaps(qemuCaps, domCaps->arch, domCaps, false, cfg->firmwares, cfg->nfirmwares) < 0) @@ -134,7 +131,6 @@ fillQemuCaps(virDomainCapsPtr domCaps, ret = 0; cleanup: - virObjectUnref(caps); virObjectUnref(qemuCaps); VIR_FREE(path); return ret; diff --git a/tests/qemucapabilitiestest.c b/tests/qemucapabilitiestest.c index 3d3e6b6d57..b38c0f6f65 100644 --- a/tests/qemucapabilitiestest.c +++ b/tests/qemucapabilitiestest.c @@ -144,7 +144,6 @@ testQemuCapsCopy(const void *opaque) int ret = -1; const testQemuData *data = opaque; char *capsFile = NULL; - virCapsPtr caps = NULL; virQEMUCapsPtr orig = NULL; virQEMUCapsPtr copy = NULL; char *actual = NULL; @@ -153,11 +152,8 @@ testQemuCapsCopy(const void *opaque) data->outputDir, data->prefix, data->version, data->archName); - if (!(caps = virCapabilitiesNew(virArchFromString(data->archName), - false, false))) - goto cleanup; - - if (!(orig = qemuTestParseCapabilities(caps, capsFile))) + if (!(orig = qemuTestParseCapabilitiesArch( + virArchFromString(data->archName), capsFile))) goto cleanup; if (!(copy = virQEMUCapsNewCopy(orig))) @@ -173,7 +169,6 @@ testQemuCapsCopy(const void *opaque) cleanup: VIR_FREE(capsFile); - virObjectUnref(caps); virObjectUnref(orig); virObjectUnref(copy); VIR_FREE(actual); diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index fe8fa776be..ba4a92ec0a 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1733,7 +1733,7 @@ mymain(void) DO_TEST_FAILURE("cpu-s390-features", QEMU_CAPS_KVM); qemuTestSetHostArch(&driver, VIR_ARCH_NONE); - qemuTestSetHostCPU(driver.caps, cpuHaswell); + qemuTestSetHostCPU(&driver, driver.hostarch, cpuHaswell); DO_TEST("cpu-Haswell", QEMU_CAPS_KVM); DO_TEST("cpu-Haswell2", QEMU_CAPS_KVM); DO_TEST("cpu-Haswell3", QEMU_CAPS_KVM); @@ -1744,7 +1744,7 @@ mymain(void) DO_TEST_CAPS_VER("cpu-tsc-frequency", "4.0.0"); DO_TEST_CAPS_VER("cpu-translation", "4.0.0"); DO_TEST_CAPS_LATEST("cpu-translation"); - qemuTestSetHostCPU(driver.caps, NULL); + qemuTestSetHostCPU(&driver, driver.hostarch, NULL); DO_TEST("encrypted-disk", QEMU_CAPS_QCOW2_LUKS, QEMU_CAPS_OBJECT_SECRET); DO_TEST("encrypted-disk-usage", QEMU_CAPS_QCOW2_LUKS, QEMU_CAPS_OBJECT_SECRET); @@ -1873,12 +1873,12 @@ mymain(void) QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, QEMU_CAPS_KVM); - qemuTestSetHostCPU(driver.caps, cpuPower9); + qemuTestSetHostCPU(&driver, driver.hostarch, cpuPower9); DO_TEST("pseries-cpu-compat-power9", QEMU_CAPS_KVM, QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE, QEMU_CAPS_DEVICE_SPAPR_VTY); - qemuTestSetHostCPU(driver.caps, NULL); + qemuTestSetHostCPU(&driver, driver.hostarch, NULL); qemuTestSetHostArch(&driver, VIR_ARCH_NONE); diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c index c01bbdd1a0..f0c2dbf50e 100644 --- a/tests/testutilsqemu.c +++ b/tests/testutilsqemu.c @@ -205,14 +205,6 @@ virCapsPtr testQemuCapsInit(void) caps->host.secModels[0].model = g_strdup("none"); caps->host.secModels[0].doi = g_strdup("0"); - if (!(cpuDefault = virCPUDefCopy(&cpuDefaultData)) || - !(cpuHaswell = virCPUDefCopy(&cpuHaswellData)) || - !(cpuPower8 = virCPUDefCopy(&cpuPower8Data)) || - !(cpuPower9 = virCPUDefCopy(&cpuPower9Data))) - goto cleanup; - - qemuTestSetHostCPU(caps, NULL); - if (!(caps->host.numa = virCapabilitiesHostNUMANewHost())) goto cleanup; @@ -237,9 +229,6 @@ virCapsPtr testQemuCapsInit(void) cleanup: caps->host.cpu = NULL; - virCPUDefFree(cpuDefault); - virCPUDefFree(cpuHaswell); - virCPUDefFree(cpuPower8); virObjectUnref(caps); return NULL; } @@ -255,16 +244,15 @@ qemuTestSetHostArch(virQEMUDriverPtr driver, virTestHostArch = arch; driver->hostarch = virArchFromHost(); driver->caps->host.arch = virArchFromHost(); - qemuTestSetHostCPU(driver->caps, NULL); + qemuTestSetHostCPU(driver, arch, NULL); } void -qemuTestSetHostCPU(virCapsPtr caps, +qemuTestSetHostCPU(virQEMUDriverPtr driver, + virArch arch, virCPUDefPtr cpu) { - virArch arch = caps->host.arch; - if (!cpu) { if (ARCH_IS_X86(arch)) cpu = cpuDefault; @@ -274,11 +262,19 @@ qemuTestSetHostCPU(virCapsPtr caps, unsetenv("VIR_TEST_MOCK_FAKE_HOST_CPU"); if (cpu) { - caps->host.arch = cpu->arch; if (cpu->model) setenv("VIR_TEST_MOCK_FAKE_HOST_CPU", cpu->model, 1); } - caps->host.cpu = cpu; + if (driver) { + if (cpu) + driver->caps->host.arch = cpu->arch; + driver->caps->host.cpu = cpu; + + virCPUDefFree(driver->hostcpu); + if (cpu) + virCPUDefRef(cpu); + driver->hostcpu = cpu; + } } @@ -300,17 +296,6 @@ qemuTestParseCapabilitiesArch(virArch arch, } -virQEMUCapsPtr -qemuTestParseCapabilities(virCapsPtr caps, - const char *capsFile) -{ - if (!caps) - return NULL; - - return qemuTestParseCapabilitiesArch(caps->host.arch, capsFile); -} - - void qemuTestDriverFree(virQEMUDriver *driver) { virMutexDestroy(&driver->lock); @@ -382,6 +367,12 @@ int qemuTestDriverInit(virQEMUDriver *driver) memset(driver, 0, sizeof(*driver)); + if (!(cpuDefault = virCPUDefCopy(&cpuDefaultData)) || + !(cpuHaswell = virCPUDefCopy(&cpuHaswellData)) || + !(cpuPower8 = virCPUDefCopy(&cpuPower8Data)) || + !(cpuPower9 = virCPUDefCopy(&cpuPower9Data))) + return -1; + if (virMutexInit(&driver->lock) < 0) return -1; @@ -439,6 +430,8 @@ int qemuTestDriverInit(virQEMUDriver *driver) if (!(driver->securityManager = virSecurityManagerNewStack(mgr))) goto error; + qemuTestSetHostCPU(driver, driver->hostarch, NULL); + return 0; error: diff --git a/tests/testutilsqemu.h b/tests/testutilsqemu.h index 8dcc930ac3..edee6e450c 100644 --- a/tests/testutilsqemu.h +++ b/tests/testutilsqemu.h @@ -72,8 +72,6 @@ virDomainXMLOptionPtr testQemuXMLConfInit(void); virQEMUCapsPtr qemuTestParseCapabilitiesArch(virArch arch, const char *capsFile); -virQEMUCapsPtr qemuTestParseCapabilities(virCapsPtr caps, - const char *capsFile); extern virCPUDefPtr cpuDefault; extern virCPUDefPtr cpuHaswell; @@ -82,7 +80,8 @@ extern virCPUDefPtr cpuPower9; void qemuTestSetHostArch(virQEMUDriverPtr driver, virArch arch); -void qemuTestSetHostCPU(virCapsPtr caps, +void qemuTestSetHostCPU(virQEMUDriverPtr driver, + virArch arch, virCPUDefPtr cpu); int qemuTestDriverInit(virQEMUDriver *driver);