>From 7fe8487c5e8d24086637d2157bad25322b3654f7 Mon Sep 17 00:00:00 2001 From: Prerna Saxena <prerna@xxxxxxxxxxxxxxxxxx> Date: Mon, 3 Nov 2014 07:53:59 +0530 CPU numa topology implicitly allows memory specification in 'KiB'. Enabling this to accept the 'unit' in which memory needs to be specified. This now allows users to specify memory in units of choice, and lists the same in 'KiB' -- just like other 'memory' elements in XML. <numa> <cell cpus='0-3' memory='1024' unit='MiB' /> <cell cpus='4-7' memory='1024' unit='MiB' /> </numa> I wanted to use virDomainParseScaledValue(), but that function implicitly assumes an XML layout where 'memory' is an _element_ of type 'scaledInteger', with 'unit' as its attribute. A NUMA cell has XML specification where 'memory' is an _attribute_ of element 'cell'. Since changing XML layout is not an option, I have borrowed code from the same. Looking forward to suggestions on how this can best be done. Signed-off-by: Prerna Saxena <prerna@xxxxxxxxxxxxxxxxxx> --- docs/schemas/domaincommon.rng | 5 +++++ src/conf/cpu_conf.c | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 20d81ae..44cabad 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -4144,6 +4144,11 @@ <ref name="memoryKB"/> </attribute> <optional> + <attribute name="unit"> + <ref name="unit"/> + </attribute> + </optional> + <optional> <attribute name="memAccess"> <choice> <value>shared</value> diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c index 5475c07..65b9815 100644 --- a/src/conf/cpu_conf.c +++ b/src/conf/cpu_conf.c @@ -189,6 +189,7 @@ virCPUDefParseXML(xmlNodePtr node, char *cpuMode; char *fallback = NULL; char *vendor_id = NULL; + unsigned long long max; if (!xmlStrEqual(node->name, BAD_CAST "cpu")) { virReportError(VIR_ERR_XML_ERROR, "%s", @@ -439,10 +440,20 @@ virCPUDefParseXML(xmlNodePtr node, def->ncells = n; + /* 32 vs 64 bit will differ in value of upper memory bound. + * On 32-bit machines, our bound is 0xffffffff * KiB. On 64-bit + * machines, our bound is off_t (2^63). + */ + if (sizeof(unsigned long) < sizeof(long long)) + max = 1024ull * ULONG_MAX; + else + max = LLONG_MAX; + for (i = 0; i < n; i++) { - char *cpus, *memory, *memAccessStr; + char *cpus, *memory, *memAccessStr, *unit; int ret, ncpus = 0; unsigned int cur_cell; + unsigned long long bytes; char *tmp = NULL; tmp = virXMLPropString(nodes[i], "id"); @@ -496,14 +507,34 @@ virCPUDefParseXML(xmlNodePtr node, goto error; } - ret = virStrToLong_ull(memory, NULL, 10, &def->cells[cur_cell].mem); + ret = virStrToLong_ull(memory, NULL, 10, &bytes); if (ret == -1) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Invalid 'memory' attribute in NUMA cell")); VIR_FREE(memory); goto error; } + + unit = virXMLPropString(nodes[i], "unit"); + if (!unit) { + if (VIR_STRDUP(unit, "KiB") < 0) + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Error processing 'memory' in NUMA cell")); + } + + if (virScaleInteger(&bytes, unit, 1024, max) < 0) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Error scaling 'memory' in NUMA cell")); + VIR_FREE(memory); + VIR_FREE(unit); + goto error; + } + + def->cells[cur_cell].mem = VIR_DIV_UP(bytes, 1024); + + bytes = 0; VIR_FREE(memory); + VIR_FREE(unit); memAccessStr = virXMLPropString(nodes[i], "memAccess"); if (memAccessStr) { @@ -703,6 +734,7 @@ virCPUDefFormatBuf(virBufferPtr buf, virBufferAsprintf(buf, " id='%zu'", i); virBufferAsprintf(buf, " cpus='%s'", def->cells[i].cpustr); virBufferAsprintf(buf, " memory='%llu'", def->cells[i].mem); + virBufferAddLit(buf, " unit='KiB'"); if (memAccess) virBufferAsprintf(buf, " memAccess='%s'", virMemAccessTypeToString(memAccess)); -- 1.9.3 -- Prerna Saxena Linux Technology Centre, IBM Systems and Technology Lab, Bangalore, India -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list