[libvirt] [PATCH v2 3/9] use virBitmap to store cpupin info

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


---
 src/conf/domain_conf.c   |  148 +++++++++++++++-------------------------------
 src/conf/domain_conf.h   |    6 +-
 src/libvirt_private.syms |    1 +
 src/qemu/qemu_cgroup.c   |    3 +-
 src/qemu/qemu_driver.c   |   29 +++++----
 src/qemu/qemu_process.c  |   21 ++++---
 6 files changed, 81 insertions(+), 127 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 8952b69..b07b6b7 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -52,6 +52,7 @@
 #include "netdev_bandwidth_conf.h"
 #include "netdev_vlan_conf.h"
 #include "device_conf.h"
+#include "bitmap.h"
 
 #define VIR_FROM_THIS VIR_FROM_DOMAIN
 
@@ -1510,10 +1511,9 @@ virDomainVcpuPinDefCopy(virDomainVcpuPinDefPtr *src, int nvcpupin)
     for (i = 0; i < nvcpupin; i++) {
         if (VIR_ALLOC(ret[i]) < 0)
             goto no_memory;
-        if (VIR_ALLOC_N(ret[i]->cpumask, VIR_DOMAIN_CPUMASK_LEN) < 0)
-            goto no_memory;
         ret[i]->vcpuid = src[i]->vcpuid;
-        memcpy(ret[i]->cpumask, src[i]->cpumask, VIR_DOMAIN_CPUMASK_LEN);
+        if ((ret[i]->cpumask = virBitmapCopy(src[i]->cpumask)) == NULL)
+            goto no_memory;
     }
 
     return ret;
@@ -1522,7 +1522,7 @@ no_memory:
     if (ret) {
         for ( ; i >= 0; --i) {
             if (ret[i]) {
-                VIR_FREE(ret[i]->cpumask);
+                virBitmapFree(ret[i]->cpumask);
                 VIR_FREE(ret[i]);
             }
         }
@@ -1534,8 +1534,17 @@ no_memory:
 }
 
 void
