From 7fe8487c5e8d24086637d2157bad25322b3654f7 Mon Sep 17 00:00:00 2001
From: Prerna Saxena <prerna(a)linux.vnet.ibm.com>
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(a)linux.vnet.ibm.com>
---
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