[libvirt] [PATCH v2 5/9] use virBitmap to store numa nodemask info.

Hu Tao hutao at cn.fujitsu.com
Thu Sep 6 10:13:56 UTC 2012


---
 src/conf/domain_conf.c           |   24 +++++-----------
 src/conf/domain_conf.h           |    2 +-
 src/lxc/lxc_controller.c         |   25 ++++++++--------
 src/parallels/parallels_driver.c |    2 +-
 src/qemu/qemu_cgroup.c           |    7 ++---
 src/qemu/qemu_cgroup.h           |    2 +-
 src/qemu/qemu_driver.c           |   58 ++++++++++----------------------------
 src/qemu/qemu_process.c          |   52 ++++++++++++++++------------------
 8 files changed, 65 insertions(+), 107 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b07b6b7..a02b805 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1680,7 +1680,7 @@ void virDomainDefFree(virDomainDefPtr def)
 
     virDomainVcpuPinDefFree(def->cputune.emulatorpin);
 
-    VIR_FREE(def->numatune.memory.nodemask);
+    virBitmapFree(def->numatune.memory.nodemask);
 
     virSysinfoDefFree(def->sysinfo);
 
@@ -8520,19 +8520,10 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
 
                     nodeset = virXMLPropString(cur, "nodeset");
                     if (nodeset) {
-                        char *set = nodeset;
-                        int nodemasklen = VIR_DOMAIN_CPUMASK_LEN;
-
-                        if (VIR_ALLOC_N(def->numatune.memory.nodemask,
-                                        nodemasklen) < 0) {
-                            virReportOOMError();
-                            goto error;
-                        }
-
-                        /* "nodeset" uses the same syntax as "cpuset". */
-                        if (virDomainCpuSetParse(set, 0,
-                                                 def->numatune.memory.nodemask,
-                                                 nodemasklen) < 0) {
+                        if (virBitmapParse(nodeset,
+                                           0,
+                                           &def->numatune.memory.nodemask,
+                                           VIR_DOMAIN_CPUMASK_LEN) < 0) {
                             VIR_FREE(nodeset);
                             goto error;
                         }
@@ -8574,7 +8565,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
 
                     /* Ignore 'nodeset' if 'placement' is 'auto' finally */
                     if (placement_mode == VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)
-                        VIR_FREE(def->numatune.memory.nodemask);
+                        virBitmapFree(def->numatune.memory.nodemask);
 
                     /* Copy 'placement' of <numatune> to <vcpu> if its 'placement'
                      * is not specified and 'placement' of <numatune> is specified.
@@ -13242,8 +13233,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
 
         if (def->numatune.memory.placement_mode ==
             VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC) {
-            nodemask = virDomainCpuSetFormat(def->numatune.memory.nodemask,
-                                         VIR_DOMAIN_CPUMASK_LEN);
+            nodemask = virBitmapFormat(def->numatune.memory.nodemask);
             if (nodemask == NULL) {
                 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                _("failed to format nodeset for "
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index bb3721c..975c565 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1560,7 +1560,7 @@ typedef struct _virDomainNumatuneDef virDomainNumatuneDef;
 typedef virDomainNumatuneDef *virDomainNumatuneDefPtr;
 struct _virDomainNumatuneDef {
     struct {
-        char *nodemask;
+        virBitmapPtr nodemask;
         int mode;
         int placement_mode; /* enum virDomainNumatuneMemPlacementMode */
     } memory;
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index ac8ce94..acaed60 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -418,20 +418,19 @@ static int virLXCControllerSetupNUMAPolicy(virLXCControllerPtr ctrl)
 
     /* Convert nodemask to NUMA bitmask. */
     nodemask_zero(&mask);
-    for (i = 0; i < VIR_DOMAIN_CPUMASK_LEN; i++) {
-        if (ctrl->def->numatune.memory.nodemask[i]) {
-            if (i > NUMA_NUM_NODES) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                               _("Host cannot support NUMA node %d"), i);
-                return -1;
-            }
-            if (i > maxnode && !warned) {
-                VIR_WARN("nodeset is out of range, there is only %d NUMA "
-                         "nodes on host", maxnode);
-                warned = true;
-            }
-            nodemask_set(&mask, i);
+    i = -1;
+    while ((i = virBitmapNextSetBit(ctrl->def->numatune.memory.nodemask, i)) > 0) {
+        if (i > NUMA_NUM_NODES) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("Host cannot support NUMA node %d"), i);
+            return -1;
+        }
+        if (i > maxnode && !warned) {
+            VIR_WARN("nodeset is out of range, there is only %d NUMA "
+                     "nodes on host", maxnode);
+            warned = true;
         }
