[libvirt] [PATCH 1/3] numa: add '-numa memdev=' support

Chen Fan chen.fan.fnst at cn.fujitsu.com
Wed Jun 25 06:42:30 UTC 2014


Since qemu has supported '-numa memdev=ram0' command option, so libvirt
should add numa element to support specified memdev attrubute in XML.

Signed-off-by: Chen Fan <chen.fan.fnst at cn.fujitsu.com>
---
 src/conf/cpu_conf.c     | 73 +++++++++++++++++++++++++++++++++++++++----------
 src/conf/cpu_conf.h     | 13 ++++++++-
 src/qemu/qemu_command.c | 10 +++++--
 3 files changed, 78 insertions(+), 18 deletions(-)

diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
index ebdaa19..2d0980e 100644
--- a/src/conf/cpu_conf.c
+++ b/src/conf/cpu_conf.c
@@ -29,6 +29,7 @@
 #include "cpu_conf.h"
 #include "domain_conf.h"
 #include "virstring.h"
+#include "c-ctype.h"
 
 #define VIR_FROM_THIS VIR_FROM_CPU
 
@@ -84,6 +85,8 @@ virCPUDefFree(virCPUDefPtr def)
     for (i = 0; i < def->ncells; i++) {
         virBitmapFree(def->cells[i].cpumask);
         VIR_FREE(def->cells[i].cpustr);
+        if (def->cells[i].memtype == VIR_CPU_CELL_MEMORY_DEV)
+            VIR_FREE(def->cells[i].data.memstr);
     }
     VIR_FREE(def->cells);
     VIR_FREE(def->vendor_id);
