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