[libvirt] [PATCH 2/3] Numa : Allow specification of 'units' for numa nodes.

Prerna Saxena prerna at linux.vnet.ibm.com
Wed Nov 5 11:06:11 UTC 2014


>From 7fe8487c5e8d24086637d2157bad25322b3654f7 Mon Sep 17 00:00:00 2001
From: Prerna Saxena <prerna at 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 at 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




More information about the libvir-list mailing list