mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
qemu_command: Introduce qemuBuildThreadContextProps()
The aim of thread-context object is to set affinity on threads that allocate memory for a memory-backend-* object. For instance: -object '{"qom-type":"thread-context","id":"tc-ram-node0","node-affinity":[3]}' \ -object '{"qom-type":"memory-backend-memfd","id":"ram-node0","hugetlb":true,\ "hugetlbsize":2097152,"share":true,"prealloc":true,"prealloc-threads":8,\ "size":15032385536,"host-nodes":[3],"policy":"preferred",\ "prealloc-context":"tc-ram-node0"}' \ allocates 14GiB worth of memory, backed by 2MiB hugepages from host NUMA node 3, using 8 threads. If it weren't for thread-context these threads wouldn't have any affinity and thus theoretically could be scheduled to run on CPUs of different NUMA node (which is what I saw occasionally). Therefore, whenever we are pinning memory (IOW setting host-nodes attribute), we can generate thread-context object with the same affinity. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
This commit is contained in:
parent
d5320907e3
commit
b03386d148
@ -3603,6 +3603,53 @@ qemuBuildMemoryDeviceProps(virQEMUDriverConfig *cfg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
qemuBuildThreadContextProps(virJSONValue **tcProps,
|
||||||
|
virJSONValue **memProps,
|
||||||
|
qemuDomainObjPrivate *priv)
|
||||||
|
{
|
||||||
|
g_autoptr(virJSONValue) props = NULL;
|
||||||
|
virJSONValue *nodemask = NULL;
|
||||||
|
g_autoptr(virJSONValue) nodemaskCopy = NULL;
|
||||||
|
g_autofree char *tcAlias = NULL;
|
||||||
|
const char *memalias = NULL;
|
||||||
|
|
||||||
|
*tcProps = NULL;
|
||||||
|
|
||||||
|
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_THREAD_CONTEXT))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
nodemask = virJSONValueObjectGetArray(*memProps, "host-nodes");
|
||||||
|
if (!nodemask)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memalias = virJSONValueObjectGetString(*memProps, "id");
|
||||||
|
if (!memalias) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("memory device alias is not assigned"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tcAlias = g_strdup_printf("tc-%s", memalias);
|
||||||
|
nodemaskCopy = virJSONValueCopy(nodemask);
|
||||||
|
|
||||||
|
if (virJSONValueObjectAdd(&props,
|
||||||
|
"s:qom-type", "thread-context",
|
||||||
|
"s:id", tcAlias,
|
||||||
|
"a:node-affinity", &nodemaskCopy,
|
||||||
|
NULL) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (virJSONValueObjectAdd(memProps,
|
||||||
|
"s:prealloc-context", tcAlias,
|
||||||
|
NULL) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*tcProps = g_steal_pointer(&props);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
qemuBuildLegacyNicStr(virDomainNetDef *net)
|
qemuBuildLegacyNicStr(virDomainNetDef *net)
|
||||||
{
|
{
|
||||||
|
@ -147,6 +147,11 @@ qemuBuildMemoryDeviceProps(virQEMUDriverConfig *cfg,
|
|||||||
const virDomainDef *def,
|
const virDomainDef *def,
|
||||||
const virDomainMemoryDef *mem);
|
const virDomainMemoryDef *mem);
|
||||||
|
|
||||||
|
int
|
||||||
|
qemuBuildThreadContextProps(virJSONValue **tcProps,
|
||||||
|
virJSONValue **memProps,
|
||||||
|
qemuDomainObjPrivate *priv);
|
||||||
|
|
||||||
/* Current, best practice */
|
/* Current, best practice */
|
||||||
virJSONValue *
|
virJSONValue *
|
||||||
qemuBuildPCIHostdevDevProps(const virDomainDef *def,
|
qemuBuildPCIHostdevDevProps(const virDomainDef *def,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user