caps: Add helpers to convert NUMA nodes to corresponding CPUs

These helpers use the remembered host capabilities to retrieve the cpu
map rather than query the host again. The intended usage for this
helpers is to fix automatic NUMA placement with strict memory alloc. The
code doing the prepare needs to pin the emulator process only to cpus
belonging to a subset of NUMA nodes of the host.
This commit is contained in:
Peter Krempa 2013-07-18 11:21:48 +02:00
parent b7f1c0c387
commit b8b38321e7
4 changed files with 68 additions and 0 deletions

View File

@ -8,6 +8,7 @@ gnulib/lib/gai_strerror.c
gnulib/lib/regcomp.c
src/access/viraccessdriverpolkit.c
src/access/viraccessmanager.c
src/conf/capabilities.c
src/conf/cpu_conf.c
src/conf/device_conf.c
src/conf/domain_conf.c

View File

@ -916,3 +916,67 @@ virCapabilitiesFormatXML(virCapsPtr caps)
return virBufferContentAndReset(&xml);
}
/* get the maximum ID of cpus in the host */
static unsigned int
virCapabilitiesGetHostMaxcpu(virCapsPtr caps)
{
unsigned int maxcpu = 0;
size_t node;
size_t cpu;
for (node = 0; node < caps->host.nnumaCell; node++) {
virCapsHostNUMACellPtr cell = caps->host.numaCell[node];
for (cpu = 0; cpu < cell->ncpus; cpu++) {
if (cell->cpus[cpu].id > maxcpu)
maxcpu = cell->cpus[cpu].id;
}
}
return maxcpu;
}
/* set cpus of a numa node in the bitmask */
static int
virCapabilitiesGetCpusForNode(virCapsPtr caps,
size_t node,
virBitmapPtr cpumask)
{
virCapsHostNUMACellPtr cell = caps->host.numaCell[node];
size_t cpu;
for (cpu = 0; cpu < cell->ncpus; cpu++) {
if (virBitmapSetBit(cpumask, cell->cpus[cpu].id) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Cpu '%u' in node '%zu' is out of range "
"of the provided bitmap"),
cell->cpus[cpu].id, node);
return -1;
}
}
return 0;
}
virBitmapPtr
virCapabilitiesGetCpusForNodemask(virCapsPtr caps,
virBitmapPtr nodemask)
{
virBitmapPtr ret = NULL;
unsigned int maxcpu = virCapabilitiesGetHostMaxcpu(caps);
ssize_t node = -1;
if (!(ret = virBitmapNew(maxcpu + 1)))
return NULL;
while ((node = virBitmapNextSetBit(nodemask, node)) >= 0) {
if (virCapabilitiesGetCpusForNode(caps, node, ret) < 0) {
virBitmapFree(ret);
return NULL;
}
}
return ret;
}

View File

@ -257,5 +257,7 @@ virCapabilitiesDefaultGuestEmulator(virCapsPtr caps,
extern char *
virCapabilitiesFormatXML(virCapsPtr caps);
virBitmapPtr virCapabilitiesGetCpusForNodemask(virCapsPtr caps,
virBitmapPtr nodemask);
#endif /* __VIR_CAPABILITIES_H */

View File

@ -57,6 +57,7 @@ virCapabilitiesDefaultGuestMachine;
virCapabilitiesFormatXML;
virCapabilitiesFreeMachines;
virCapabilitiesFreeNUMAInfo;
virCapabilitiesGetCpusForNodemask;
virCapabilitiesNew;
virCapabilitiesSetHostCPU;