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;