There are two places where you'll find info on huge pages. The first one is under <cpu/> element, where all supported huge page sizes are listed. Then the second one is under each <cell/> element which refers to concrete NUMA node. At this place, the size of huge page's pool is reported. So the capabilities XML looks something like this: <capabilities> <host> <uuid>01281cda-f352-cb11-a9db-e905fe22010c</uuid> <cpu> <arch>x86_64</arch> <model>Westmere</model> <vendor>Intel</vendor> <topology sockets='1' cores='1' threads='1'/> ... <pages unit='KiB' size='1048576'/> <pages unit='KiB' size='2048'/> </cpu> ... <topology> <cells num='4'> <cell id='0'> <memory unit='KiB'>4054408</memory> <pages unit='KiB' size='1048576'>1</pages> <pages unit='KiB' size='2048'>3</pages> <distances/> <cpus num='1'> <cpu id='0' socket_id='0' core_id='0' siblings='0'/> </cpus> </cell> <cell id='1'> <memory unit='KiB'>4071072</memory> <pages unit='KiB' size='1048576'>2</pages> <pages unit='KiB' size='2048'>1024</pages> <distances/> <cpus num='1'> <cpu id='1' socket_id='0' core_id='0' siblings='1'/> </cpus> </cell> ... </cells> </topology> ... </host> <guest/> </capabilities> Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- docs/schemas/capability.rng | 21 +++++++++++++++++++++ src/conf/capabilities.c | 25 ++++++++++++++++++++++--- src/conf/capabilities.h | 15 ++++++++++++++- src/libxl/libxl_conf.c | 1 + src/nodeinfo.c | 41 ++++++++++++++++++++++++++++++++++++++++- src/qemu/qemu_capabilities.c | 29 ++++++++++++++++++++++++++++- src/test/test_driver.c | 2 +- src/xen/xend_internal.c | 1 + tests/vircaps2xmltest.c | 3 ++- tests/vircapstest.c | 1 + 10 files changed, 131 insertions(+), 8 deletions(-) diff --git a/docs/schemas/capability.rng b/docs/schemas/capability.rng index 0c95c05..ee6cb2e 100644 --- a/docs/schemas/capability.rng +++ b/docs/schemas/capability.rng @@ -118,6 +118,9 @@ <empty/> </element> </zeroOrMore> + <zeroOrMore> + <ref name='hugepagesElem'/> + </zeroOrMore> </define> <define name='power_management'> @@ -188,6 +191,10 @@ <ref name='memory'/> </optional> + <zeroOrMore> + <ref name='hugepagesElem'/> + </zeroOrMore> + <optional> <element name='distances'> <zeroOrMore> @@ -416,4 +423,18 @@ <param name='pattern'>[a-zA-Z0-9\-_]+</param> </data> </define> + + <define name='hugepagesElem'> + <element name='pages'> + <optional> + <attribute name='unit'> + <ref name='unit'/> + </attribute> + </optional> + <attribute name='size'> + <ref name='unsignedInt'/> + </attribute> + <ref name='unsignedInt'/> + </element> + </define> </grammar> diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c index 954456b..c773752 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->hugepages); VIR_FREE(cell); } @@ -223,6 +224,7 @@ virCapabilitiesDispose(void *object) } VIR_FREE(caps->host.secModels); + VIR_FREE(caps->host.hugePagesSize); 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 + * @nhugepages: number of hugepages at node @num + * @hugepages: info on each single huge 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 nhugepages, + virCapsHostNUMACellHugePageInfoPtr hugepages) { 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->nhugepages = nhugepages; + cell->hugepages = hugepages; caps->host.numaCell[caps->host.nnumaCell++] = cell; @@ -773,6 +781,12 @@ virCapabilitiesFormatNUMATopology(virBufferPtr buf, virBufferAsprintf(buf, "<memory unit='KiB'>%llu</memory>\n", cells[i]->mem); + for (j = 0; j < cells[i]->nhugepages; j++) { + virBufferAsprintf(buf, "<pages unit='KiB' size='%u'>%zu</pages>\n", + cells[i]->hugepages[j].size, + cells[i]->hugepages[j].avail); + } + if (cells[i]->nsiblings) { virBufferAddLit(buf, "<distances>\n"); virBufferAdjustIndent(buf, 2); @@ -856,6 +870,11 @@ virCapabilitiesFormatXML(virCapsPtr caps) } virCPUDefFormatBuf(&buf, caps->host.cpu, 0); + for (i = 0; i < caps->host.nhugePagesSize; i++) { + virBufferAsprintf(&buf, "<pages unit='KiB' size='%u'/>\n", + caps->host.hugePagesSize[i]); + } + virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</cpu>\n"); diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h index 53a83c9..384e256 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 _virCapsHostNUMACellHugePageInfo virCapsHostNUMACellHugePageInfo; +typedef virCapsHostNUMACellHugePageInfo *virCapsHostNUMACellHugePageInfoPtr; +struct _virCapsHostNUMACellHugePageInfo { + unsigned int size; /* huge 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 nhugepages; + virCapsHostNUMACellHugePageInfoPtr hugepages; }; typedef struct _virCapsHostSecModelLabel virCapsHostSecModelLabel; @@ -152,6 +161,8 @@ struct _virCapsHost { virCapsHostSecModelPtr secModels; virCPUDefPtr cpu; + int nhugePagesSize; /* size of hugePagesSize array */ + unsigned int *hugePagesSize; /* huge 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 nhugepages, + virCapsHostNUMACellHugePageInfoPtr hugepages); extern int diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index cec37d6..eca51a1 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 5eef42e..fbf2e3c 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; @@ -1795,6 +1796,36 @@ virNodeCapsGetSiblingInfo(int node, return ret; } +static int +virNodeCapsGetHugePagesInfo(int node, + virCapsHostNUMACellHugePageInfoPtr *hugepages, + int *nhugepages) +{ + int ret = -1; + unsigned int *pages_size = NULL, *pages_avail = NULL; + size_t npages, i; + + if (virNumaGetHugePages(node, &pages_size, + &pages_avail, NULL, &npages) < 0) + goto cleanup; + + if (VIR_ALLOC_N(*hugepages, npages) < 0) + goto cleanup; + *nhugepages = npages; + + for (i = 0; i < npages; i++) { + (*hugepages)[i].size = pages_size[i]; + (*hugepages)[i].avail = pages_avail[i]; + } + + ret = 0; + + cleanup: + VIR_FREE(pages_avail); + VIR_FREE(pages_size); + return ret; +} + int nodeCapsInitNUMA(virCapsPtr caps) { @@ -1804,6 +1835,8 @@ nodeCapsInitNUMA(virCapsPtr caps) virBitmapPtr cpumap = NULL; virCapsHostNUMACellSiblingInfoPtr siblings = NULL; int nsiblings; + virCapsHostNUMACellHugePageInfoPtr hugepages = NULL; + int nhugepages; int ret = -1; int ncpus = 0; int cpu; @@ -1846,17 +1879,22 @@ nodeCapsInitNUMA(virCapsPtr caps) if (virNodeCapsGetSiblingInfo(n, &siblings, &nsiblings) < 0) goto cleanup; + if (virNodeCapsGetHugePagesInfo(n, &hugepages, &nhugepages) < 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, + nhugepages, hugepages) < 0) goto cleanup; cpus = NULL; siblings = NULL; + hugepages = NULL; } ret = 0; @@ -1868,6 +1906,7 @@ nodeCapsInitNUMA(virCapsPtr caps) virBitmapFree(cpumap); VIR_FREE(cpus); VIR_FREE(siblings); + VIR_FREE(hugepages); if (ret < 0) VIR_FREE(cpus); diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 08c3d04..d07deeb 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -920,6 +920,29 @@ virQEMUCapsInitCPU(virCapsPtr caps, } +static int +virQEMUCapsInitHugePages(virCapsPtr caps) +{ + int ret = -1; + unsigned int *pages_size = NULL; + size_t npages; + + if (virNumaGetHugePages(-1 /* Magic constant for overall info */, + &pages_size, NULL, NULL, &npages) < 0) + goto cleanup; + + caps->host.hugePagesSize = pages_size; + pages_size = NULL; + caps->host.nhugePagesSize = 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 (virQEMUCapsInitHugePages(caps) < 0) + VIR_WARN("Failed to get huge 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 f9e2b3d..0bf710a 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 5ddf71a..03fdde1 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 fa02534..7166c98 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 3edebba..59e9c2b 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; -- 1.8.5.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list