+        nodemask_set(&mask, i);
     }
 
     mode = ctrl->def->numatune.memory.mode;
diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c
index 06a75b3..0d8dcb8 100644
--- a/src/parallels/parallels_driver.c
+++ b/src/parallels/parallels_driver.c
@@ -1428,7 +1428,7 @@ parallelsApplyChanges(virDomainObjPtr dom, virDomainDefPtr new)
 
     if (old->numatune.memory.mode != new->numatune.memory.mode ||
         old->numatune.memory.placement_mode != new->numatune.memory.placement_mode ||
-        !STREQ_NULLABLE(old->numatune.memory.nodemask, new->numatune.memory.nodemask)) {
+        !virBitmapEqual(old->numatune.memory.nodemask, new->numatune.memory.nodemask)) {
 
         virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
                         _("numa parameters are not supported "
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index be95761..0947527 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -195,7 +195,7 @@ int qemuSetupHostUsbDeviceCgroup(usbDevice *dev ATTRIBUTE_UNUSED,
 
 int qemuSetupCgroup(struct qemud_driver *driver,
                     virDomainObjPtr vm,
-                    char *nodemask)
+                    virBitmapPtr nodemask)
 {
     virCgroupPtr cgroup = NULL;
     int rc;
@@ -412,10 +412,9 @@ int qemuSetupCgroup(struct qemud_driver *driver,
         char *mask = NULL;
         if (vm->def->numatune.memory.placement_mode ==
             VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)
-            mask = virDomainCpuSetFormat(nodemask, VIR_DOMAIN_CPUMASK_LEN);
+            mask = virBitmapFormat(nodemask);
         else
-            mask = virDomainCpuSetFormat(vm->def->numatune.memory.nodemask,
-                                         VIR_DOMAIN_CPUMASK_LEN);
+            mask = virBitmapFormat(vm->def->numatune.memory.nodemask);
         if (!mask) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("failed to convert memory nodemask"));
diff --git a/src/qemu/qemu_cgroup.h b/src/qemu/qemu_cgroup.h
index 04f70a1..1de4856 100644
--- a/src/qemu/qemu_cgroup.h
+++ b/src/qemu/qemu_cgroup.h
@@ -49,7 +49,7 @@ int qemuSetupHostUsbDeviceCgroup(usbDevice *dev,
                                  void *opaque);
 int qemuSetupCgroup(struct qemud_driver *driver,
                     virDomainObjPtr vm,
-                    char *nodemask);
+                    virBitmapPtr nodemask);
 int qemuSetupCgroupVcpuBW(virCgroupPtr cgroup,
                           unsigned long long period,
                           long long quota);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e96c3b8..3340928 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7512,18 +7512,12 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
             }
         } else if (STREQ(param->field, VIR_DOMAIN_NUMA_NODESET)) {
             int rc;
-            char *nodeset = NULL;
+            virBitmapPtr nodeset = NULL;
             char *nodeset_str = NULL;
 
-            if (VIR_ALLOC_N(nodeset, VIR_DOMAIN_CPUMASK_LEN) < 0) {
-                virReportOOMError();
-                ret = -1;
-                goto cleanup;
-            };
-
-            if (virDomainCpuSetParse(params[i].value.s,
-                                     0, nodeset,
-                                     VIR_DOMAIN_CPUMASK_LEN) < 0) {
+            if (virBitmapParse(params[i].value.s,
+                               0, &nodeset,
+                               VIR_DOMAIN_CPUMASK_LEN) < 0) {
                 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                _("Failed to parse nodeset"));
                 ret = -1;
@@ -7536,17 +7530,16 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
                     virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                                    _("change of nodeset for running domain "
                                      "requires strict numa mode"));
-                    VIR_FREE(nodeset);
+                    virBitmapFree(nodeset);
                     ret = -1;
                     continue;
                 }
 
                 /* Ensure the cpuset string is formated before passing to cgroup */
