On Tue, Aug 21, 2012 at 05:18:42PM +0800, Hu Tao wrote: > This patch introduces support of setting emulator's period and > quota to limit cpu bandwidth when the vm starts. Also updates > XML Schema for new entries and docs. > --- > docs/formatdomain.html.in | 24 ++++++++++++++++++++++++ > docs/schemas/domaincommon.rng | 10 ++++++++++ > src/conf/domain_conf.c | 25 +++++++++++++++++++++++-- > src/conf/domain_conf.h | 2 ++ > src/qemu/qemu_cgroup.c | 11 ++++++++++- > 5 files changed, 69 insertions(+), 3 deletions(-) > > diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in > index 81ec2cd..6142f4b 100644 > --- a/docs/formatdomain.html.in > +++ b/docs/formatdomain.html.in > @@ -388,6 +388,8 @@ > <shares>2048</shares> > <period>1000000</period> > <quota>-1</quota> > + <emulator_period>1000000</period> > + <emulator_quota>-1</quota> > </cputune> > ... > </domain> > @@ -451,6 +453,28 @@ > <span class="since">Only QEMU driver support since 0.9.4, LXC since > 0.9.10</span> > </dd> > + > + <dt><code>emulator_period</code></dt> > + <dd> > + The optional <code>emulator_period</code> element specifies the enforcement > + interval(unit: microseconds). Within <code>emulator_period</code>, emulator > + threads(those excluding vcpus) of the domain will not be allowed to consume > + more than <code>emulator_quota</code> worth of runtime. The value should be > + in range [1000, 1000000]. A period with value 0 means no value. > + <span class="since">Only QEMU driver support since 0.10.0</span> > + </dd> > + <dt><code>emulator_quota</code></dt> > + <dd> > + The optional <code>emulator_quota</code> element specifies the maximum > + allowed bandwidth(unit: microseconds) for domain's emulator threads(those > + excluding vcpus). A domain with <code>emulator_quota</code> as any negative > + value indicates that the domain has infinite bandwidth for emulator threads > + (those excluding vcpus), which means that it is not bandwidth controlled. > + The value should be in range [1000, 18446744073709551] or less than 0. A > + quota with value 0 means no value. > + <span class="since">Only QEMU driver support since 0.10.0</span> > + </dd> > + > </dl> > > > diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng > index b02ad96..7aa6e47 100644 > --- a/docs/schemas/domaincommon.rng > +++ b/docs/schemas/domaincommon.rng > @@ -581,6 +581,16 @@ > <ref name="cpuquota"/> > </element> > </optional> > + <optional> > + <element name="emulator_period"> > + <ref name="cpuperiod"/> > + </element> > + </optional> > + <optional> > + <element name="emulator_quota"> > + <ref name="cpuquota"/> > + </element> > + </optional> > <zeroOrMore> > <element name="vcpupin"> > <attribute name="vcpu"> > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > index dab9c5d..7bb07b4 100644 > --- a/src/conf/domain_conf.c > +++ b/src/conf/domain_conf.c > @@ -8297,6 +8297,14 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, > &def->cputune.quota) < 0) > def->cputune.quota = 0; > > + if (virXPathULongLong("string(./cputune/emulator_period[1])", ctxt, > + &def->cputune.emulator_period) < 0) > + def->cputune.emulator_period = 0; > + > + if (virXPathLongLong("string(./cputune/emulator_quota[1])", ctxt, > + &def->cputune.emulator_quota) < 0) > + def->cputune.emulator_quota = 0; > + > if ((n = virXPathNodeSet("./cputune/vcpupin", ctxt, &nodes)) < 0) { > goto error; > } > @@ -13030,7 +13038,8 @@ virDomainDefFormatInternal(virDomainDefPtr def, > > if (def->cputune.shares || def->cputune.vcpupin || > def->cputune.period || def->cputune.quota || > - def->cputune.emulatorpin) > + def->cputune.emulatorpin || > + def->cputune.emulator_period || def->cputune.emulator_quota) > virBufferAddLit(buf, " <cputune>\n"); > > if (def->cputune.shares) > @@ -13042,6 +13051,17 @@ virDomainDefFormatInternal(virDomainDefPtr def, > if (def->cputune.quota) > virBufferAsprintf(buf, " <quota>%lld</quota>\n", > def->cputune.quota); > + > + if (def->cputune.emulator_period) > + virBufferAsprintf(buf, " <emulator_period>%llu" > + "</emulator_period>\n", > + def->cputune.emulator_period); > + > + if (def->cputune.emulator_quota) > + virBufferAsprintf(buf, " <emulator_quota>%lld" > + "</emulator_quota>\n", > + def->cputune.emulator_quota); > + > if (def->cputune.vcpupin) { > for (i = 0; i < def->cputune.nvcpupin; i++) { > virBufferAsprintf(buf, " <vcpupin vcpu='%u' ", > @@ -13080,7 +13100,8 @@ virDomainDefFormatInternal(virDomainDefPtr def, > > if (def->cputune.shares || def->cputune.vcpupin || > def->cputune.period || def->cputune.quota || > - def->cputune.emulatorpin) > + def->cputune.emulatorpin || > + def->cputune.emulator_period || def->cputune.emulator_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 b6bf5a8..089d9bc 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 emulator_period; > + long long emulator_quota; > int nvcpupin; > virDomainVcpuPinDefPtr *vcpupin; > virDomainVcpuPinDefPtr emulatorpin; > diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c > index 2fb29b5..2237d11 100644 > --- a/src/qemu/qemu_cgroup.c > +++ b/src/qemu/qemu_cgroup.c > @@ -564,7 +564,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", > @@ -631,6 +631,8 @@ int qemuSetupCgroupForEmulator(struct qemud_driver *driver, > virCgroupPtr cgroup = NULL; > virCgroupPtr cgroup_emulator = NULL; > virDomainDefPtr def = vm->def; > + unsigned long long period = vm->def->cputune.emulator_period; > + long long quota = vm->def->cputune.emulator_quota; > int rc, i; > > if (driver->cgroup == NULL) > @@ -672,6 +674,13 @@ int qemuSetupCgroupForEmulator(struct qemud_driver *driver, > qemuSetupCgroupEmulatorPin(cgroup_emulator, def->cputune.emulatorpin) < 0) > goto cleanup; > > + if (period || quota) { > + if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) { > + if (qemuSetupCgroupVcpuBW(cgroup_emulator, period, quota) < 0) > + goto cleanup; > + } > + } > + > virCgroupFree(&cgroup_emulator); > virCgroupFree(&cgroup); > return 0; ACK, looks fine, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@xxxxxxxxxxxx | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list