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 | 11 ++++++++++-
3 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 98ea335..fd437a9 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -8235,6 +8235,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;
}
@@ -12993,7 +13001,8 @@ virDomainDefFormatInternal(virDomainDefPtr def,
if (def->cputune.shares || def->cputune.vcpupin ||
def->cputune.period || def->cputune.quota ||
- def->cputune.hypervisorpin)
+ def->cputune.hypervisorpin ||
+ def->cputune.hypervisor_period || def->cputune.hypervisor_quota)
virBufferAddLit(buf, " <cputune>\n");
if (def->cputune.shares)
@@ -13005,6 +13014,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' ",
@@ -13043,7 +13063,8 @@ virDomainDefFormatInternal(virDomainDefPtr def,
if (def->cputune.shares || def->cputune.vcpupin ||
def->cputune.period || def->cputune.quota ||
- def->cputune.hypervisorpin)
+ def->cputune.hypervisorpin ||
+ 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 9f63669..44283ef 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1607,6 +1607,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;
virDomainVcpuPinDefPtr hypervisorpin;
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 4d97665..27c0c8a 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -575,7 +575,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 vcpus run in the same
+ /* If we don't know VCPU<->PID mapping or all vcpu runs in the same
* thread, we cannot control each vcpu.
*/
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -639,6 +639,8 @@ int qemuSetupCgroupForHypervisor(struct qemud_driver *driver,
virCgroupPtr cgroup = NULL;
virCgroupPtr cgroup_hypervisor = NULL;
virDomainDefPtr def = vm->def;
+ unsigned long long period = vm->def->cputune.hypervisor_period;
+ long long quota = vm->def->cputune.hypervisor_quota;
int rc, i;
if (driver->cgroup == NULL)
@@ -680,6 +682,13 @@ int qemuSetupCgroupForHypervisor(struct qemud_driver *driver,
qemuSetupCgroupHypervisorPin(cgroup_hypervisor, def) < 0)
goto cleanup;
+ if (period || quota) {
+ if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) {
+ if (qemuSetupCgroupVcpuBW(cgroup_hypervisor, period, quota) < 0)
+ goto cleanup;
+ }
+ }
+
virCgroupFree(&cgroup_hypervisor);
virCgroupFree(&cgroup);
return 0;
--
1.7.10.2