Avoid grabbing the whole virCapsPtr object when we only need the
host CPU information.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
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 ae6facc829..1fe310e16c 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13354,7 +13354,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,
@@ -13365,10 +13365,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 cc89ff8571..3a3860b1a3 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:
@@ -7803,20 +7799,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
@@ -7825,20 +7821,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
@@ -7846,16 +7842,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 fb9b85747a..6fd121855d 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);
--
2.23.0