conf: move NUMA capabilities into self contained object

The NUMA cells are stored directly in the virCapsHostPtr
struct. This moves them into their own struct allowing
them to be stored independantly of the rest of the host
capabilities. The change is used as an excuse to switch
the representation to use a GPtrArray too.

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 09:55:59 +00:00
parent bc1676fc2f
commit 6cc992bd1a
21 changed files with 194 additions and 165 deletions

View File

@ -182,14 +182,19 @@ virCapabilitiesFreeStoragePool(virCapsStoragePoolPtr pool)
void void
virCapabilitiesFreeNUMAInfo(virCapsPtr caps) virCapabilitiesHostNUMAUnref(virCapsHostNUMAPtr caps)
{ {
size_t i; if (g_atomic_int_dec_and_test(&caps->refs)) {
g_ptr_array_unref(caps->cells);
for (i = 0; i < caps->host.nnumaCell; i++) VIR_FREE(caps);
virCapabilitiesFreeHostNUMACell(caps->host.numaCell[i]); }
VIR_FREE(caps->host.numaCell); }
caps->host.nnumaCell = 0;
void
virCapabilitiesHostNUMARef(virCapsHostNUMAPtr caps)
{
g_atomic_int_inc(&caps->refs);
} }
static void static void
@ -234,7 +239,8 @@ virCapsDispose(void *object)
VIR_FREE(caps->host.features[i]); VIR_FREE(caps->host.features[i]);
VIR_FREE(caps->host.features); VIR_FREE(caps->host.features);
virCapabilitiesFreeNUMAInfo(caps); if (caps->host.numa)
virCapabilitiesHostNUMAUnref(caps->host.numa);
for (i = 0; i < caps->host.nmigrateTrans; i++) for (i = 0; i < caps->host.nmigrateTrans; i++)
VIR_FREE(caps->host.migrateTrans[i]); VIR_FREE(caps->host.migrateTrans[i]);
@ -320,7 +326,7 @@ virCapabilitiesSetNetPrefix(virCapsPtr caps,
/** /**
* virCapabilitiesAddHostNUMACell: * virCapabilitiesHostNUMAAddCell:
* @caps: capabilities to extend * @caps: capabilities to extend
* @num: ID number of NUMA cell * @num: ID number of NUMA cell
* @mem: Total size of memory in the NUMA node (in KiB) * @mem: Total size of memory in the NUMA node (in KiB)
@ -334,8 +340,8 @@ virCapabilitiesSetNetPrefix(virCapsPtr caps,
* Registers a new NUMA cell for a host, passing in a * Registers a new NUMA cell for a host, passing in a
* array of CPU IDs belonging to the cell * array of CPU IDs belonging to the cell
*/ */
int void
virCapabilitiesAddHostNUMACell(virCapsPtr caps, virCapabilitiesHostNUMAAddCell(virCapsHostNUMAPtr caps,
int num, int num,
unsigned long long mem, unsigned long long mem,
int ncpus, int ncpus,
@ -345,14 +351,7 @@ virCapabilitiesAddHostNUMACell(virCapsPtr caps,
int npageinfo, int npageinfo,
virCapsHostNUMACellPageInfoPtr pageinfo) virCapsHostNUMACellPageInfoPtr pageinfo)
{ {
virCapsHostNUMACellPtr cell; virCapsHostNUMACellPtr cell = g_new0(virCapsHostNUMACell, 1);
if (VIR_RESIZE_N(caps->host.numaCell, caps->host.nnumaCell_max,
caps->host.nnumaCell, 1) < 0)
return -1;
if (VIR_ALLOC(cell) < 0)
return -1;
cell->num = num; cell->num = num;
cell->mem = mem; cell->mem = mem;
@ -363,9 +362,7 @@ virCapabilitiesAddHostNUMACell(virCapsPtr caps,
cell->npageinfo = npageinfo; cell->npageinfo = npageinfo;
cell->pageinfo = pageinfo; cell->pageinfo = pageinfo;
caps->host.numaCell[caps->host.nnumaCell++] = cell; g_ptr_array_add(caps->cells, cell);
return 0;
} }
@ -857,9 +854,8 @@ virCapabilitiesAddStoragePool(virCapsPtr caps,
static int static int
virCapabilitiesFormatNUMATopology(virBufferPtr buf, virCapabilitiesHostNUMAFormat(virCapsHostNUMAPtr caps,
size_t ncells, virBufferPtr buf)
virCapsHostNUMACellPtr *cells)
{ {
size_t i; size_t i;
size_t j; size_t j;
@ -867,48 +863,49 @@ virCapabilitiesFormatNUMATopology(virBufferPtr buf,
virBufferAddLit(buf, "<topology>\n"); virBufferAddLit(buf, "<topology>\n");
virBufferAdjustIndent(buf, 2); virBufferAdjustIndent(buf, 2);
virBufferAsprintf(buf, "<cells num='%zu'>\n", ncells); virBufferAsprintf(buf, "<cells num='%d'>\n", caps->cells->len);
virBufferAdjustIndent(buf, 2); virBufferAdjustIndent(buf, 2);
for (i = 0; i < ncells; i++) { for (i = 0; i < caps->cells->len; i++) {
virBufferAsprintf(buf, "<cell id='%d'>\n", cells[i]->num); virCapsHostNUMACellPtr cell = g_ptr_array_index(caps->cells, i);
virBufferAsprintf(buf, "<cell id='%d'>\n", cell->num);
virBufferAdjustIndent(buf, 2); virBufferAdjustIndent(buf, 2);
/* Print out the numacell memory total if it is available */ /* Print out the numacell memory total if it is available */
if (cells[i]->mem) if (cell->mem)
virBufferAsprintf(buf, "<memory unit='KiB'>%llu</memory>\n", virBufferAsprintf(buf, "<memory unit='KiB'>%llu</memory>\n",
cells[i]->mem); cell->mem);
for (j = 0; j < cells[i]->npageinfo; j++) { for (j = 0; j < cell->npageinfo; j++) {
virBufferAsprintf(buf, "<pages unit='KiB' size='%u'>%llu</pages>\n", virBufferAsprintf(buf, "<pages unit='KiB' size='%u'>%llu</pages>\n",
cells[i]->pageinfo[j].size, cell->pageinfo[j].size,
cells[i]->pageinfo[j].avail); cell->pageinfo[j].avail);
} }
if (cells[i]->nsiblings) { if (cell->nsiblings) {
virBufferAddLit(buf, "<distances>\n"); virBufferAddLit(buf, "<distances>\n");
virBufferAdjustIndent(buf, 2); virBufferAdjustIndent(buf, 2);
for (j = 0; j < cells[i]->nsiblings; j++) { for (j = 0; j < cell->nsiblings; j++) {
virBufferAsprintf(buf, "<sibling id='%d' value='%d'/>\n", virBufferAsprintf(buf, "<sibling id='%d' value='%d'/>\n",
cells[i]->siblings[j].node, cell->siblings[j].node,
cells[i]->siblings[j].distance); cell->siblings[j].distance);
} }
virBufferAdjustIndent(buf, -2); virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</distances>\n"); virBufferAddLit(buf, "</distances>\n");
} }
virBufferAsprintf(buf, "<cpus num='%d'>\n", cells[i]->ncpus); virBufferAsprintf(buf, "<cpus num='%d'>\n", cell->ncpus);
virBufferAdjustIndent(buf, 2); virBufferAdjustIndent(buf, 2);
for (j = 0; j < cells[i]->ncpus; j++) { for (j = 0; j < cell->ncpus; j++) {
virBufferAsprintf(buf, "<cpu id='%d'", cells[i]->cpus[j].id); virBufferAsprintf(buf, "<cpu id='%d'", cell->cpus[j].id);
if (cells[i]->cpus[j].siblings) { if (cell->cpus[j].siblings) {
if (!(siblings = virBitmapFormat(cells[i]->cpus[j].siblings))) if (!(siblings = virBitmapFormat(cell->cpus[j].siblings)))
return -1; return -1;
virBufferAsprintf(buf, virBufferAsprintf(buf,
" socket_id='%d' core_id='%d' siblings='%s'", " socket_id='%d' core_id='%d' siblings='%s'",
cells[i]->cpus[j].socket_id, cell->cpus[j].socket_id,
cells[i]->cpus[j].core_id, cell->cpus[j].core_id,
siblings); siblings);
VIR_FREE(siblings); VIR_FREE(siblings);
} }
@ -1187,9 +1184,8 @@ virCapabilitiesFormatHostXML(virCapsHostPtr host,
virBufferAsprintf(buf, "<netprefix>%s</netprefix>\n", virBufferAsprintf(buf, "<netprefix>%s</netprefix>\n",
host->netprefix); host->netprefix);
if (host->nnumaCell && if (host->numa &&
virCapabilitiesFormatNUMATopology(buf, host->nnumaCell, virCapabilitiesHostNUMAFormat(host->numa, buf) < 0)
host->numaCell) < 0)
goto error; goto error;
if (virCapabilitiesFormatCaches(buf, &host->cache) < 0) if (virCapabilitiesFormatCaches(buf, &host->cache) < 0)
@ -1394,14 +1390,15 @@ virCapabilitiesFormatXML(virCapsPtr caps)
/* get the maximum ID of cpus in the host */ /* get the maximum ID of cpus in the host */
static unsigned int static unsigned int
virCapabilitiesGetHostMaxcpu(virCapsPtr caps) virCapabilitiesHostNUMAGetMaxcpu(virCapsHostNUMAPtr caps)
{ {
unsigned int maxcpu = 0; unsigned int maxcpu = 0;
size_t node; size_t node;
size_t cpu; size_t cpu;
for (node = 0; node < caps->host.nnumaCell; node++) { for (node = 0; node < caps->cells->len; node++) {
virCapsHostNUMACellPtr cell = caps->host.numaCell[node]; virCapsHostNUMACellPtr cell =
g_ptr_array_index(caps->cells, node);
for (cpu = 0; cpu < cell->ncpus; cpu++) { for (cpu = 0; cpu < cell->ncpus; cpu++) {
if (cell->cpus[cpu].id > maxcpu) if (cell->cpus[cpu].id > maxcpu)
@ -1414,19 +1411,19 @@ virCapabilitiesGetHostMaxcpu(virCapsPtr caps)
/* set cpus of a numa node in the bitmask */ /* set cpus of a numa node in the bitmask */
static int static int
virCapabilitiesGetCpusForNode(virCapsPtr caps, virCapabilitiesHostNUMAGetCellCpus(virCapsHostNUMAPtr caps,
size_t node, size_t node,
virBitmapPtr cpumask) virBitmapPtr cpumask)
{ {
virCapsHostNUMACellPtr cell = NULL; virCapsHostNUMACellPtr cell = NULL;
size_t cpu; size_t cpu;
size_t i; size_t i;
/* The numa node numbers can be non-contiguous. Ex: 0,1,16,17. */ /* The numa node numbers can be non-contiguous. Ex: 0,1,16,17. */
for (i = 0; i < caps->host.nnumaCell; i++) { for (i = 0; i < caps->cells->len; i++) {
if (caps->host.numaCell[i]->num == node) { cell = g_ptr_array_index(caps->cells, i);
cell = caps->host.numaCell[i]; if (cell->num == node)
break; break;
} cell = NULL;
} }
for (cpu = 0; cell && cpu < cell->ncpus; cpu++) { for (cpu = 0; cell && cpu < cell->ncpus; cpu++) {
@ -1443,11 +1440,11 @@ virCapabilitiesGetCpusForNode(virCapsPtr caps,
} }
virBitmapPtr virBitmapPtr
virCapabilitiesGetCpusForNodemask(virCapsPtr caps, virCapabilitiesHostNUMAGetCpus(virCapsHostNUMAPtr caps,
virBitmapPtr nodemask) virBitmapPtr nodemask)
{ {
virBitmapPtr ret = NULL; virBitmapPtr ret = NULL;
unsigned int maxcpu = virCapabilitiesGetHostMaxcpu(caps); unsigned int maxcpu = virCapabilitiesHostNUMAGetMaxcpu(caps);
ssize_t node = -1; ssize_t node = -1;
if (!(ret = virBitmapNew(maxcpu + 1))) if (!(ret = virBitmapNew(maxcpu + 1)))
@ -1455,7 +1452,7 @@ virCapabilitiesGetCpusForNodemask(virCapsPtr caps,
while ((node = virBitmapNextSetBit(nodemask, node)) >= 0) { while ((node = virBitmapNextSetBit(nodemask, node)) >= 0) {
if (virCapabilitiesGetCpusForNode(caps, node, ret) < 0) { if (virCapabilitiesHostNUMAGetCellCpus(caps, node, ret) < 0) {
virBitmapFree(ret); virBitmapFree(ret);
return NULL; return NULL;
} }
@ -1591,7 +1588,7 @@ virCapabilitiesGetNUMAPagesInfo(int node,
static int static int
virCapabilitiesInitNUMAFake(virCapsPtr caps) virCapabilitiesHostNUMAInitFake(virCapsHostNUMAPtr caps)
{ {
virNodeInfo nodeinfo; virNodeInfo nodeinfo;
virCapsHostNUMACellCPUPtr cpus; virCapsHostNUMACellCPUPtr cpus;
@ -1631,16 +1628,18 @@ virCapabilitiesInitNUMAFake(virCapsPtr caps)
} }
} }
if (virCapabilitiesAddHostNUMACell(caps, 0, caps = g_new0(virCapsHostNUMA, 1);
nodeinfo.memory, caps->cells = g_ptr_array_new_with_free_func(
(GDestroyNotify)virCapabilitiesFreeHostNUMACell);
virCapabilitiesHostNUMAAddCell(caps, 0,
nodeinfo.memory,
#ifdef __linux__ #ifdef __linux__
onlinecpus, cpus, onlinecpus, cpus,
#else #else
ncpus, cpus, ncpus, cpus,
#endif #endif
0, NULL, 0, NULL,
0, NULL) < 0) 0, NULL);
goto error;
return 0; return 0;
@ -1651,8 +1650,9 @@ virCapabilitiesInitNUMAFake(virCapsPtr caps)
return -1; return -1;
} }
int
virCapabilitiesInitNUMA(virCapsPtr caps) static int
virCapabilitiesHostNUMAInitReal(virCapsHostNUMAPtr caps)
{ {
int n; int n;
unsigned long long memory; unsigned long long memory;
@ -1665,12 +1665,8 @@ virCapabilitiesInitNUMA(virCapsPtr caps)
int ret = -1; int ret = -1;
int ncpus = 0; int ncpus = 0;
int cpu; int cpu;
bool topology_failed = false;
int max_node; int max_node;
if (!virNumaIsAvailable())
return virCapabilitiesInitNUMAFake(caps);
if ((max_node = virNumaGetMaxNode()) < 0) if ((max_node = virNumaGetMaxNode()) < 0)
goto cleanup; goto cleanup;
@ -1690,10 +1686,8 @@ virCapabilitiesInitNUMA(virCapsPtr caps)
for (i = 0; i < virBitmapSize(cpumap); i++) { for (i = 0; i < virBitmapSize(cpumap); i++) {
if (virBitmapIsBitSet(cpumap, i)) { if (virBitmapIsBitSet(cpumap, i)) {
if (virCapabilitiesFillCPUInfo(i, cpus + cpu++) < 0) { if (virCapabilitiesFillCPUInfo(i, cpus + cpu++) < 0)
topology_failed = true; goto cleanup;
virResetLastError();
}
} }
} }
@ -1707,11 +1701,10 @@ virCapabilitiesInitNUMA(virCapsPtr caps)
virNumaGetNodeMemory(n, &memory, NULL); virNumaGetNodeMemory(n, &memory, NULL);
memory >>= 10; memory >>= 10;
if (virCapabilitiesAddHostNUMACell(caps, n, memory, virCapabilitiesHostNUMAAddCell(caps, n, memory,
ncpus, cpus, ncpus, cpus,
nsiblings, siblings, nsiblings, siblings,
npageinfo, pageinfo) < 0) npageinfo, pageinfo);
goto cleanup;
cpus = NULL; cpus = NULL;
siblings = NULL; siblings = NULL;
@ -1723,9 +1716,6 @@ virCapabilitiesInitNUMA(virCapsPtr caps)
ret = 0; ret = 0;
cleanup: cleanup:
if ((topology_failed || ret < 0) && cpus)
virCapabilitiesClearHostNUMACellCPUTopology(cpus, ncpus);
virBitmapFree(cpumap); virBitmapFree(cpumap);
VIR_FREE(cpus); VIR_FREE(cpus);
VIR_FREE(siblings); VIR_FREE(siblings);
@ -1733,6 +1723,44 @@ virCapabilitiesInitNUMA(virCapsPtr caps)
return ret; return ret;
} }
virCapsHostNUMAPtr
virCapabilitiesHostNUMANew(void)
{
virCapsHostNUMAPtr caps = NULL;
caps = g_new0(virCapsHostNUMA, 1);
caps->refs = 1;
caps->cells = g_ptr_array_new_with_free_func(
(GDestroyNotify)virCapabilitiesFreeHostNUMACell);
return caps;
}
virCapsHostNUMAPtr
virCapabilitiesHostNUMANewHost(void)
{
virCapsHostNUMAPtr caps = virCapabilitiesHostNUMANew();
if (virNumaIsAvailable()) {
if (virCapabilitiesHostNUMAInitReal(caps) == 0)
return caps;
virCapabilitiesHostNUMAUnref(caps);
caps = virCapabilitiesHostNUMANew();
VIR_WARN("Failed to query host NUMA topology, faking single NUMA node");
}
if (virCapabilitiesHostNUMAInitFake(caps) < 0) {
virCapabilitiesHostNUMAUnref(caps);
return NULL;
}
return caps;
}
int int
virCapabilitiesInitPages(virCapsPtr caps) virCapabilitiesInitPages(virCapsPtr caps)
{ {

View File

@ -113,6 +113,11 @@ struct _virCapsHostNUMACell {
virCapsHostNUMACellPageInfoPtr pageinfo; virCapsHostNUMACellPageInfoPtr pageinfo;
}; };
struct _virCapsHostNUMA {
gint refs;
GPtrArray *cells;
};
struct _virCapsHostSecModelLabel { struct _virCapsHostSecModelLabel {
char *type; char *type;
char *label; char *label;
@ -168,9 +173,8 @@ struct _virCapsHost {
size_t nmigrateTrans; size_t nmigrateTrans;
size_t nmigrateTrans_max; size_t nmigrateTrans_max;
char **migrateTrans; char **migrateTrans;
size_t nnumaCell;
size_t nnumaCell_max; virCapsHostNUMAPtr numa;
virCapsHostNUMACellPtr *numaCell;
virResctrlInfoPtr resctrl; virResctrlInfoPtr resctrl;
@ -225,7 +229,11 @@ virCapabilitiesNew(virArch hostarch,
bool liveMigrate); bool liveMigrate);
void void
virCapabilitiesFreeNUMAInfo(virCapsPtr caps); virCapabilitiesHostNUMAUnref(virCapsHostNUMAPtr caps);
void
virCapabilitiesHostNUMARef(virCapsHostNUMAPtr caps);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCapsHostNUMA, virCapabilitiesHostNUMAUnref);
int int
virCapabilitiesAddHostFeature(virCapsPtr caps, virCapabilitiesAddHostFeature(virCapsPtr caps,
@ -239,8 +247,8 @@ int
virCapabilitiesSetNetPrefix(virCapsPtr caps, virCapabilitiesSetNetPrefix(virCapsPtr caps,
const char *prefix); const char *prefix);
int void
virCapabilitiesAddHostNUMACell(virCapsPtr caps, virCapabilitiesHostNUMAAddCell(virCapsHostNUMAPtr caps,
int num, int num,
unsigned long long mem, unsigned long long mem,
int ncpus, int ncpus,
@ -323,14 +331,15 @@ virCapabilitiesClearHostNUMACellCPUTopology(virCapsHostNUMACellCPUPtr cpu,
char * char *
virCapabilitiesFormatXML(virCapsPtr caps); virCapabilitiesFormatXML(virCapsPtr caps);
virBitmapPtr virCapabilitiesGetCpusForNodemask(virCapsPtr caps, virBitmapPtr virCapabilitiesHostNUMAGetCpus(virCapsHostNUMAPtr caps,
virBitmapPtr nodemask); virBitmapPtr nodemask);
int virCapabilitiesGetNodeInfo(virNodeInfoPtr nodeinfo); int virCapabilitiesGetNodeInfo(virNodeInfoPtr nodeinfo);
int virCapabilitiesInitPages(virCapsPtr caps); int virCapabilitiesInitPages(virCapsPtr caps);
int virCapabilitiesInitNUMA(virCapsPtr caps); virCapsHostNUMAPtr virCapabilitiesHostNUMANew(void);
virCapsHostNUMAPtr virCapabilitiesHostNUMANewHost(void);
bool virCapsHostCacheBankEquals(virCapsHostCacheBankPtr a, bool virCapsHostCacheBankEquals(virCapsHostCacheBankPtr a,
virCapsHostCacheBankPtr b); virCapsHostCacheBankPtr b);

View File

@ -66,6 +66,9 @@ typedef virCapsHostMemBW *virCapsHostMemBWPtr;
typedef struct _virCapsHostMemBWNode virCapsHostMemBWNode; typedef struct _virCapsHostMemBWNode virCapsHostMemBWNode;
typedef virCapsHostMemBWNode *virCapsHostMemBWNodePtr; typedef virCapsHostMemBWNode *virCapsHostMemBWNodePtr;
typedef struct _virCapsHostNUMA virCapsHostNUMA;
typedef virCapsHostNUMA *virCapsHostNUMAPtr;
typedef struct _virCapsHostNUMACell virCapsHostNUMACell; typedef struct _virCapsHostNUMACell virCapsHostNUMACell;
typedef virCapsHostNUMACell *virCapsHostNUMACellPtr; typedef virCapsHostNUMACell *virCapsHostNUMACellPtr;

View File

@ -49,7 +49,6 @@ virCapabilitiesAddGuestFeature;
virCapabilitiesAddGuestFeatureWithToggle; virCapabilitiesAddGuestFeatureWithToggle;
virCapabilitiesAddHostFeature; virCapabilitiesAddHostFeature;
virCapabilitiesAddHostMigrateTransport; virCapabilitiesAddHostMigrateTransport;
virCapabilitiesAddHostNUMACell;
virCapabilitiesAddStoragePool; virCapabilitiesAddStoragePool;
virCapabilitiesAllocMachines; virCapabilitiesAllocMachines;
virCapabilitiesClearHostNUMACellCPUTopology; virCapabilitiesClearHostNUMACellCPUTopology;
@ -58,13 +57,16 @@ virCapabilitiesDomainSupported;
virCapabilitiesFormatXML; virCapabilitiesFormatXML;
virCapabilitiesFreeGuest; virCapabilitiesFreeGuest;
virCapabilitiesFreeMachines; virCapabilitiesFreeMachines;
virCapabilitiesFreeNUMAInfo;
virCapabilitiesGetCpusForNodemask;
virCapabilitiesGetNodeInfo; virCapabilitiesGetNodeInfo;
virCapabilitiesHostInitIOMMU; virCapabilitiesHostInitIOMMU;
virCapabilitiesHostNUMAAddCell;
virCapabilitiesHostNUMAGetCpus;
virCapabilitiesHostNUMANew;
virCapabilitiesHostNUMANewHost;
virCapabilitiesHostNUMARef;
virCapabilitiesHostNUMAUnref;
virCapabilitiesHostSecModelAddBaseLabel; virCapabilitiesHostSecModelAddBaseLabel;
virCapabilitiesInitCaches; virCapabilitiesInitCaches;
virCapabilitiesInitNUMA;
virCapabilitiesInitPages; virCapabilitiesInitPages;
virCapabilitiesNew; virCapabilitiesNew;
virCapabilitiesSetHostCPU; virCapabilitiesSetHostCPU;

View File

@ -320,6 +320,7 @@ libxlCapsInitNuma(libxl_ctx *ctx, virCapsPtr caps)
} }
} }
caps->host.numa = virCapabilitiesHostNUMANew();
for (i = 0; i < nr_nodes; i++) { for (i = 0; i < nr_nodes; i++) {
if (numa_info[i].size == LIBXL_NUMAINFO_INVALID_ENTRY) if (numa_info[i].size == LIBXL_NUMAINFO_INVALID_ENTRY)
continue; continue;
@ -337,15 +338,11 @@ libxlCapsInitNuma(libxl_ctx *ctx, virCapsPtr caps)
} }
} }
if (virCapabilitiesAddHostNUMACell(caps, i, virCapabilitiesHostNUMAAddCell(caps->host.numa, i,
numa_info[i].size / 1024, numa_info[i].size / 1024,
nr_cpus_node[i], cpus[i], nr_cpus_node[i], cpus[i],
nr_siblings, siblings, nr_siblings, siblings,
0, NULL) < 0) { 0, NULL);
virCapabilitiesClearHostNUMACellCPUTopology(cpus[i],
nr_cpus_node[i]);
goto cleanup;
}
/* This is safe, as the CPU list is now stored in the NUMA cell */ /* This is safe, as the CPU list is now stored in the NUMA cell */
cpus[i] = NULL; cpus[i] = NULL;
@ -357,7 +354,10 @@ libxlCapsInitNuma(libxl_ctx *ctx, virCapsPtr caps)
if (ret != 0) { if (ret != 0) {
for (i = 0; cpus && i < nr_nodes; i++) for (i = 0; cpus && i < nr_nodes; i++)
VIR_FREE(cpus[i]); VIR_FREE(cpus[i]);
virCapabilitiesFreeNUMAInfo(caps); if (caps->host.numa) {
virCapabilitiesHostNUMAUnref(caps->host.numa);
caps->host.numa = NULL;
}
VIR_FREE(siblings); VIR_FREE(siblings);
} }

View File

@ -70,10 +70,8 @@ virCapsPtr virLXCDriverCapsInit(virLXCDriverPtr driver)
* unexpected failures. We don't want to break the lxc * unexpected failures. We don't want to break the lxc
* driver in this scenario, so log errors & carry on * driver in this scenario, so log errors & carry on
*/ */
if (virCapabilitiesInitNUMA(caps) < 0) { if (!(caps->host.numa = virCapabilitiesHostNUMANewHost()))
virCapabilitiesFreeNUMAInfo(caps); goto error;
VIR_WARN("Failed to query host NUMA topology, disabling NUMA capabilities");
}
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

@ -155,7 +155,7 @@ virCapsPtr openvzCapsInit(void)
false, false)) == NULL) false, false)) == NULL)
goto no_memory; goto no_memory;
if (virCapabilitiesInitNUMA(caps) < 0) if (!(caps->host.numa = virCapabilitiesHostNUMANewHost()))
goto no_memory; goto no_memory;
if (virCapabilitiesInitCaches(caps) < 0) if (virCapabilitiesInitCaches(caps) < 0)

View File

@ -322,11 +322,8 @@ phypCapsInit(void)
* unexpected failures. We don't want to break the QEMU * unexpected failures. We don't want to break the QEMU
* driver in this scenario, so log errors & carry on * driver in this scenario, so log errors & carry on
*/ */
if (virCapabilitiesInitNUMA(caps) < 0) { if (!(caps->host.numa = virCapabilitiesHostNUMANewHost()))
virCapabilitiesFreeNUMAInfo(caps); goto no_memory;
VIR_WARN
("Failed to query host NUMA topology, disabling NUMA capabilities");
}
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

@ -1036,10 +1036,8 @@ virQEMUCapsInit(virFileCachePtr cache)
* unexpected failures. We don't want to break the QEMU * unexpected failures. We don't want to break the QEMU
* driver in this scenario, so log errors & carry on * driver in this scenario, so log errors & carry on
*/ */
if (virCapabilitiesInitNUMA(caps) < 0) { if (!(caps->host.numa = virCapabilitiesHostNUMANewHost()))
virCapabilitiesFreeNUMAInfo(caps); goto error;
VIR_WARN("Failed to query host NUMA topology, disabling NUMA capabilities");
}
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

@ -2941,8 +2941,11 @@ qemuDomainObjPrivateXMLParseAutomaticPlacement(xmlXPathContextPtr ctxt,
/* 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.nnumaCell; i++) for (i = 0; i < caps->host.numa->cells->len; i++) {
nodesetSize = MAX(nodesetSize, caps->host.numaCell[i]->num + 1); virCapsHostNUMACellPtr cell =
g_ptr_array_index(caps->host.numa->cells, i);
nodesetSize = MAX(nodesetSize, cell->num + 1);
}
if (nodeset && if (nodeset &&
virBitmapParse(nodeset, &priv->autoNodeset, nodesetSize) < 0) virBitmapParse(nodeset, &priv->autoNodeset, nodesetSize) < 0)
@ -2954,8 +2957,8 @@ 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 = virCapabilitiesGetCpusForNodemask(caps, if (!(priv->autoCpuset = virCapabilitiesHostNUMAGetCpus(caps->host.numa,
priv->autoNodeset))) priv->autoNodeset)))
goto cleanup; goto cleanup;
} }

View File

@ -4838,16 +4838,12 @@ qemuMigrationDstPersist(virQEMUDriverPtr driver,
{ {
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
virCapsPtr caps = NULL;
virDomainDefPtr vmdef; virDomainDefPtr vmdef;
virDomainDefPtr oldDef = NULL; virDomainDefPtr oldDef = NULL;
unsigned int oldPersist = vm->persistent; unsigned int oldPersist = vm->persistent;
virObjectEventPtr event; virObjectEventPtr event;
int ret = -1; int ret = -1;
if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
goto cleanup;
vm->persistent = 1; vm->persistent = 1;
oldDef = vm->newDef; oldDef = vm->newDef;
vm->newDef = qemuMigrationCookieGetPersistent(mig); vm->newDef = qemuMigrationCookieGetPersistent(mig);
@ -4871,7 +4867,6 @@ qemuMigrationDstPersist(virQEMUDriverPtr driver,
cleanup: cleanup:
virDomainDefFree(oldDef); virDomainDefFree(oldDef);
virObjectUnref(caps);
virObjectUnref(cfg); virObjectUnref(cfg);
return ret; return ret;

View File

@ -6161,7 +6161,7 @@ qemuProcessPrepareDomainNUMAPlacement(virDomainObjPtr vm,
/* 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 = virCapabilitiesGetCpusForNodemask(caps, numadNodeset))) if (!(priv->autoCpuset = virCapabilitiesHostNUMAGetCpus(caps->host.numa, numadNodeset)))
goto cleanup; goto cleanup;
virBitmapIntersect(numadNodeset, hostMemoryNodeset); virBitmapIntersect(numadNodeset, hostMemoryNodeset);

View File

@ -302,6 +302,7 @@ testBuildCapabilities(virConnectPtr conn)
caps->host.pagesSize[caps->host.nPagesSize++] = 2048; caps->host.pagesSize[caps->host.nPagesSize++] = 2048;
caps->host.pagesSize[caps->host.nPagesSize++] = 1024 * 1024; caps->host.pagesSize[caps->host.nPagesSize++] = 1024 * 1024;
caps->host.numa = virCapabilitiesHostNUMANew();
for (i = 0; i < privconn->numCells; i++) { for (i = 0; i < privconn->numCells; i++) {
virCapsHostNUMACellCPUPtr cpu_cells; virCapsHostNUMACellCPUPtr cpu_cells;
virCapsHostNUMACellPageInfoPtr pages; virCapsHostNUMACellPageInfoPtr pages;
@ -326,10 +327,10 @@ testBuildCapabilities(virConnectPtr conn)
pages[0].avail = privconn->cells[i].mem / pages[0].size; pages[0].avail = privconn->cells[i].mem / pages[0].size;
if (virCapabilitiesAddHostNUMACell(caps, i, privconn->cells[i].mem, virCapabilitiesHostNUMAAddCell(caps->host.numa,
privconn->cells[i].numCpus, i, privconn->cells[i].mem,
cpu_cells, 0, NULL, nPages, pages) < 0) privconn->cells[i].numCpus,
goto error; cpu_cells, 0, NULL, nPages, pages);
} }
for (i = 0; i < G_N_ELEMENTS(guest_types); i++) { for (i = 0; i < G_N_ELEMENTS(guest_types); i++) {

View File

@ -76,7 +76,7 @@ vboxCapsInit(void)
false, false)) == NULL) false, false)) == NULL)
goto no_memory; goto no_memory;
if (virCapabilitiesInitNUMA(caps) < 0) if (!(caps->host.numa = virCapabilitiesHostNUMANewHost()))
goto no_memory; goto no_memory;
if (virCapabilitiesInitCaches(caps) < 0) if (virCapabilitiesInitCaches(caps) < 0)

View File

@ -71,7 +71,7 @@ vmwareCapsInit(void)
false, false)) == NULL) false, false)) == NULL)
goto error; goto error;
if (virCapabilitiesInitNUMA(caps) < 0) if (!(caps->host.numa = virCapabilitiesHostNUMANewHost()))
goto error; goto error;
if (virCapabilitiesInitCaches(caps) < 0) if (virCapabilitiesInitCaches(caps) < 0)

View File

@ -116,7 +116,7 @@ vzBuildCapabilities(void)
false, false)) == NULL) false, false)) == NULL)
return NULL; return NULL;
if (virCapabilitiesInitNUMA(caps) < 0) if (!(caps->host.numa = virCapabilitiesHostNUMANewHost()))
goto error; goto error;
if (virCapabilitiesInitCaches(caps) < 0) if (virCapabilitiesInitCaches(caps) < 0)

View File

@ -1053,10 +1053,10 @@ virCapsPtr virTestGenericCapsInit(void)
* Build NUMA topology with cell id starting from (0 + seq) * Build NUMA topology with cell id starting from (0 + seq)
* for testing * for testing
*/ */
int virCapsHostNUMAPtr
virTestCapsBuildNUMATopology(virCapsPtr caps, virTestCapsBuildNUMATopology(int seq)
int seq)
{ {
virCapsHostNUMAPtr caps = virCapabilitiesHostNUMANew();
virCapsHostNUMACellCPUPtr cell_cpus = NULL; virCapsHostNUMACellCPUPtr cell_cpus = NULL;
int core_id, cell_id; int core_id, cell_id;
int id; int id;
@ -1077,22 +1077,21 @@ virTestCapsBuildNUMATopology(virCapsPtr caps,
} }
id++; id++;
if (virCapabilitiesAddHostNUMACell(caps, cell_id + seq, virCapabilitiesHostNUMAAddCell(caps, cell_id + seq,
MAX_MEM_IN_CELL, MAX_MEM_IN_CELL,
MAX_CPUS_IN_CELL, cell_cpus, MAX_CPUS_IN_CELL, cell_cpus,
VIR_ARCH_NONE, NULL, VIR_ARCH_NONE, NULL,
VIR_ARCH_NONE, NULL) < 0) VIR_ARCH_NONE, NULL);
goto error;
cell_cpus = NULL; cell_cpus = NULL;
} }
return 0; return caps;
error: error:
virCapabilitiesClearHostNUMACellCPUTopology(cell_cpus, MAX_CPUS_IN_CELL); virCapabilitiesHostNUMAUnref(caps);
VIR_FREE(cell_cpus); VIR_FREE(cell_cpus);
return -1; return NULL;
} }
static virDomainDefParserConfig virTestGenericDomainDefParserConfig = { static virDomainDefParserConfig virTestGenericDomainDefParserConfig = {

View File

@ -157,8 +157,7 @@ int virTestMain(int argc,
#define VIR_TEST_MOCK(mock) (abs_builddir "/.libs/lib" mock "mock" MOCK_EXT) #define VIR_TEST_MOCK(mock) (abs_builddir "/.libs/lib" mock "mock" MOCK_EXT)
virCapsPtr virTestGenericCapsInit(void); virCapsPtr virTestGenericCapsInit(void);
int virTestCapsBuildNUMATopology(virCapsPtr caps, virCapsHostNUMAPtr virTestCapsBuildNUMATopology(int seq);
int seq);
virDomainXMLOptionPtr virTestGenericDomainXMLConfInit(void); virDomainXMLOptionPtr virTestGenericDomainXMLConfInit(void);
typedef enum { typedef enum {

View File

@ -205,7 +205,7 @@ virCapsPtr testQemuCapsInit(void)
* Build a NUMA topology with cell_id (NUMA node id * Build a NUMA topology with cell_id (NUMA node id
* being 3(0 + 3),4(1 + 3), 5 and 6 * being 3(0 + 3),4(1 + 3), 5 and 6
*/ */
if (virTestCapsBuildNUMATopology(caps, 3) < 0) 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++) {

View File

@ -58,8 +58,10 @@ test_virCapabilities(const void *opaque)
if (!caps) if (!caps)
goto cleanup; goto cleanup;
if (virCapabilitiesInitNUMA(caps) < 0 || if (!(caps->host.numa = virCapabilitiesHostNUMANewHost()))
virCapabilitiesInitCaches(caps) < 0) goto cleanup;
if (virCapabilitiesInitCaches(caps) < 0)
goto cleanup; goto cleanup;
virFileWrapperClearPrefixes(); virFileWrapperClearPrefixes();

View File

@ -35,27 +35,22 @@ test_virCapabilitiesGetCpusForNodemask(const void *data G_GNUC_UNUSED)
const char *nodestr = "3,4,5,6"; const char *nodestr = "3,4,5,6";
virBitmapPtr nodemask = NULL; virBitmapPtr nodemask = NULL;
virBitmapPtr cpumap = NULL; virBitmapPtr cpumap = NULL;
virCapsPtr caps = NULL; g_autoptr(virCapsHostNUMA) caps = NULL;
int mask_size = 8; int mask_size = 8;
int ret = -1; int ret = -1;
if (!(caps = virTestCapsBuildNUMATopology(3)))
if (!(caps = virCapabilitiesNew(VIR_ARCH_X86_64, false, false)))
goto error;
if (virTestCapsBuildNUMATopology(caps, 3) < 0)
goto error; goto error;
if (virBitmapParse(nodestr, &nodemask, mask_size) < 0) if (virBitmapParse(nodestr, &nodemask, mask_size) < 0)
goto error; goto error;
if (!(cpumap = virCapabilitiesGetCpusForNodemask(caps, nodemask))) if (!(cpumap = virCapabilitiesHostNUMAGetCpus(caps, nodemask)))
goto error; goto error;
ret = 0; ret = 0;
error: error:
virObjectUnref(caps);
virBitmapFree(nodemask); virBitmapFree(nodemask);
virBitmapFree(cpumap); virBitmapFree(cpumap);
return ret; return ret;