-                if (!(nodeset_str = virDomainCpuSetFormat(nodeset,
-                                                          VIR_DOMAIN_CPUMASK_LEN))) {
+                if (!(nodeset_str = virBitmapFormat(nodeset))) {
                     virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                    _("Failed to format nodeset"));
-                    VIR_FREE(nodeset);
+                    virBitmapFree(nodeset);
                     ret = -1;
                     continue;
                 }
@@ -7554,7 +7547,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
                 if ((rc = virCgroupSetCpusetMems(group, nodeset_str) != 0)) {
                     virReportSystemError(-rc, "%s",
                                          _("unable to set numa tunable"));
-                    VIR_FREE(nodeset);
+                    virBitmapFree(nodeset);
                     VIR_FREE(nodeset_str);
                     ret = -1;
                     continue;
@@ -7563,40 +7556,22 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
 
                 /* update vm->def here so that dumpxml can read the new
                  * values from vm->def. */
-                if (!vm->def->numatune.memory.nodemask) {
-                    if (VIR_ALLOC_N(vm->def->numatune.memory.nodemask,
-                                    VIR_DOMAIN_CPUMASK_LEN) < 0) {
-                        virReportOOMError();
-                        VIR_FREE(nodeset);
-                        ret = -1;
-                        goto cleanup;
-                    }
-                } else {
-                    VIR_FREE(vm->def->numatune.memory.nodemask);
-                }
+                virBitmapFree(vm->def->numatune.memory.nodemask);
 
-                vm->def->numatune.memory.nodemask = nodeset;
                 vm->def->numatune.memory.placement_mode =
                     VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC;
+                vm->def->numatune.memory.nodemask = virBitmapCopy(nodeset);
             }
 
             if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
-                if (!persistentDef->numatune.memory.nodemask) {
-                    if (VIR_ALLOC_N(persistentDef->numatune.memory.nodemask,
-                                    VIR_DOMAIN_CPUMASK_LEN) < 0) {
-                        virReportOOMError();
-                        VIR_FREE(nodeset);
-                        ret = -1;
-                        goto cleanup;
-                    }
-                } else {
-                    VIR_FREE(persistentDef->numatune.memory.nodemask);
-                }
+                virBitmapFree(persistentDef->numatune.memory.nodemask);
 
                 persistentDef->numatune.memory.nodemask = nodeset;
                 persistentDef->numatune.memory.placement_mode =
                     VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC;
+                nodeset = NULL;
             }
+            virBitmapFree(nodeset);
         }
     }
 
