From: Hyman Huang(黄勇) <huangy81@xxxxxxxxxxxxxxx> Extend qemuDomainGetVcpus for getting dirtylimit info so that 'virsh vcpuinfo' api can display vcpu dirty page rate limit. Signed-off-by: Hyman Huang(黄勇) <huangy81@xxxxxxxxxxxxxxx> --- include/libvirt/libvirt-domain.h | 2 ++ src/qemu/qemu_driver.c | 62 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 2e49224..24348d0 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -2365,6 +2365,8 @@ struct _virVcpuInfo { int state; /* value from virVcpuState */ unsigned long long cpuTime; /* CPU time used, in nanoseconds */ int cpu; /* real CPU number, or one of the values from virVcpuHostCpuState */ + unsigned long long limit; /* virtual cpu dirty page rate limit in MB/s */ + unsigned long long current; /* virtual cpu dirty page rate in MB/s */ }; /** diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 981027a..235a187 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4756,6 +4756,64 @@ qemuDomainGetEmulatorPinInfo(virDomainPtr dom, } static int +qemuDomainGetVcpuDirtyLimit(virDomainPtr dom, + virDomainObj *vm, + virVcpuInfoPtr info, + int maxinfo) +{ + qemuDomainObjPrivate *priv = vm->privateData; + qemuMonitorVcpuDirtyLimitInfo dirtylimit_info; + size_t ncpuinfo = 0; + size_t i; + int ret = -1; + + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VCPU_DIRTY_LIMIT)) + return 0; + + if (qemuDomainObjBeginJob(vm, VIR_JOB_MODIFY) < 0) + goto endjob; + + if (virDomainObjCheckActive(vm) < 0) + goto endjob; + + qemuDomainObjEnterMonitor(vm); + if (qemuMonitorQueryVcpuDirtyLimit(priv->mon, &dirtylimit_info) < 0) { + qemuDomainObjExitMonitor(vm); + goto endjob; + } + qemuDomainObjExitMonitor(vm); + + /* qemu allow to set dirty page limit for hotpluggable vcpu, which + * therefore may return unhotpluggable vcpu dirty limit info for + * qmp command 'query-vcpu-dirty-limit', filter out that */ + for (i = 0; i < dirtylimit_info.nvcpus && ncpuinfo < maxinfo; i++) { + int cpu_index = dirtylimit_info.limits[i].idx; + + /* cpu index greater than array size of cpu info, which means + * the remaining cpus are hotpluggable but not active */ + if (cpu_index >= maxinfo) + break; + + virDomainVcpuDef *vcpu = virDomainDefGetVcpu(vm->def, cpu_index); + + if (!vcpu->online) + continue; + + virVcpuInfoPtr vcpuinfo = info + cpu_index; + + vcpuinfo->current = dirtylimit_info.limits[i].current; + vcpuinfo->limit = dirtylimit_info.limits[i].limit; + + ncpuinfo++; + } + ret = 0; + + endjob: + qemuDomainObjEndJob(vm); + return ret; +} + +static int qemuDomainGetVcpus(virDomainPtr dom, virVcpuInfoPtr info, int maxinfo, @@ -4779,6 +4837,10 @@ qemuDomainGetVcpus(virDomainPtr dom, ret = qemuDomainHelperGetVcpus(vm, info, NULL, NULL, maxinfo, cpumaps, maplen); + /* append dirty limit data to vcpu info */ + if (qemuDomainGetVcpuDirtyLimit(dom, vm, info, maxinfo) < 0) + goto cleanup; + cleanup: virDomainObjEndAPI(&vm); return ret; -- 1.8.3.1