-virDomainVcpuPinDefFree(virDomainVcpuPinDefPtr *def,
-                        int nvcpupin)
+virDomainVcpuPinDefFree(virDomainVcpuPinDefPtr def)
+{
+    if (def) {
+        virBitmapFree(def->cpumask);
+        VIR_FREE(def);
+    }
+}
+
+void
+virDomainVcpuPinDefArrayFree(virDomainVcpuPinDefPtr *def,
+                             int nvcpupin)
 {
     int i;
 
@@ -1543,8 +1552,7 @@ virDomainVcpuPinDefFree(virDomainVcpuPinDefPtr *def,
         return;
 
     for(i = 0; i < nvcpupin; i++) {
-        VIR_FREE(def[i]->cpumask);
-        VIR_FREE(def[i]);
+        virDomainVcpuPinDefFree(def[i]);
     }
 
     VIR_FREE(def);
@@ -1668,7 +1676,9 @@ void virDomainDefFree(virDomainDefPtr def)
 
     virCPUDefFree(def->cpu);
 
-    virDomainVcpuPinDefFree(def->cputune.vcpupin, def->cputune.nvcpupin);
+    virDomainVcpuPinDefArrayFree(def->cputune.vcpupin, def->cputune.nvcpupin);
+
+    virDomainVcpuPinDefFree(def->cputune.emulatorpin);
 
     VIR_FREE(def->numatune.memory.nodemask);
 
@@ -8025,12 +8035,8 @@ virDomainVcpuPinDefParseXML(const xmlNodePtr node,
         char *set = tmp;
         int cpumasklen = VIR_DOMAIN_CPUMASK_LEN;
 
-        if (VIR_ALLOC_N(def->cpumask, cpumasklen) < 0) {
-            virReportOOMError();
-            goto error;
-        }
-        if (virDomainCpuSetParse(set, 0, def->cpumask,
-                                 cpumasklen) < 0)
+        if (virBitmapParse(set, 0, &def->cpumask,
+                           cpumasklen) < 0)
            goto error;
         VIR_FREE(tmp);
     } else {
@@ -8465,18 +8471,11 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
             goto error;
         }
 
-        if (VIR_ALLOC(def->cputune.emulatorpin) < 0) {
-            goto no_memory;
-        }
+        def->cputune.emulatorpin = virDomainVcpuPinDefParseXML(nodes[0], ctxt,
+                                                               def->maxvcpus, 1);
 
-        virDomainVcpuPinDefPtr emulatorpin = NULL;
-        emulatorpin = virDomainVcpuPinDefParseXML(nodes[0], ctxt,
-                                                  def->maxvcpus, 1);
-
-        if (!emulatorpin)
+        if (!def->cputune.emulatorpin)
             goto error;
-
-        def->cputune.emulatorpin = emulatorpin;
     }
     VIR_FREE(nodes);
 
@@ -11093,34 +11092,6 @@ virDomainVcpuPinFindByVcpu(virDomainVcpuPinDefPtr *def,
     return NULL;
 }
 
-static char *bitmapFromBytemap(unsigned char *bytemap, int maplen)
-{
-    char *bitmap = NULL;
-    int i;
-
-    if (VIR_ALLOC_N(bitmap, VIR_DOMAIN_CPUMASK_LEN) < 0) {
-        virReportOOMError();
-        goto cleanup;
-    }
-
-    /* Reset bitmap to all 0s. */
-    for (i = 0; i < VIR_DOMAIN_CPUMASK_LEN; i++)
-        bitmap[i] = 0;
-
-    /* Convert bitmap (bytemap) to bitmap, which is byte map? */
-    for (i = 0; i < maplen; i++) {
-        int cur;
-
-        for (cur = 0; cur < 8; cur++) {
-            if (bytemap[i] & (1 << cur))
-                bitmap[i * 8 + cur] = 1;
-        }
-    }
-
-cleanup:
-    return bitmap;
-}
-
 int virDomainVcpuPinAdd(virDomainVcpuPinDefPtr **vcpupin_list,
                         int *nvcpupin,
                         unsigned char *cpumap,
@@ -11128,20 +11099,21 @@ int virDomainVcpuPinAdd(virDomainVcpuPinDefPtr **vcpupin_list,
                         int vcpu)
 {
     virDomainVcpuPinDefPtr vcpupin = NULL;
-    char *cpumask = NULL;
 
     if (!vcpupin_list)
         return -1;
 
-    if ((cpumask = bitmapFromBytemap(cpumap, maplen)) == NULL)
-        return -1;
-
     vcpupin = virDomainVcpuPinFindByVcpu(*vcpupin_list,
                                          *nvcpupin,
                                          vcpu);
     if (vcpupin) {
         vcpupin->vcpuid = vcpu;
-        vcpupin->cpumask = cpumask;
+        virBitmapFree(vcpupin->cpumask);
+        vcpupin->cpumask = virBitmapAllocFromData(cpumap, maplen);
+        if (!vcpupin->cpumask) {
+            virReportOOMError();
+            return -1;
+        }
 
         return 0;
     }
@@ -11150,16 +11122,17 @@ int virDomainVcpuPinAdd(virDomainVcpuPinDefPtr **vcpupin_list,
 
     if (VIR_ALLOC(vcpupin) < 0) {
         virReportOOMError();
-        VIR_FREE(cpumask);
         return -1;
     }
     vcpupin->vcpuid = vcpu;
-    vcpupin->cpumask = cpumask;
-
+    vcpupin->cpumask = virBitmapAllocFromData(cpumap, maplen);
+    if (!vcpupin->cpumask) {
+        virReportOOMError();
+        return -1;
+    }
 
     if (VIR_REALLOC_N(*vcpupin_list, *nvcpupin + 1) < 0) {
         virReportOOMError();
-        VIR_FREE(cpumask);
         VIR_FREE(vcpupin);
         return -1;
     }
@@ -11214,68 +11187,43 @@ virDomainEmulatorPinAdd(virDomainDefPtr def,
                         int maplen)
 {
     virDomainVcpuPinDefPtr emulatorpin = NULL;
-    char *cpumask = NULL;
-    int i;
-
-    if (VIR_ALLOC_N(cpumask, VIR_DOMAIN_CPUMASK_LEN) < 0) {
-        virReportOOMError();
-        goto cleanup;
-    }
-
-    /* Convert bitmap (cpumap) to cpumask, which is byte map. */
-    for (i = 0; i < maplen; i++) {
-        int cur;
-
-        for (cur = 0; cur < 8; cur++) {
-            if (cpumap[i] & (1 << cur))
-                cpumask[i * 8 + cur] = 1;
-        }
-    }
 
     if (!def->cputune.emulatorpin) {
         /* No emulatorpin exists yet. */
         if (VIR_ALLOC(emulatorpin) < 0) {
             virReportOOMError();
-            goto cleanup;
+            return -1;
         }
 
         emulatorpin->vcpuid = -1;
-        emulatorpin->cpumask = cpumask;
+        emulatorpin->cpumask = virBitmapAllocFromData(cpumap, maplen);
+        if (!emulatorpin->cpumask)
+            return -1;
+
         def->cputune.emulatorpin = emulatorpin;
     } else {
         /* Since there is only 1 emulatorpin for each vm,
          * juest replace the old one.
          */
-        VIR_FREE(def->cputune.emulatorpin->cpumask);
-        def->cputune.emulatorpin->cpumask = cpumask;
+        virBitmapFree(def->cputune.emulatorpin->cpumask);
+        def->cputune.emulatorpin->cpumask = virBitmapAllocFromData(cpumap, maplen);
+        if (!def->cputune.emulatorpin->cpumask)
+            return -1;
     }
 
     return 0;
-
-cleanup:
-    VIR_FREE(cpumask);
-    return -1;
 }
 
 int
 virDomainEmulatorPinDel(virDomainDefPtr def)
 {
-    virDomainVcpuPinDefPtr emulatorpin = NULL;
-
-    /* No emulatorpin exists yet */
     if (!def->cputune.emulatorpin) {
         return 0;
     }
 
-    emulatorpin = def->cputune.emulatorpin;
-
-    VIR_FREE(emulatorpin->cpumask);
-    VIR_FREE(emulatorpin);
+    virDomainVcpuPinDefFree(def->cputune.emulatorpin);
     def->cputune.emulatorpin = NULL;
 
-    if (def->cputune.emulatorpin)
-        return -1;
-
     return 0;
 }
 
@@ -13248,8 +13196,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
                               def->cputune.vcpupin[i]->vcpuid);
 
             char *cpumask = NULL;
-            cpumask = virDomainCpuSetFormat(def->cputune.vcpupin[i]->cpumask,
-                                            VIR_DOMAIN_CPUMASK_LEN);
+            cpumask = virBitmapFormat(def->cputune.vcpupin[i]->cpumask);
 
             if (cpumask == NULL) {
                 virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -13266,8 +13213,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
         virBufferAsprintf(buf, "    <emulatorpin ");
 
         char *cpumask = NULL;
-        cpumask = virDomainCpuSetFormat(def->cputune.emulatorpin->cpumask,
-                                        VIR_DOMAIN_CPUMASK_LEN);
+        cpumask = virBitmapFormat(def->cputune.emulatorpin->cpumask);
         if (cpumask == NULL) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            "%s", _("failed to format cpuset for emulator"));
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 3995c2d..bb3721c 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -46,6 +46,7 @@
 # include "virnetdevvlan.h"
 # include "virobject.h"
 # include "device_conf.h"
+# include "bitmap.h"
 
 /* forward declarations of all device types, required by
  * virDomainDeviceDef
@@ -1538,10 +1539,11 @@ typedef struct _virDomainVcpuPinDef virDomainVcpuPinDef;
 typedef virDomainVcpuPinDef *virDomainVcpuPinDefPtr;
 struct _virDomainVcpuPinDef {
     int vcpuid;
-    char *cpumask;
+    virBitmapPtr cpumask;
 };
 
-void virDomainVcpuPinDefFree(virDomainVcpuPinDefPtr *def, int nvcpupin);
+void virDomainVcpuPinDefFree(virDomainVcpuPinDefPtr def);
+void virDomainVcpuPinDefArrayFree(virDomainVcpuPinDefPtr *def, int nvcpupin);
 
 virDomainVcpuPinDefPtr *virDomainVcpuPinDefCopy(virDomainVcpuPinDefPtr *src,
                                                 int nvcpupin);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 028b65c..d7cd356 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -524,6 +524,7 @@ virDomainTimerTickpolicyTypeToString;
 virDomainTimerTrackTypeFromString;
 virDomainTimerTrackTypeToString;
 virDomainVcpuPinAdd;
+virDomainVcpuPinDefArrayFree;
 virDomainVcpuPinDefCopy;
 virDomainVcpuPinDefFree;
 virDomainVcpuPinDel;
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index c95cc77..be95761 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -513,8 +513,7 @@ int qemuSetupCgroupEmulatorPin(virCgroupPtr cgroup,
     int rc = 0;
     char *new_cpus = NULL;
 
-    new_cpus = virDomainCpuSetFormat(vcpupin->cpumask,
-                                     VIR_DOMAIN_CPUMASK_LEN);
+    new_cpus = virBitmapFormat(vcpupin->cpumask);
     if (!new_cpus) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("failed to convert cpu mask"));
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b12d9bc..bdff4bb 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3785,7 +3785,7 @@ qemudDomainPinVcpuFlags(virDomainPtr dom,
         if (virDomainVcpuPinAdd(&newVcpuPin, &newVcpuPinNum, cpumap, maplen, vcpu) < 0) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("failed to update vcpupin"));
-            virDomainVcpuPinDefFree(newVcpuPin, newVcpuPinNum);
+            virDomainVcpuPinDefArrayFree(newVcpuPin, newVcpuPinNum);
             goto cleanup;
         }
 
@@ -3818,7 +3818,7 @@ qemudDomainPinVcpuFlags(virDomainPtr dom,
             }
         } else {
             if (vm->def->cputune.vcpupin)
-                virDomainVcpuPinDefFree(vm->def->cputune.vcpupin, vm->def->cputune.nvcpupin);
+                virDomainVcpuPinDefArrayFree(vm->def->cputune.vcpupin, vm->def->cputune.nvcpupin);
 
             vm->def->cputune.vcpupin = newVcpuPin;
             vm->def->cputune.nvcpupin = newVcpuPinNum;
@@ -3826,7 +3826,7 @@ qemudDomainPinVcpuFlags(virDomainPtr dom,
         }
 
         if (newVcpuPin)
-            virDomainVcpuPinDefFree(newVcpuPin, newVcpuPinNum);
+            virDomainVcpuPinDefArrayFree(newVcpuPin, newVcpuPinNum);
 
         if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
             goto cleanup;
@@ -3901,8 +3901,9 @@ qemudDomainGetVcpuPinInfo(virDomainPtr dom,
     int maxcpu, hostcpus, vcpu, pcpu;
     int n;
     virDomainVcpuPinDefPtr *vcpupin_list;
-    char *cpumask = NULL;
+    virBitmapPtr cpumask = NULL;
     unsigned char *cpumap;
+    bool pinned;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -3961,7 +3962,9 @@ qemudDomainGetVcpuPinInfo(virDomainPtr dom,
         cpumask = vcpupin_list[n]->cpumask;
         cpumap = VIR_GET_CPUMAP(cpumaps, maplen, vcpu);
         for (pcpu = 0; pcpu < maxcpu; pcpu++) {
-            if (cpumask[pcpu] == 0)
+            if (virBitmapGetBit(cpumask, pcpu, &pinned) < 0)
+                goto cleanup;
+            if (!pinned)
                 VIR_UNUSE_CPU(cpumap, pcpu);
         }
     }
@@ -4045,7 +4048,7 @@ qemudDomainPinEmulator(virDomainPtr dom,
             if (virDomainVcpuPinAdd(&newVcpuPin, &newVcpuPinNum, cpumap, maplen, -1) < 0) {
                 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                _("failed to update vcpupin"));
-                virDomainVcpuPinDefFree(newVcpuPin, newVcpuPinNum);
+                virDomainVcpuPinDefArrayFree(newVcpuPin, newVcpuPinNum);
                 goto cleanup;
             }
 
@@ -4083,16 +4086,13 @@ qemudDomainPinEmulator(virDomainPtr dom,
                     goto cleanup;
                 }
             } else {
-                if (vm->def->cputune.emulatorpin) {
-                    VIR_FREE(vm->def->cputune.emulatorpin->cpumask);
-                    VIR_FREE(vm->def->cputune.emulatorpin);
-                }
+                virDomainVcpuPinDefFree(vm->def->cputune.emulatorpin);
                 vm->def->cputune.emulatorpin = newVcpuPin[0];
                 VIR_FREE(newVcpuPin);
             }
 
             if (newVcpuPin)
-                virDomainVcpuPinDefFree(newVcpuPin, newVcpuPinNum);
+                virDomainVcpuPinDefArrayFree(newVcpuPin, newVcpuPinNum);
         } else {
             virReportError(VIR_ERR_OPERATION_INVALID,
                            "%s", _("cpu affinity is not supported"));
@@ -4151,7 +4151,8 @@ qemudDomainGetEmulatorPinInfo(virDomainPtr dom,
     int ret = -1;
     int maxcpu, hostcpus, pcpu;
     virDomainVcpuPinDefPtr emulatorpin = NULL;
-    char *cpumask = NULL;
+    virBitmapPtr cpumask = NULL;
+    bool pinned;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -4200,7 +4201,9 @@ qemudDomainGetEmulatorPinInfo(virDomainPtr dom,
 
     cpumask = emulatorpin->cpumask;
     for (pcpu = 0; pcpu < maxcpu; pcpu++) {
-        if (cpumask[pcpu] == 0)
+        if (virBitmapGetBit(cpumask, pcpu, &pinned) < 0)
+            goto cleanup;
+        if (!pinned)
             VIR_UNUSE_CPU(cpumaps, pcpu);
     }
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 93653c6..4e9aaef 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1951,10 +1951,11 @@ qemuProcessSetVcpuAffinites(virConnectPtr conn,
     virDomainDefPtr def = vm->def;
     virNodeInfo nodeinfo;
     pid_t vcpupid;
-    unsigned char *cpumask;
+    virBitmapPtr cpumask;
     int vcpu, cpumaplen, hostcpus, maxcpu, n;
     unsigned char *cpumap = NULL;
     int ret = -1;
+    bool result;
 
     if (virNodeGetInfo(conn, &nodeinfo) != 0) {
         return  -1;
@@ -1986,13 +1987,12 @@ qemuProcessSetVcpuAffinites(virConnectPtr conn,
         vcpu = def->cputune.vcpupin[n]->vcpuid;
 
         memset(cpumap, 0, cpumaplen);
-        cpumask = (unsigned char *)def->cputune.vcpupin[n]->cpumask;
+        cpumask = def->cputune.vcpupin[n]->cpumask;
         vcpupid = priv->vcpupids[vcpu];
 
-        for (i = 0 ; i < VIR_DOMAIN_CPUMASK_LEN ; i++) {
-            if (cpumask[i])
-                VIR_USE_CPU(cpumap, i);
-        }
+        i = -1;
+        while ((i = virBitmapNextSetBit(cpumask, i)) > 0)
+            VIR_USE_CPU(cpumap, i);
 
         if (virProcessInfoSetAffinity(vcpupid,
                                       cpumap,
@@ -2015,11 +2015,12 @@ qemuProcessSetEmulatorAffinites(virConnectPtr conn,
 {
     virDomainDefPtr def = vm->def;
     pid_t pid = vm->pid;
-    unsigned char *cpumask = NULL;
+    virBitmapPtr cpumask = NULL;
     unsigned char *cpumap = NULL;
     virNodeInfo nodeinfo;
     int cpumaplen, hostcpus, maxcpu, i;
     int ret = -1;
+    bool result;
 
     if (virNodeGetInfo(conn, &nodeinfo) != 0)
         return -1;
@@ -2039,9 +2040,11 @@ qemuProcessSetEmulatorAffinites(virConnectPtr conn,
         return -1;
     }
 
-    cpumask = (unsigned char *)def->cputune.emulatorpin->cpumask;
+    cpumask = def->cputune.emulatorpin->cpumask;
     for (i = 0; i < VIR_DOMAIN_CPUMASK_LEN; i++) {
-        if (cpumask[i])
+        if (virBitmapGetBit(cpumask, i, &result) < 0)
+            goto cleanup;
+        if (result)
             VIR_USE_CPU(cpumap, i);
     }
 
-- 
1.7.10.2




More information about the libvir-list mailing list