From: Wen Congyang <wency(a)cn.fujitsu.com>
set hypervisor's period and quota to limit cpu bandwidth when the vm starts.
---
src/conf/domain_conf.c | 25 +++++++++++++++++++++++--
src/conf/domain_conf.h | 2 ++
src/qemu/qemu_cgroup.c | 13 +++++++++++--
3 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 4651765..c3959a7 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -8152,6 +8152,14 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
&def->cputune.quota) < 0)
def->cputune.quota = 0;
+ if (virXPathULongLong("string(./cputune/hypervisor_period[1])", ctxt,
+ &def->cputune.hypervisor_period) < 0)
+ def->cputune.hypervisor_period = 0;
+
+ if (virXPathLongLong("string(./cputune/hypervisor_quota[1])", ctxt,
+ &def->cputune.hypervisor_quota) < 0)
+ def->cputune.hypervisor_quota = 0;
+
if ((n = virXPathNodeSet("./cputune/vcpupin", ctxt, &nodes)) < 0) {
goto error;
}
@@ -12752,7 +12760,8 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virBufferAsprintf(buf, ">%u</vcpu>\n", def->maxvcpus);
if (def->cputune.shares || def->cputune.vcpupin ||
- def->cputune.period || def->cputune.quota)
+ def->cputune.period || def->cputune.quota ||
+ def->cputune.hypervisor_period || def->cputune.hypervisor_quota)
virBufferAddLit(buf, " <cputune>\n");
if (def->cputune.shares)
@@ -12764,6 +12773,17 @@ virDomainDefFormatInternal(virDomainDefPtr def,
if (def->cputune.quota)
virBufferAsprintf(buf, " <quota>%lld</quota>\n",
def->cputune.quota);
+
+ if (def->cputune.hypervisor_period)
+ virBufferAsprintf(buf, " <hypervisor_period>%llu"
+ "</hypervisor_period>\n",
+ def->cputune.hypervisor_period);
+
+ if (def->cputune.hypervisor_period)
+ virBufferAsprintf(buf, " <hypervisor_quota>%lld"
+ "</hypervisor_quota>\n",
+ def->cputune.hypervisor_quota);
+
if (def->cputune.vcpupin) {
for (i = 0; i < def->cputune.nvcpupin; i++) {
virBufferAsprintf(buf, " <vcpupin vcpu='%u' ",
@@ -12785,7 +12805,8 @@ virDomainDefFormatInternal(virDomainDefPtr def,
}
if (def->cputune.shares || def->cputune.vcpupin ||
- def->cputune.period || def->cputune.quota)
+ def->cputune.period || def->cputune.quota ||
+ def->cputune.hypervisor_period || def->cputune.hypervisor_quota)
virBufferAddLit(buf, " </cputune>\n");
if (def->numatune.memory.nodemask ||
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 3712785..4b42d32 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1598,6 +1598,8 @@ struct _virDomainDef {
unsigned long shares;
unsigned long long period;
long long quota;
+ unsigned long long hypervisor_period;
+ long long hypervisor_quota;
int nvcpupin;
virDomainVcpuPinDefPtr *vcpupin;
} cputune;
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 021f489..b675902 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -509,7 +509,7 @@ int qemuSetupCgroupForVcpu(struct qemud_driver *driver,
virDomainObjPtr vm)
}
if (priv->nvcpupids == 0 || priv->vcpupids[0] == vm->pid) {
- /* If we does not know VCPU<->PID mapping or all vcpu runs in the same
+ /* If we don't know VCPU<->PID mapping or all vcpu runs in the same
* thread, we cannot control each vcpu.
*/
virCgroupFree(&cgroup);
@@ -562,6 +562,8 @@ int qemuSetupCgroupForHypervisor(struct qemud_driver *driver,
virCgroupPtr cgroup = NULL;
virCgroupPtr cgroup_hypervisor = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
+ unsigned long long period = vm->def->cputune.hypervisor_period;
+ long long quota = vm->def->cputune.hypervisor_quota;
int rc;
if (driver->cgroup == NULL)
@@ -576,7 +578,7 @@ int qemuSetupCgroupForHypervisor(struct qemud_driver *driver,
}
if (priv->nvcpupids == 0 || priv->vcpupids[0] == vm->pid) {
- /* If we does not know VCPU<->PID mapping or all vcpu runs in the same
+ /* If we don't know VCPU<->PID mapping or all vcpu runs in the same
* thread, we cannot control each vcpu.
*/
virCgroupFree(&cgroup);
@@ -600,6 +602,13 @@ int qemuSetupCgroupForHypervisor(struct qemud_driver *driver,
goto cleanup;
}
+ if (period || quota) {
+ if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) {
+ if (qemuSetupCgroupCpuBandwidth(cgroup_hypervisor, period, quota) < 0)
+ goto cleanup;
+ }
+ }
+
virCgroupFree(&cgroup_hypervisor);
virCgroupFree(&cgroup);
return 0;
--
1.7.4.4