qemu: use NUMA capabilities object directly

Avoid grabbing the whole virCapsPtr object when we only need the
NUMA information.

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2019-11-29 10:40:39 +00:00
parent 6cc992bd1a
commit 1a1d848694
6 changed files with 57 additions and 41 deletions

View File

@ -1032,13 +1032,6 @@ virQEMUCapsInit(virFileCachePtr cache)
true, true)) == NULL) true, true)) == NULL)
goto error; goto error;
/* Some machines have problematic NUMA topology causing
* unexpected failures. We don't want to break the QEMU
* driver in this scenario, so log errors & carry on
*/
if (!(caps->host.numa = virCapabilitiesHostNUMANewHost()))
goto error;
if (virCapabilitiesInitCaches(caps) < 0) if (virCapabilitiesInitCaches(caps) < 0)
VIR_WARN("Failed to get host CPU cache info"); VIR_WARN("Failed to get host CPU cache info");

View File

@ -1204,6 +1204,22 @@ virQEMUDriverCreateXMLConf(virQEMUDriverPtr driver,
} }
virCapsHostNUMAPtr
virQEMUDriverGetHostNUMACaps(virQEMUDriverPtr driver)
{
qemuDriverLock(driver);
if (!driver->hostnuma)
driver->hostnuma = virCapabilitiesHostNUMANewHost();
qemuDriverUnlock(driver);
virCapabilitiesHostNUMARef(driver->hostnuma);
return driver->hostnuma;
}
virCapsPtr virQEMUDriverCreateCapabilities(virQEMUDriverPtr driver) virCapsPtr virQEMUDriverCreateCapabilities(virQEMUDriverPtr driver)
{ {
size_t i, j; size_t i, j;
@ -1255,6 +1271,7 @@ virCapsPtr virQEMUDriverCreateCapabilities(virQEMUDriverPtr driver)
"DOI \"%s\"", model, doi); "DOI \"%s\"", model, doi);
} }
caps->host.numa = virQEMUDriverGetHostNUMACaps(driver);
return g_steal_pointer(&caps); return g_steal_pointer(&caps);
} }

View File