@@ -153,7 +156,13 @@ virCPUDefCopy(const virCPUDef *cpu)
 
         for (i = 0; i < cpu->ncells; i++) {
             copy->cells[i].cellid = cpu->cells[i].cellid;
-            copy->cells[i].mem = cpu->cells[i].mem;
+            copy->cells[i].memtype = cpu->cells[i].memtype;
+            if (cpu->cells[i].memtype == VIR_CPU_CELL_MEMORY_DEV) {
+                if (VIR_STRDUP(copy->cells[i].data.memstr, cpu->cells[i].data.memstr) < 0)
+                    goto error;
+            } else {
+                copy->cells[i].data.mem = cpu->cells[i].data.mem;
+            }
 
             copy->cells[i].cpumask = virBitmapNewCopy(cpu->cells[i].cpumask);
 
@@ -436,7 +445,7 @@ virCPUDefParseXML(xmlNodePtr node,
         def->ncells = n;
 
         for (i = 0; i < n; i++) {
-            char *cpus, *memory;
+            char *cpus, *memory, *memdev;
             int ret, ncpus = 0;
 
             def->cells[i].cellid = i;
@@ -455,20 +464,52 @@ virCPUDefParseXML(xmlNodePtr node,
             def->cells_cpus += ncpus;
 
             memory = virXMLPropString(nodes[i], "memory");
-            if (!memory) {
-                virReportError(VIR_ERR_XML_ERROR, "%s",
-                               _("Missing 'memory' attribute in NUMA cell"));
-                goto error;
-            }
-
-            ret  = virStrToLong_ui(memory, NULL, 10, &def->cells[i].mem);
-            if (ret == -1) {
+            memdev = virXMLPropString(nodes[i], "memdev");
+            if (memory || memdev) {
+                if (memory && memdev) {
+                    virReportError(VIR_ERR_XML_ERROR, "%s",
+                                   _("Both 'memory' and 'memdev' attribute in NUMA cell is not allowed"));
+                    goto error;
+                }
+
+                if (memory) {
+                    ret  = virStrToLong_ui(memory, NULL, 10, &def->cells[i].data.mem);
+                    if (ret == -1) {
+                        virReportError(VIR_ERR_XML_ERROR, "%s",
+                                       _("Invalid 'memory' attribute in NUMA cell"));
+                        VIR_FREE(memory);
+                        goto error;
+                    }
+                    def->cells[i].memtype = VIR_CPU_CELL_MEMORY_SIZE;
+                    VIR_FREE(memory);
+                } else {
+                    if (strlen(memdev) < 1) {
+                        virReportError(VIR_ERR_XML_ERROR, "%s",
+                                       _("Empty 'memdev' attribute in NUMA cell"));
+                        VIR_FREE(memdev);
+                        goto error;
+                    }
+
+                    if (!c_isalpha(memdev[0])) {
+                        virReportError(VIR_ERR_XML_ERROR, "%s",
+                                       _("Invalid 'memdev' attribute name in NUMA cell, "
+                                         "it must begin with a letter"));
+                        VIR_FREE(memdev);
+                        goto error;
+                    }
+
+                    if (VIR_STRDUP(def->cells[i].data.memstr, memdev) < 0) {
+                        VIR_FREE(memdev);
+                        goto error;
+                    }
+                    def->cells[i].memtype = VIR_CPU_CELL_MEMORY_DEV;
+                    VIR_FREE(memdev);
+                }
+            } else {
                 virReportError(VIR_ERR_XML_ERROR, "%s",
-                               _("Invalid 'memory' attribute in NUMA cell"));
-                VIR_FREE(memory);
+                               _("Missing 'memory' or 'memdev' attribute in NUMA cell"));
                 goto error;
             }
-            VIR_FREE(memory);
         }
     }
 
@@ -648,7 +689,11 @@ virCPUDefFormatBuf(virBufferPtr buf,
         for (i = 0; i < def->ncells; i++) {
             virBufferAddLit(buf, "<cell");
             virBufferAsprintf(buf, " cpus='%s'", def->cells[i].cpustr);
-            virBufferAsprintf(buf, " memory='%d'", def->cells[i].mem);
+            if (def->cells[i].memtype == VIR_CPU_CELL_MEMORY_DEV) {
+                virBufferAsprintf(buf, " memdev='%s'", def->cells[i].data.memstr);
+            } else {
+                virBufferAsprintf(buf, " memory='%d'", def->cells[i].data.mem);
+            }
             virBufferAddLit(buf, "/>\n");
         }
         virBufferAdjustIndent(buf, -2);
diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
index 8c932ce..b1ebd9c 100644
--- a/src/conf/cpu_conf.h
+++ b/src/conf/cpu_conf.h
@@ -90,13 +90,24 @@ struct _virCPUFeatureDef {
     int policy;         /* enum virCPUFeaturePolicy */
 };
 
+typedef enum {
+    VIR_CPU_CELL_MEMORY_SIZE,
+    VIR_CPU_CELL_MEMORY_DEV,
+
+    VIR_CPU_CELL_MEMORY_LAST
+} virCPUCellMemoryType;
+
 typedef struct _virCellDef virCellDef;
 typedef virCellDef *virCellDefPtr;
 struct _virCellDef {
    int cellid;
    virBitmapPtr cpumask;	/* CPUs that are part of this node */
    char *cpustr;	/* CPUs stored in string form for dumpxml */
-   unsigned int mem;	/* Node memory in kB */
+   int memtype;
+   union {
+       char *memstr;        /* Node memory device name */
+       unsigned int mem;    /* Node memory in kB */
+   } data;
 };
 
 typedef struct _virCPUDef virCPUDef;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2caee66..b351f60 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6560,9 +6560,13 @@ qemuBuildNumaArgStr(const virDomainDef *def, virCommandPtr cmd)
             goto cleanup;
         }
         virBufferAdd(&buf, cpumask, -1);
-        def->cpu->cells[i].mem = VIR_DIV_UP(def->cpu->cells[i].mem,
-                                            1024) * 1024;
-        virBufferAsprintf(&buf, ",mem=%d", def->cpu->cells[i].mem / 1024);
+        if (def->cpu->cells[i].memtype == VIR_CPU_CELL_MEMORY_DEV) {
+            virBufferAsprintf(&buf, ",memdev=%s", def->cpu->cells[i].data.memstr);
+        } else {
+            def->cpu->cells[i].data.mem = VIR_DIV_UP(def->cpu->cells[i].data.mem,
+                                                     1024) * 1024;
+            virBufferAsprintf(&buf, ",mem=%d", def->cpu->cells[i].data.mem / 1024);
+        }
 
         if (virBufferError(&buf)) {
             virReportOOMError();
-- 
1.9.3




More information about the libvir-list mailing list