[libvirt] [PATCH v3 01/13] cgroup: Prepare for sparse vCPU topologies in virCgroupGetPercpuStats

Peter Krempa pkrempa at redhat.com
Fri Feb 5 15:44:37 UTC 2016


Pass a bitmap of enabled guest vCPUs to virCgroupGetPercpuStats so that
non-continuous vCPU topologies can be used.
---

Notes:
    v3:
    - don't allocate @guestvcpus when qemu doesn't report vcpu pids

 src/lxc/lxc_driver.c   |  2 +-
 src/qemu/qemu_driver.c |  8 +++++++-
 src/util/vircgroup.c   | 16 ++++++++--------
 src/util/vircgroup.h   |  3 ++-
 tests/vircgrouptest.c  |  2 +-
 5 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index b3399d9..41639ac 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -5706,7 +5706,7 @@ lxcDomainGetCPUStats(virDomainPtr dom,
                                               params, nparams);
     else
         ret = virCgroupGetPercpuStats(priv->cgroup, params,
-                                      nparams, start_cpu, ncpus, 0);
+                                      nparams, start_cpu, ncpus, NULL);
  cleanup:
     virObjectUnlock(vm);
     return ret;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f2db7d7..78f177a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -18205,6 +18205,7 @@ qemuDomainGetCPUStats(virDomainPtr domain,
     virDomainObjPtr vm = NULL;
     int ret = -1;
     qemuDomainObjPrivatePtr priv;
+    virBitmapPtr guestvcpus = NULL;

     virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY, -1);

@@ -18228,13 +18229,18 @@ qemuDomainGetCPUStats(virDomainPtr domain,
         goto cleanup;
     }

+    if (qemuDomainHasVcpuPids(vm) &&
+        !(guestvcpus = virDomainDefGetOnlineVcpumap(vm->def)))
+        goto cleanup;
+
     if (start_cpu == -1)
         ret = virCgroupGetDomainTotalCpuStats(priv->cgroup,
                                               params, nparams);
     else
         ret = virCgroupGetPercpuStats(priv->cgroup, params, nparams,
-                                      start_cpu, ncpus, priv->nvcpupids);
+                                      start_cpu, ncpus, guestvcpus);
  cleanup:
+    virBitmapFree(guestvcpus);
     virDomainObjEndAPI(&vm);
     return ret;
 }
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index 2f54cf2..f625cbc 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -3161,17 +3161,17 @@ virCgroupDenyDevicePath(virCgroupPtr group, const char *path, int perms)
  */
 static int
 virCgroupGetPercpuVcpuSum(virCgroupPtr group,
-                          unsigned int nvcpupids,
+                          virBitmapPtr guestvcpus,
                           unsigned long long *sum_cpu_time,
                           size_t nsum,
                           virBitmapPtr cpumap)
 {
     int ret = -1;
-    size_t i;
+    ssize_t i = -1;
     char *buf = NULL;
     virCgroupPtr group_vcpu = NULL;

-    for (i = 0; i < nvcpupids; i++) {
+    while ((i = virBitmapNextSetBit(guestvcpus, i)) >= 0) {
         char *pos;
         unsigned long long tmp;
         ssize_t j;
@@ -3233,7 +3233,7 @@ virCgroupGetPercpuStats(virCgroupPtr group,
                         unsigned int nparams,
                         int start_cpu,
                         unsigned int ncpus,
-                        unsigned int nvcpupids)
+                        virBitmapPtr guestvcpus)
 {
     int ret = -1;
     size_t i;
@@ -3248,7 +3248,7 @@ virCgroupGetPercpuStats(virCgroupPtr group,

     /* return the number of supported params */
     if (nparams == 0 && ncpus != 0) {
-        if (nvcpupids == 0)
+        if (!guestvcpus)
             return CGROUP_NB_PER_CPU_STAT_PARAM;
         else
             return CGROUP_NB_PER_CPU_STAT_PARAM + 1;
@@ -3303,11 +3303,11 @@ virCgroupGetPercpuStats(virCgroupPtr group,
     /* return percpu vcputime in index 1 */
     param_idx = 1;

-    if (nvcpupids > 0 && param_idx < nparams) {
+    if (guestvcpus && param_idx < nparams) {
         if (VIR_ALLOC_N(sum_cpu_time, need_cpus) < 0)
             goto cleanup;
-        if (virCgroupGetPercpuVcpuSum(group, nvcpupids, sum_cpu_time, need_cpus,
-                                      cpumap) < 0)
+        if (virCgroupGetPercpuVcpuSum(group, guestvcpus, sum_cpu_time,
+                                      need_cpus, cpumap) < 0)
             goto cleanup;

         for (i = start_cpu; i < need_cpus; i++) {
diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h
index bec88dc..b1bf731 100644
--- a/src/util/vircgroup.h
+++ b/src/util/vircgroup.h
@@ -26,6 +26,7 @@
 # define __VIR_CGROUP_H__

 # include "virutil.h"
+# include "virbitmap.h"

 struct virCgroup;
 typedef struct virCgroup *virCgroupPtr;
@@ -246,7 +247,7 @@ virCgroupGetPercpuStats(virCgroupPtr group,
                         unsigned int nparams,
                         int start_cpu,
                         unsigned int ncpus,
-                        unsigned int nvcpupids);
+                        virBitmapPtr guestvcpus);

 int
 virCgroupGetDomainTotalCpuStats(virCgroupPtr group,
diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c
index 7ea6e13..322f6cb 100644
--- a/tests/vircgrouptest.c
+++ b/tests/vircgrouptest.c
@@ -656,7 +656,7 @@ static int testCgroupGetPercpuStats(const void *args ATTRIBUTE_UNUSED)

     if ((rv = virCgroupGetPercpuStats(cgroup,
                                       params,
-                                      1, 0, EXPECTED_NCPUS, 0)) < 0) {
+                                      1, 0, EXPECTED_NCPUS, NULL)) < 0) {
         fprintf(stderr, "Failed call to virCgroupGetPercpuStats for /virtualmachines cgroup: %d\n", -rv);
         goto cleanup;
     }
-- 
2.6.2




More information about the libvir-list mailing list