mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-21 20:15:17 +00:00
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:
parent
6cc992bd1a
commit
1a1d848694
@ -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");
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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++) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user