@@ -7691,11 +7666,8 @@ qemuDomainGetNumaParameters(virDomainPtr dom,
 
         case 1: /* fill numa nodeset here */
             if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
-                char *mask = persistentDef->numatune.memory.nodemask;
-                if (mask)
-                    nodeset = virDomainCpuSetFormat(mask,
-                                                    VIR_DOMAIN_CPUMASK_LEN);
-                else
+                nodeset = virBitmapFormat(persistentDef->numatune.memory.nodemask);
+                if (!nodeset)
                     nodeset = strdup("");
             } else {
                 rc = virCgroupGetCpusetMems(group, &nodeset);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 8fe9fa1..627516d 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -63,6 +63,7 @@
 #include "uuid.h"
 #include "virtime.h"
 #include "virnetdevtap.h"
+#include "bitmap.h"
 
 #define VIR_FROM_THIS VIR_FROM_QEMU
 
@@ -1696,7 +1697,7 @@ qemuProcessDetectVcpuPIDs(struct qemud_driver *driver,
 #if HAVE_NUMACTL
 static int
 qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm,
-                                const char *nodemask)
+                                virBitmapPtr nodemask)
 {
     nodemask_t mask;
     int mode = -1;
@@ -1706,7 +1707,7 @@ qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm,
     int maxnode = 0;
     bool warned = false;
     virDomainNumatuneDef numatune = vm->def->numatune;
-    const char *tmp_nodemask = NULL;
+    virBitmapPtr tmp_nodemask = NULL;
 
     if (numatune.memory.placement_mode ==
         VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC) {
@@ -1731,20 +1732,19 @@ qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm,
     maxnode = numa_max_node() + 1;
     /* Convert nodemask to NUMA bitmask. */
     nodemask_zero(&mask);
-    for (i = 0; i < VIR_DOMAIN_CPUMASK_LEN; i++) {
-        if (tmp_nodemask[i]) {
-            if (i > NUMA_NUM_NODES) {
-                virReportError(VIR_ERR_INTERNAL_ERROR,
-                               _("Host cannot support NUMA node %d"), i);
-                return -1;
-            }
-            if (i > maxnode && !warned) {
-                VIR_WARN("nodeset is out of range, there is only %d NUMA "
-                         "nodes on host", maxnode);
-                warned = true;
-            }
-            nodemask_set(&mask, i);
+    i = -1;
+    while ((i = virBitmapNextSetBit(tmp_nodemask, i)) > 0) {
+        if (i > NUMA_NUM_NODES) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Host cannot support NUMA node %d"), i);
+            return -1;
         }
+        if (i > maxnode && !warned) {
+            VIR_WARN("nodeset is out of range, there is only %d NUMA "
+                     "nodes on host", maxnode);
+            warned = true;
+        }
+        nodemask_set(&mask, i);
     }
 
     mode = numatune.memory.mode;
@@ -1840,7 +1840,7 @@ qemuGetNumadAdvice(virDomainDefPtr def ATTRIBUTE_UNUSED)
 static int
 qemuProcessInitCpuAffinity(struct qemud_driver *driver,
                            virDomainObjPtr vm,
-                           const char *nodemask)
+                           virBitmapPtr nodemask)
 {
     int ret = -1;
     int i, hostcpus, maxcpu = QEMUD_CPUMASK_LEN;
@@ -1870,7 +1870,10 @@ qemuProcessInitCpuAffinity(struct qemud_driver *driver,
         for (i = 0; i < driver->caps->host.nnumaCell; i++) {
             int j;
             int cur_ncpus = driver->caps->host.numaCell[i]->ncpus;
-            if (nodemask[i]) {
+            bool result;
+            if (virBitmapGetBit(nodemask, i, &result) < 0)
+                goto cleanup;
+            if (result) {
                 for (j = 0; j < cur_ncpus; j++)
                     ignore_value(virBitmapSetBit(cpumap,
                                                  driver->caps->host.numaCell[i]->cpus[j]));
@@ -2575,7 +2578,7 @@ struct qemuProcessHookData {
     virConnectPtr conn;
     virDomainObjPtr vm;
     struct qemud_driver *driver;
-    char *nodemask;
+    virBitmapPtr nodemask;
 };
 
 static int qemuProcessHook(void *data)
@@ -3332,7 +3335,7 @@ int qemuProcessStart(virConnectPtr conn,
     unsigned long cur_balloon;
     int i;
     char *nodeset = NULL;
-    char *nodemask = NULL;
+    virBitmapPtr nodemask = NULL;
     unsigned int stop_flags;
 
     /* Okay, these are just internal flags,
@@ -3529,13 +3532,8 @@ int qemuProcessStart(virConnectPtr conn,
 
         VIR_DEBUG("Nodeset returned from numad: %s", nodeset);
 
-        if (VIR_ALLOC_N(nodemask, VIR_DOMAIN_CPUMASK_LEN) < 0) {
-            virReportOOMError();
-            goto cleanup;
-        }
-
-        if (virDomainCpuSetParse(nodeset, 0, nodemask,
-                                 VIR_DOMAIN_CPUMASK_LEN) < 0)
+        if (virBitmapParse(nodeset, 0, &nodemask,
+                           VIR_DOMAIN_CPUMASK_LEN) < 0)
             goto cleanup;
     }
     hookData.nodemask = nodemask;
@@ -3864,7 +3862,7 @@ cleanup:
      * if we failed to initialize the now running VM. kill it off and
      * pretend we never started it */
     VIR_FREE(nodeset);
-    VIR_FREE(nodemask);
+    virBitmapFree(nodemask);
     virCommandFree(cmd);
     VIR_FORCE_CLOSE(logfile);
     qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, stop_flags);
-- 
1.7.10.2




More information about the libvir-list mailing list