@ -262,6 +262,11 @@ struct _virQEMUDriver {
*/ */
virCapsPtr caps; virCapsPtr caps;
/* Lazy initialized on first use, immutable thereafter.
* Require lock to get the pointer & do optional initialization
*/
virCapsHostNUMAPtr hostnuma;
/* Immutable value */ /* Immutable value */
virArch hostarch; virArch hostarch;
@ -319,6 +324,7 @@ virQEMUDriverConfigSetDefaults(virQEMUDriverConfigPtr cfg);
virQEMUDriverConfigPtr virQEMUDriverGetConfig(virQEMUDriverPtr driver); virQEMUDriverConfigPtr virQEMUDriverGetConfig(virQEMUDriverPtr driver);
bool virQEMUDriverIsPrivileged(virQEMUDriverPtr driver); bool virQEMUDriverIsPrivileged(virQEMUDriverPtr driver);
virCapsHostNUMAPtr virQEMUDriverGetHostNUMACaps(virQEMUDriverPtr driver);
virCapsPtr virQEMUDriverCreateCapabilities(virQEMUDriverPtr driver); virCapsPtr virQEMUDriverCreateCapabilities(virQEMUDriverPtr driver);
virCapsPtr virQEMUDriverGetCapabilities(virQEMUDriverPtr driver, virCapsPtr virQEMUDriverGetCapabilities(virQEMUDriverPtr driver,
bool refresh); bool refresh);

View File

@ -2922,7 +2922,7 @@ qemuDomainObjPrivateXMLParseAutomaticPlacement(xmlXPathContextPtr ctxt,
qemuDomainObjPrivatePtr priv, qemuDomainObjPrivatePtr priv,
virQEMUDriverPtr driver) virQEMUDriverPtr driver)
{ {
virCapsPtr caps = NULL; g_autoptr(virCapsHostNUMA) caps = NULL;
char *nodeset; char *nodeset;
char *cpuset; char *cpuset;
int nodesetSize = 0; int nodesetSize = 0;
@ -2935,15 +2935,15 @@ qemuDomainObjPrivateXMLParseAutomaticPlacement(xmlXPathContextPtr ctxt,
if (!nodeset && !cpuset) if (!nodeset && !cpuset)
return 0; return 0;
if (!(caps = virQEMUDriverGetCapabilities(driver, false))) if (!(caps = virQEMUDriverGetHostNUMACaps(driver)))
goto cleanup; goto cleanup;
/* Figure out how big the nodeset bitmap needs to be. /* Figure out how big the nodeset bitmap needs to be.
* This is necessary because NUMA node IDs are not guaranteed to * This is necessary because NUMA node IDs are not guaranteed to
* start from 0 or be densely allocated */ * start from 0 or be densely allocated */
for (i = 0; i < caps->host.numa->cells->len; i++) { for (i = 0; i < caps->cells->len; i++) {
virCapsHostNUMACellPtr cell = virCapsHostNUMACellPtr cell =
g_ptr_array_index(caps->host.numa->cells, i); g_ptr_array_index(caps->cells, i);
nodesetSize = MAX(nodesetSize, cell->num + 1); nodesetSize = MAX(nodesetSize, cell->num + 1);
} }
@ -2957,7 +2957,7 @@ qemuDomainObjPrivateXMLParseAutomaticPlacement(xmlXPathContextPtr ctxt,
} else { } else {
/* autoNodeset is present in this case, since otherwise we wouldn't /* autoNodeset is present in this case, since otherwise we wouldn't
* reach this code */ * reach this code */
if (!(priv->autoCpuset = virCapabilitiesHostNUMAGetCpus(caps->host.numa, if (!(priv->autoCpuset = virCapabilitiesHostNUMAGetCpus(caps,
priv->autoNodeset))) priv->autoNodeset)))
goto cleanup; goto cleanup;
} }

View File

@ -6129,14 +6129,14 @@ qemuProcessUpdateGuestCPU(virDomainDefPtr def,
static int static int
qemuProcessPrepareDomainNUMAPlacement(virDomainObjPtr vm, qemuProcessPrepareDomainNUMAPlacement(virQEMUDriverPtr driver,
virCapsPtr caps) virDomainObjPtr vm)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
char *nodeset = NULL; g_autofree char *nodeset = NULL;
virBitmapPtr numadNodeset = NULL; g_autoptr(virBitmap) numadNodeset = NULL;
virBitmapPtr hostMemoryNodeset = NULL; g_autoptr(virBitmap) hostMemoryNodeset = NULL;
int ret = -1; g_autoptr(virCapsHostNUMA) caps = NULL;
/* Get the advisory nodeset from numad if 'placement' of /* Get the advisory nodeset from numad if 'placement' of
* either <vcpu> or <numatune> is 'auto'. * either <vcpu> or <numatune> is 'auto'.
@ -6148,33 +6148,30 @@ qemuProcessPrepareDomainNUMAPlacement(virDomainObjPtr vm,
virDomainDefGetMemoryTotal(vm->def)); virDomainDefGetMemoryTotal(vm->def));
if (!nodeset) if (!nodeset)
goto cleanup; return -1;
if (!(hostMemoryNodeset = virNumaGetHostMemoryNodeset())) if (!(hostMemoryNodeset = virNumaGetHostMemoryNodeset()))
goto cleanup; return -1;
VIR_DEBUG("Nodeset returned from numad: %s", nodeset); VIR_DEBUG("Nodeset returned from numad: %s", nodeset);
if (virBitmapParse(nodeset, &numadNodeset, VIR_DOMAIN_CPUMASK_LEN) < 0) if (virBitmapParse(nodeset, &numadNodeset, VIR_DOMAIN_CPUMASK_LEN) < 0)
goto cleanup; return -1;
if (!(caps = virQEMUDriverGetHostNUMACaps(driver)))
return -1;
/* numad may return a nodeset that only contains cpus but cgroups don't play /* numad may return a nodeset that only contains cpus but cgroups don't play
* well with that. Set the autoCpuset from all cpus from that nodeset, but * well with that. Set the autoCpuset from all cpus from that nodeset, but
* assign autoNodeset only with nodes containing memory. */ * assign autoNodeset only with nodes containing memory. */
if (!(priv->autoCpuset = virCapabilitiesHostNUMAGetCpus(caps->host.numa, numadNodeset))) if (!(priv->autoCpuset = virCapabilitiesHostNUMAGetCpus(caps, numadNodeset)))
goto cleanup; return -1;
virBitmapIntersect(numadNodeset, hostMemoryNodeset); virBitmapIntersect(numadNodeset, hostMemoryNodeset);
priv->autoNodeset = g_steal_pointer(&numadNodeset); priv->autoNodeset = g_steal_pointer(&numadNodeset);
ret = 0; return 0;
cleanup:
VIR_FREE(nodeset);
virBitmapFree(numadNodeset);
virBitmapFree(hostMemoryNodeset);
return ret;
} }
@ -6252,10 +6249,6 @@ qemuProcessPrepareDomain(virQEMUDriverPtr driver,
size_t i; size_t i;
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
virCapsPtr caps;
if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
goto cleanup;
priv->machineName = qemuDomainGetMachineName(vm); priv->machineName = qemuDomainGetMachineName(vm);
if (!priv->machineName) if (!priv->machineName)
@ -6271,7 +6264,7 @@ qemuProcessPrepareDomain(virQEMUDriverPtr driver,
} }
virDomainAuditSecurityLabel(vm, true); virDomainAuditSecurityLabel(vm, true);
if (qemuProcessPrepareDomainNUMAPlacement(vm, caps) < 0) if (qemuProcessPrepareDomainNUMAPlacement(driver, vm) < 0)
goto cleanup; goto cleanup;
} }
@ -6359,7 +6352,6 @@ qemuProcessPrepareDomain(virQEMUDriverPtr driver,
ret = 0; ret = 0;
cleanup: cleanup:
virObjectUnref(caps);
virObjectUnref(cfg); virObjectUnref(cfg);
return ret; return ret;
} }

View File

@ -109,6 +109,18 @@ virFindFileInPath(const char *file)
return NULL; return NULL;
} }
virCapsHostNUMAPtr
virCapabilitiesHostNUMANewHost(void)
{
/*
* Build a NUMA topology with cell_id (NUMA node id
* being 3(0 + 3),4(1 + 3), 5 and 6
*/
return virTestCapsBuildNUMATopology(3);
}
static int static int
testQemuAddGuest(virCapsPtr caps, testQemuAddGuest(virCapsPtr caps,
virArch arch) virArch arch)
@ -201,11 +213,7 @@ virCapsPtr testQemuCapsInit(void)
qemuTestSetHostCPU(caps, NULL); qemuTestSetHostCPU(caps, NULL);
/* if (!(caps->host.numa = virCapabilitiesHostNUMANewHost()))
* Build a NUMA topology with cell_id (NUMA node id
* being 3(0 + 3),4(1 + 3), 5 and 6
*/
if (!(caps->host.numa = virTestCapsBuildNUMATopology(3)))
goto cleanup; goto cleanup;
for (i = 0; i < VIR_ARCH_LAST; i++) { for (i = 0; i < VIR_ARCH_LAST; i++) {