diff --git a/docs/schemas/capability.rng b/docs/schemas/capability.rng
index 0c95c05d6851174b63c0d3991b2ab36a8c393865..f954599739681a931b62419f87c8ffb427bf2b39 100644
--- a/docs/schemas/capability.rng
+++ b/docs/schemas/capability.rng
@@ -118,6 +118,9 @@
+
+
+
@@ -188,6 +191,10 @@
+
+
+
+
@@ -416,4 +423,18 @@
[a-zA-Z0-9\-_]+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c
index 954456b4d087ba6f6fdd5080940004d8f265d0a8..19359a57c6d1259052fd0b028f0e33fdfc8aff96 100644
--- a/src/conf/capabilities.c
+++ b/src/conf/capabilities.c
@@ -108,6 +108,7 @@ virCapabilitiesFreeHostNUMACell(virCapsHostNUMACellPtr cell)
VIR_FREE(cell->cpus);
VIR_FREE(cell->siblings);
+ VIR_FREE(cell->pageinfo);
VIR_FREE(cell);
}
@@ -223,6 +224,7 @@ virCapabilitiesDispose(void *object)
}
VIR_FREE(caps->host.secModels);
+ VIR_FREE(caps->host.pagesSize);
virCPUDefFree(caps->host.cpu);
}
@@ -281,6 +283,8 @@ virCapabilitiesAddHostMigrateTransport(virCapsPtr caps,
* @cpus: array of CPU definition structures, the pointer is stolen
* @nsiblings: number of sibling NUMA nodes
* @siblings: info on sibling NUMA nodes
+ * @npageinfo: number of pages at node @num
+ * @pageinfo: info on each single memory page
*
* Registers a new NUMA cell for a host, passing in a
* array of CPU IDs belonging to the cell
@@ -292,7 +296,9 @@ virCapabilitiesAddHostNUMACell(virCapsPtr caps,
int ncpus,
virCapsHostNUMACellCPUPtr cpus,
int nsiblings,
- virCapsHostNUMACellSiblingInfoPtr siblings)
+ virCapsHostNUMACellSiblingInfoPtr siblings,
+ int npageinfo,
+ virCapsHostNUMACellPageInfoPtr pageinfo)
{
virCapsHostNUMACellPtr cell;
@@ -303,12 +309,14 @@ virCapabilitiesAddHostNUMACell(virCapsPtr caps,
if (VIR_ALLOC(cell) < 0)
return -1;
- cell->ncpus = ncpus;
cell->num = num;
cell->mem = mem;
+ cell->ncpus = ncpus;
cell->cpus = cpus;
- cell->siblings = siblings;
cell->nsiblings = nsiblings;
+ cell->siblings = siblings;
+ cell->npageinfo = npageinfo;
+ cell->pageinfo = pageinfo;
caps->host.numaCell[caps->host.nnumaCell++] = cell;
@@ -773,6 +781,12 @@ virCapabilitiesFormatNUMATopology(virBufferPtr buf,
virBufferAsprintf(buf, "%llu\n",
cells[i]->mem);
+ for (j = 0; j < cells[i]->npageinfo; j++) {
+ virBufferAsprintf(buf, "%zu\n",
+ cells[i]->pageinfo[j].size,
+ cells[i]->pageinfo[j].avail);
+ }
+
if (cells[i]->nsiblings) {
virBufferAddLit(buf, "\n");
virBufferAdjustIndent(buf, 2);
@@ -856,6 +870,11 @@ virCapabilitiesFormatXML(virCapsPtr caps)
}
virCPUDefFormatBuf(&buf, caps->host.cpu, 0);
+ for (i = 0; i < caps->host.nPagesSize; i++) {
+ virBufferAsprintf(&buf, "\n",
+ caps->host.pagesSize[i]);
+ }
+
virBufferAdjustIndent(&buf, -2);
virBufferAddLit(&buf, "\n");
diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h
index 53a83c9df740dd7600adf6c5dfc05225ca28ca56..2f944514ce3652bc6fe28445462ba194717e40f5 100644
--- a/src/conf/capabilities.h
+++ b/src/conf/capabilities.h
@@ -102,6 +102,13 @@ struct _virCapsHostNUMACellSiblingInfo {
unsigned int distance; /* distance to the node */
};
+typedef struct _virCapsHostNUMACellPageInfo virCapsHostNUMACellPageInfo;
+typedef virCapsHostNUMACellPageInfo *virCapsHostNUMACellPageInfoPtr;
+struct _virCapsHostNUMACellPageInfo {
+ unsigned int size; /* page size in kibibytes */
+ size_t avail; /* the size of pool */
+};
+
typedef struct _virCapsHostNUMACell virCapsHostNUMACell;
typedef virCapsHostNUMACell *virCapsHostNUMACellPtr;
struct _virCapsHostNUMACell {
@@ -111,6 +118,8 @@ struct _virCapsHostNUMACell {
virCapsHostNUMACellCPUPtr cpus;
int nsiblings;
virCapsHostNUMACellSiblingInfoPtr siblings;
+ int npageinfo;
+ virCapsHostNUMACellPageInfoPtr pageinfo;
};
typedef struct _virCapsHostSecModelLabel virCapsHostSecModelLabel;
@@ -152,6 +161,8 @@ struct _virCapsHost {
virCapsHostSecModelPtr secModels;
virCPUDefPtr cpu;
+ int nPagesSize; /* size of pagesSize array */
+ unsigned int *pagesSize; /* page sizes support on the system */
unsigned char host_uuid[VIR_UUID_BUFLEN];
};
@@ -206,7 +217,9 @@ virCapabilitiesAddHostNUMACell(virCapsPtr caps,
int ncpus,
virCapsHostNUMACellCPUPtr cpus,
int nsiblings,
- virCapsHostNUMACellSiblingInfoPtr siblings);
+ virCapsHostNUMACellSiblingInfoPtr siblings,
+ int npageinfo,
+ virCapsHostNUMACellPageInfoPtr pageinfo);
extern int
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index cec37d6991b734fd6dacca82eab82e207ecb7d65..eca51a1556a0b3b3bbcf58048338d536fa7edc02 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -210,6 +210,7 @@ libxlCapsInitNuma(libxl_ctx *ctx, virCapsPtr caps)
if (virCapabilitiesAddHostNUMACell(caps, i,
numa_info[i].size / 1024,
nr_cpus_node[i], cpus[i],
+ 0, NULL,
0, NULL) < 0) {
virCapabilitiesClearHostNUMACellCPUTopology(cpus[i],
nr_cpus_node[i]);
diff --git a/src/nodeinfo.c b/src/nodeinfo.c
index fd831b460a11095305cd91655c93b9714f6b25fb..b55d77e5016fbe3f486012ec1dc87395f7a121a6 100644
--- a/src/nodeinfo.c
+++ b/src/nodeinfo.c
@@ -1646,6 +1646,7 @@ nodeCapsInitNUMAFake(virCapsPtr caps ATTRIBUTE_UNUSED)
if (virCapabilitiesAddHostNUMACell(caps, 0,
nodeinfo.memory,
ncpus, cpus,
+ 0, NULL,
0, NULL) < 0)
goto error;
@@ -1824,6 +1825,35 @@ virNodeCapsGetSiblingInfo(int node,
return ret;
}
+static int
+virNodeCapsGetPagesInfo(int node,
+ virCapsHostNUMACellPageInfoPtr *pageinfo,
+ int *npageinfo)
+{
+ int ret = -1;
+ unsigned int *pages_size = NULL, *pages_avail = NULL;
+ size_t npages, i;
+
+ if (virNumaGetPages(node, &pages_size, &pages_avail, NULL, &npages) < 0)
+ goto cleanup;
+
+ if (VIR_ALLOC_N(*pageinfo, npages) < 0)
+ goto cleanup;
+ *npageinfo = npages;
+
+ for (i = 0; i < npages; i++) {
+ (*pageinfo)[i].size = pages_size[i];
+ (*pageinfo)[i].avail = pages_avail[i];
+ }
+
+ ret = 0;
+
+ cleanup:
+ VIR_FREE(pages_avail);
+ VIR_FREE(pages_size);
+ return ret;
+}
+
int
nodeCapsInitNUMA(virCapsPtr caps)
{
@@ -1833,6 +1863,8 @@ nodeCapsInitNUMA(virCapsPtr caps)
virBitmapPtr cpumap = NULL;
virCapsHostNUMACellSiblingInfoPtr siblings = NULL;
int nsiblings = 0;
+ virCapsHostNUMACellPageInfoPtr pageinfo = NULL;
+ int npageinfo;
int ret = -1;
int ncpus = 0;
int cpu;
@@ -1875,17 +1907,22 @@ nodeCapsInitNUMA(virCapsPtr caps)
if (virNodeCapsGetSiblingInfo(n, &siblings, &nsiblings) < 0)
goto cleanup;
+ if (virNodeCapsGetPagesInfo(n, &pageinfo, &npageinfo) < 0)
+ goto cleanup;
+
/* Detect the amount of memory in the numa cell in KiB */
virNumaGetNodeMemory(n, &memory, NULL);
memory >>= 10;
if (virCapabilitiesAddHostNUMACell(caps, n, memory,
ncpus, cpus,
- nsiblings, siblings) < 0)
+ nsiblings, siblings,
+ npageinfo, pageinfo) < 0)
goto cleanup;
cpus = NULL;
siblings = NULL;
+ pageinfo = NULL;
}
ret = 0;
@@ -1897,6 +1934,7 @@ nodeCapsInitNUMA(virCapsPtr caps)
virBitmapFree(cpumap);
VIR_FREE(cpus);
VIR_FREE(siblings);
+ VIR_FREE(pageinfo);
if (ret < 0)
VIR_FREE(cpus);
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 08c3d04c77e558e75b21eee3a9093f2d22ec2f63..245d6b50fdad98f120c54a895a25516f503b1ca5 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -920,6 +920,29 @@ virQEMUCapsInitCPU(virCapsPtr caps,
}
+static int
+virQEMUCapsInitPages(virCapsPtr caps)
+{
+ int ret = -1;
+ unsigned int *pages_size = NULL;
+ size_t npages;
+
+ if (virNumaGetPages(-1 /* Magic constant for overall info */,
+ &pages_size, NULL, NULL, &npages) < 0)
+ goto cleanup;
+
+ caps->host.pagesSize = pages_size;
+ pages_size = NULL;
+ caps->host.nPagesSize = npages;
+ npages = 0;
+
+ ret = 0;
+ cleanup:
+ VIR_FREE(pages_size);
+ return ret;
+}
+
+
virCapsPtr virQEMUCapsInit(virQEMUCapsCachePtr cache)
{
virCapsPtr caps;
@@ -943,10 +966,14 @@ virCapsPtr virQEMUCapsInit(virQEMUCapsCachePtr cache)
VIR_WARN("Failed to get host CPU");
/* Add the power management features of the host */
-
if (virNodeSuspendGetTargetMask(&caps->host.powerMgmt) < 0)
VIR_WARN("Failed to get host power management capabilities");
+ /* Add huge pages info */
+ if (virQEMUCapsInitPages(caps) < 0)
+ VIR_WARN("Failed to get pages info");
+
+ /* Add domain migration transport URI */
virCapabilitiesAddHostMigrateTransport(caps,
"tcp");
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index f9e2b3dcc83ed29d7f5342fbde1082364c997c16..0bf710a1abe6af16b283c0b5236729cf58979aa6 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -338,7 +338,7 @@ testBuildCapabilities(virConnectPtr conn)
if (virCapabilitiesAddHostNUMACell(caps, i, 0,
privconn->cells[i].numCpus,
- cpu_cells, 0, NULL) < 0)
+ cpu_cells, 0, NULL, 0, NULL) < 0)
goto error;
}
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
index 5ddf71acbc7aece405fb3fb4472f32e56ea5c34f..03fdde18e1f2b1413b09fd54ee0102e2e5ca8ab6 100644
--- a/src/xen/xend_internal.c
+++ b/src/xen/xend_internal.c
@@ -1102,6 +1102,7 @@ sexpr_to_xend_topology(const struct sexpr *root, virCapsPtr caps)
if (virCapabilitiesAddHostNUMACell(caps, cell, 0,
nb_cpus, cpuInfo,
+ 0, NULL,
0, NULL) < 0)
goto error;
cpuInfo = NULL;
diff --git a/tests/vircaps2xmltest.c b/tests/vircaps2xmltest.c
index fa02534656ee30a229e434d044864853f7c955cb..7166c98e69c27b4798667ff23ab5304332912604 100644
--- a/tests/vircaps2xmltest.c
+++ b/tests/vircaps2xmltest.c
@@ -74,7 +74,8 @@ buildVirCapabilities(int max_cells,
if (virCapabilitiesAddHostNUMACell(caps, cell_id,
max_mem_in_cell,
max_cpus_in_cell, cell_cpus,
- nsiblings, siblings) < 0)
+ nsiblings, siblings,
+ 0, NULL) < 0)
goto error;
cell_cpus = NULL;
diff --git a/tests/vircapstest.c b/tests/vircapstest.c
index 3edebba5ef13562c553ae82c5b0a3d630476913c..59e9c2bcd8c8b5344d9b3f2121afcf508548d953 100644
--- a/tests/vircapstest.c
+++ b/tests/vircapstest.c
@@ -66,6 +66,7 @@ buildNUMATopology(int seq)
if (virCapabilitiesAddHostNUMACell(caps, cell_id + seq,
MAX_MEM_IN_CELL,
MAX_CPUS_IN_CELL, cell_cpus,
+ 0, NULL,
0, NULL) < 0)
goto error;