From 02129b7c0e581898f03468e0bfb5472dc9903339 Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Fri, 6 Jun 2014 18:12:51 +0200 Subject: [PATCH] virCaps: expose pages info There are two places where you'll find info on page sizes. The first one is under element, where all supported pages sizes are listed. Then the second one is under each element which refers to concrete NUMA node. At this place, the size of page's pool is reported. So the capabilities XML looks something like this: 01281cda-f352-cb11-a9db-e905fe22010c x86_64 Westmere Intel ... ... 4054408 1013602 3 1 4071072 1017768 3 1 ... ... Signed-off-by: Michal Privoznik --- docs/schemas/capability.rng | 21 +++++++++++++++++++ src/conf/capabilities.c | 25 +++++++++++++++++++--- src/conf/capabilities.h | 15 +++++++++++++- src/libxl/libxl_conf.c | 1 + src/nodeinfo.c | 40 +++++++++++++++++++++++++++++++++++- 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, 130 insertions(+), 8 deletions(-) diff --git a/docs/schemas/capability.rng b/docs/schemas/capability.rng index 0c95c05d68..f954599739 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 954456b4d0..19359a57c6 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 53a83c9df7..2f944514ce 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 cec37d6991..eca51a1556 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 fd831b460a..b55d77e501 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 08c3d04c77..245d6b50fd 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 f9e2b3dcc8..0bf710a1ab 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 5ddf71acbc..03fdde18e1 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 fa02534656..7166c98e69 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 3edebba5ef..59e9c2bcd8 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; -- GitLab