void
virCPUDefFree(virCPUDefPtr def)
{
- size_t i;
-
if (!def)
return;
virCPUDefFreeModel(def);
- for (i = 0; i < def->ncells; i++)
- virBitmapFree(def->cells[i].cpumask);
- VIR_FREE(def->cells);
VIR_FREE(def->vendor_id);
VIR_FREE(def);
virCPUDefCopy(const virCPUDef *cpu)
{
virCPUDefPtr copy;
- size_t i;
if (!cpu || VIR_ALLOC(copy) < 0)
return NULL;
if (virCPUDefCopyModel(copy, cpu, false) < 0)
goto error;
- if (cpu->ncells) {
- if (VIR_ALLOC_N(copy->cells, cpu->ncells) < 0)
- goto error;
-
- for (i = 0; i < cpu->ncells; i++) {
- copy->cells[i].mem = cpu->cells[i].mem;
-
- copy->cells[i].cpumask = virBitmapNewCopy(cpu->cells[i].cpumask);
-
- if (!copy->cells[i].cpumask)
- goto error;
- }
- }
-
return copy;
error:
char *
virCPUDefFormat(virCPUDefPtr def,
+ virDomainNumaPtr numa,
bool updateCPU)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
- if (virCPUDefFormatBufFull(&buf, def, updateCPU) < 0)
+ if (virCPUDefFormatBufFull(&buf, def, numa, updateCPU) < 0)
goto cleanup;
if (virBufferCheckError(&buf) < 0)
int
virCPUDefFormatBufFull(virBufferPtr buf,
virCPUDefPtr def,
+ virDomainNumaPtr numa,
bool updateCPU)
{
if (!def)
if (virCPUDefFormatBuf(buf, def, updateCPU) < 0)
return -1;
- if (virDomainNumaDefCPUFormat(buf, def) < 0)
+ if (virDomainNumaDefCPUFormat(buf, numa) < 0)
return -1;
virBufferAdjustIndent(buf, -2);
# include "virxml.h"
# include "virbitmap.h"
# include "virarch.h"
+# include "numa_conf.h"
# define VIR_CPU_VENDOR_ID_LENGTH 12
int policy; /* enum virCPUFeaturePolicy */
};
-typedef struct _virCellDef virCellDef;
-typedef virCellDef *virCellDefPtr;
-struct _virCellDef {
- virBitmapPtr cpumask; /* CPUs that are part of this node */
- unsigned long long mem; /* Node memory in kB */
- int memAccess; /* virNumaMemAccess */
-};
typedef struct _virCPUDef virCPUDef;
typedef virCPUDef *virCPUDefPtr;
size_t nfeatures;
size_t nfeatures_max;
virCPUFeatureDefPtr features;
- size_t ncells;
- virCellDefPtr cells;
};
char *
virCPUDefFormat(virCPUDefPtr def,
+ virDomainNumaPtr numa,
bool updateCPU);
int
int
virCPUDefFormatBufFull(virBufferPtr buf,
virCPUDefPtr def,
+ virDomainNumaPtr numa,
bool updateCPU);
int
}
- if (virDomainNumaDefCPUParseXML(def->cpu, ctxt) < 0)
+ if (virDomainNumaDefCPUParseXML(def->numa, ctxt) < 0)
goto error;
- if (def->cpu &&
- virDomainNumaGetCPUCountTotal(def->cpu) > def->maxvcpus) {
+ if (virDomainNumaGetCPUCountTotal(def->numa) > def->maxvcpus) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Number of CPUs in <numa> exceeds the"
" <vcpu> count"));
if (virDomainNumatuneParseXML(def->numa,
def->placement_mode ==
VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC,
- virDomainNumaGetNodeCount(def->cpu),
ctxt) < 0)
goto error;
virBufferAddLit(buf, "</features>\n");
}
- if (virCPUDefFormatBufFull(buf, def->cpu,
+ if (virCPUDefFormatBufFull(buf, def->cpu, def->numa,
!!(flags & VIR_DOMAIN_DEF_FORMAT_UPDATE_CPU)) < 0)
goto error;
} memory; /* pinning for all the memory */
struct _virDomainNumaNode {
- virBitmapPtr nodeset;
- virDomainNumatuneMemMode mode;
- } *mem_nodes; /* fine tuning per guest node */
+ unsigned long long mem; /* memory size in KiB */
+ virBitmapPtr cpumask; /* bitmap of vCPUs corresponding to the node */
+ virBitmapPtr nodeset; /* host memory nodes where this guest node resides */
+ virDomainNumatuneMemMode mode; /* memory mode selection */
+ virNumaMemAccess memAccess; /* shared memory access configuration */
+ } *mem_nodes; /* guest node configuration */
size_t nmem_nodes;
/* Future NUMA tuning related stuff should go here. */
static int
virDomainNumatuneNodeParseXML(virDomainNumaPtr numa,
- size_t ncells,
xmlXPathContextPtr ctxt)
{
char *tmp = NULL;
goto cleanup;
}
- if (!ncells) {
+ if (!numa->nmem_nodes) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("Element 'memnode' is invalid without "
"any guest NUMA cells"));
goto cleanup;
}
- VIR_FREE(numa->mem_nodes);
- if (VIR_ALLOC_N(numa->mem_nodes, ncells) < 0)
- goto cleanup;
-
- numa->nmem_nodes = ncells;
-
for (i = 0; i < n; i++) {
int mode = 0;
unsigned int cellid = 0;
int
virDomainNumatuneParseXML(virDomainNumaPtr numa,
bool placement_static,
- size_t ncells,
xmlXPathContextPtr ctxt)
{
char *tmp = NULL;
nodeset) < 0)
goto cleanup;
- if (virDomainNumatuneNodeParseXML(numa, ncells, ctxt) < 0)
+ if (virDomainNumatuneNodeParseXML(numa, ctxt) < 0)
goto cleanup;
ret = 0;
return;
virBitmapFree(numa->memory.nodeset);
- for (i = 0; i < numa->nmem_nodes; i++)
+ for (i = 0; i < numa->nmem_nodes; i++) {
+ virBitmapFree(numa->mem_nodes[i].cpumask);
virBitmapFree(numa->mem_nodes[i].nodeset);
+ }
VIR_FREE(numa->mem_nodes);
VIR_FREE(numa);
int
-virDomainNumaDefCPUParseXML(virCPUDefPtr def,
+virDomainNumaDefCPUParseXML(virDomainNumaPtr def,
xmlXPathContextPtr ctxt)
{
xmlNodePtr *nodes = NULL;
goto cleanup;
}
- if (VIR_ALLOC_N(def->cells, n) < 0)
+ if (VIR_ALLOC_N(def->mem_nodes, n) < 0)
goto cleanup;
- def->ncells = n;
+ def->nmem_nodes = n;
for (i = 0; i < n; i++) {
int rc;
}
VIR_FREE(tmp);
- if (def->cells[cur_cell].cpumask) {
+ if (def->mem_nodes[cur_cell].cpumask) {
virReportError(VIR_ERR_XML_ERROR,
_("Duplicate NUMA cell info for cell id '%u'"),
cur_cell);
goto cleanup;
}
- if (virBitmapParse(tmp, 0, &def->cells[cur_cell].cpumask,
+ if (virBitmapParse(tmp, 0, &def->mem_nodes[cur_cell].cpumask,
VIR_DOMAIN_CPUMASK_LEN) < 0)
goto cleanup;
- if (virBitmapIsAllClear(def->cells[cur_cell].cpumask)) {
+ if (virBitmapIsAllClear(def->mem_nodes[cur_cell].cpumask)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("NUMA cell %d has no vCPUs assigned"), cur_cell);
goto cleanup;
ctxt->node = nodes[i];
if (virDomainParseMemory("./@memory", "./@unit", ctxt,
- &def->cells[cur_cell].mem, true, false) < 0)
+ &def->mem_nodes[cur_cell].mem, true, false) < 0)
goto cleanup;
if ((tmp = virXMLPropString(nodes[i], "memAccess"))) {
goto cleanup;
}
- def->cells[cur_cell].memAccess = rc;
+ def->mem_nodes[cur_cell].memAccess = rc;
VIR_FREE(tmp);
}
}
int
virDomainNumaDefCPUFormat(virBufferPtr buf,
- virCPUDefPtr def)
+ virDomainNumaPtr def)
{
virNumaMemAccess memAccess;
char *cpustr;
unsigned int
-virDomainNumaGetCPUCountTotal(virCPUDefPtr numa)
+virDomainNumaGetCPUCountTotal(virDomainNumaPtr numa)
{
size_t i;
unsigned int ret = 0;
- for (i = 0; i < numa->ncells; i++)
+ for (i = 0; i < numa->nmem_nodes; i++)
ret += virBitmapCountBits(virDomainNumaGetNodeCpumask(numa, i));
return ret;
size_t
-virDomainNumaGetNodeCount(virCPUDefPtr numa)
+virDomainNumaGetNodeCount(virDomainNumaPtr numa)
{
if (!numa)
return 0;
- return numa->ncells;
+ return numa->nmem_nodes;
}
virBitmapPtr
-virDomainNumaGetNodeCpumask(virCPUDefPtr numa,
+virDomainNumaGetNodeCpumask(virDomainNumaPtr numa,
size_t node)
{
- return numa->cells[node].cpumask;
+ return numa->mem_nodes[node].cpumask;
}
virNumaMemAccess
-virDomainNumaGetNodeMemoryAccessMode(virCPUDefPtr numa,
+virDomainNumaGetNodeMemoryAccessMode(virDomainNumaPtr numa,
size_t node)
{
- return numa->cells[node].memAccess;
+ return numa->mem_nodes[node].memAccess;
}
unsigned long long
-virDomainNumaGetNodeMemorySize(virCPUDefPtr numa,
+virDomainNumaGetNodeMemorySize(virDomainNumaPtr numa,
size_t node)
{
- return numa->cells[node].mem;
+ return numa->mem_nodes[node].mem;
}
void
-virDomainNumaSetNodeMemorySize(virCPUDefPtr numa,
+virDomainNumaSetNodeMemorySize(virDomainNumaPtr numa,
size_t node,
unsigned long long size)
{
- numa->cells[node].mem = size;
+ numa->mem_nodes[node].mem = size;
}
# include "virutil.h"
# include "virbitmap.h"
# include "virbuffer.h"
-# include "cpu_conf.h"
typedef struct _virDomainNuma virDomainNuma;
*/
int virDomainNumatuneParseXML(virDomainNumaPtr numa,
bool placement_static,
- size_t ncells,
xmlXPathContextPtr ctxt)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4);
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
int virDomainNumatuneFormatXML(virBufferPtr buf, virDomainNumaPtr numatune)
ATTRIBUTE_NONNULL(1);
virBitmapPtr *retNodeset,
int cellid);
-size_t virDomainNumaGetNodeCount(virCPUDefPtr numa)
+size_t virDomainNumaGetNodeCount(virDomainNumaPtr numa)
ATTRIBUTE_NONNULL(1);
-virBitmapPtr virDomainNumaGetNodeCpumask(virCPUDefPtr numa,
+virBitmapPtr virDomainNumaGetNodeCpumask(virDomainNumaPtr numa,
size_t node)
ATTRIBUTE_NONNULL(1);
-virNumaMemAccess virDomainNumaGetNodeMemoryAccessMode(virCPUDefPtr numa,
+virNumaMemAccess virDomainNumaGetNodeMemoryAccessMode(virDomainNumaPtr numa,
size_t node)
ATTRIBUTE_NONNULL(1);
-unsigned long long virDomainNumaGetNodeMemorySize(virCPUDefPtr numa,
+unsigned long long virDomainNumaGetNodeMemorySize(virDomainNumaPtr numa,
size_t node)
ATTRIBUTE_NONNULL(1);
virBitmapPtr nodeset)
ATTRIBUTE_NONNULL(1);
-void virDomainNumaSetNodeMemorySize(virCPUDefPtr numa,
+void virDomainNumaSetNodeMemorySize(virDomainNumaPtr numa,
size_t node,
unsigned long long size)
ATTRIBUTE_NONNULL(1);
bool virDomainNumatuneNodeSpecified(virDomainNumaPtr numatune,
int cellid);
-int virDomainNumaDefCPUParseXML(virCPUDefPtr def, xmlXPathContextPtr ctxt);
-int virDomainNumaDefCPUFormat(virBufferPtr buf, virCPUDefPtr def);
+int virDomainNumaDefCPUParseXML(virDomainNumaPtr def, xmlXPathContextPtr ctxt);
+int virDomainNumaDefCPUFormat(virBufferPtr buf, virDomainNumaPtr def);
-unsigned int virDomainNumaGetCPUCountTotal(virCPUDefPtr numa);
+unsigned int virDomainNumaGetCPUCountTotal(virDomainNumaPtr numa);
#endif /* __NUMA_CONF_H__ */
if (!(cpu = cpuBaseline(cpus, ncpus, models, nmodels, flags)))
goto error;
- cpustr = virCPUDefFormat(cpu, false);
+ cpustr = virCPUDefFormat(cpu, NULL, false);
cleanup:
if (cpus) {
virDomainHugePagePtr hugepage = NULL;
virDomainNumatuneMemMode mode;
const long system_page_size = virGetSystemPageSizeKB();
- virNumaMemAccess memAccess = virDomainNumaGetNodeMemoryAccessMode(def->cpu, guestNode);
+ virNumaMemAccess memAccess = virDomainNumaGetNodeMemoryAccessMode(def->numa, guestNode);
size_t i;
char *mem_path = NULL;
if (virAsprintf(&alias, "ram-node%zu", cell) < 0)
goto cleanup;
- if ((rc = qemuBuildMemoryBackendStr(virDomainNumaGetNodeMemorySize(def->cpu, cell),
+ if ((rc = qemuBuildMemoryBackendStr(virDomainNumaGetNodeMemorySize(def->numa, cell),
0, cell,
NULL, auto_nodeset,
def, qemuCaps, cfg,
bool needBackend = false;
int rc;
int ret = -1;
- size_t ncells = virDomainNumaGetNodeCount(def->cpu);
+ size_t ncells = virDomainNumaGetNodeCount(def->numa);
const long system_page_size = virGetSystemPageSizeKB();
if (virDomainNumatuneHasPerNodeBinding(def->numa) &&
/* using of -numa memdev= cannot be combined with -numa mem=, thus we
* need to check which approach to use */
for (i = 0; i < ncells; i++) {
- unsigned long long cellmem = virDomainNumaGetNodeMemorySize(def->cpu, i);
- virDomainNumaSetNodeMemorySize(def->cpu, i, VIR_ROUND_UP(cellmem, 1024));
+ unsigned long long cellmem = virDomainNumaGetNodeMemorySize(def->numa, i);
+ virDomainNumaSetNodeMemorySize(def->numa, i, VIR_ROUND_UP(cellmem, 1024));
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM) ||
virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE)) {
if (rc == 0)
needBackend = true;
} else {
- if (virDomainNumaGetNodeMemoryAccessMode(def->cpu, i)) {
+ if (virDomainNumaGetNodeMemoryAccessMode(def->numa, i)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Shared memory mapping is not supported "
"with this QEMU"));
for (i = 0; i < ncells; i++) {
VIR_FREE(cpumask);
- if (!(cpumask = virBitmapFormat(virDomainNumaGetNodeCpumask(def->cpu, i))))
+ if (!(cpumask = virBitmapFormat(virDomainNumaGetNodeCpumask(def->numa, i))))
goto cleanup;
if (strchr(cpumask, ',') &&
virBufferAsprintf(&buf, ",memdev=ram-node%zu", i);
else
virBufferAsprintf(&buf, ",mem=%llu",
- virDomainNumaGetNodeMemorySize(def->cpu, i) / 1024);
+ virDomainNumaGetNodeMemorySize(def->numa, i) / 1024);
virCommandAddArgBuffer(cmd, &buf);
}
virCommandAddArg(cmd, "-m");
def->mem.max_balloon = VIR_DIV_UP(def->mem.max_balloon, 1024) * 1024;
virCommandAddArgFormat(cmd, "%llu", def->mem.max_balloon / 1024);
- if (def->mem.nhugepages && !virDomainNumaGetNodeCount(def->cpu)) {
+ if (def->mem.nhugepages && !virDomainNumaGetNodeCount(def->numa)) {
const long system_page_size = virGetSystemPageSizeKB();
char *mem_path = NULL;
}
}
- if (virDomainNumaGetNodeCount(def->cpu))
+ if (virDomainNumaGetNodeCount(def->numa))
if (qemuBuildNumaArgStr(cfg, def, cmd, qemuCaps, nodeset) < 0)
goto error;
if (virtTestLoadFile(xml, &expected) < 0)
goto cleanup;
- if (!(actual = virCPUDefFormat(cpu, updateCPU)))
+ if (!(actual = virCPUDefFormat(cpu, NULL, updateCPU)))
goto cleanup;
if (STRNEQ(expected, actual)) {
ARRAY_CARDINALITY(host_cpu_features), /* nfeatures */
ARRAY_CARDINALITY(host_cpu_features), /* nfeatures_max */
host_cpu_features, /* features */
- 0, /* ncells */
- NULL, /* cells */
};
if ((caps = virCapabilitiesNew(host_cpu.arch,