mirror of https://gitee.com/openkylin/libvirt.git
qemu: introduce period/quota tuning for emulator
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.
This commit is contained in:
parent
1d4395eb47
commit
b65dafa812
|
@ -388,6 +388,8 @@
|
||||||
<shares>2048</shares>
|
<shares>2048</shares>
|
||||||
<period>1000000</period>
|
<period>1000000</period>
|
||||||
<quota>-1</quota>
|
<quota>-1</quota>
|
||||||
|
<emulator_period>1000000</period>
|
||||||
|
<emulator_quota>-1</quota>
|
||||||
</cputune>
|
</cputune>
|
||||||
...
|
...
|
||||||
</domain>
|
</domain>
|
||||||
|
@ -451,6 +453,28 @@
|
||||||
<span class="since">Only QEMU driver support since 0.9.4, LXC since
|
<span class="since">Only QEMU driver support since 0.9.4, LXC since
|
||||||
0.9.10</span>
|
0.9.10</span>
|
||||||
</dd>
|
</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>
|
</dl>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -581,6 +581,16 @@
|
||||||
<ref name="cpuquota"/>
|
<ref name="cpuquota"/>
|
||||||
</element>
|
</element>
|
||||||
</optional>
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<element name="emulator_period">
|
||||||
|
<ref name="cpuperiod"/>
|
||||||
|
</element>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<element name="emulator_quota">
|
||||||
|
<ref name="cpuquota"/>
|
||||||
|
</element>
|
||||||
|
</optional>
|
||||||
<zeroOrMore>
|
<zeroOrMore>
|
||||||
<element name="vcpupin">
|
<element name="vcpupin">
|
||||||
<attribute name="vcpu">
|
<attribute name="vcpu">
|
||||||
|
|
|
@ -8344,6 +8344,14 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
|
||||||
&def->cputune.quota) < 0)
|
&def->cputune.quota) < 0)
|
||||||
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) {
|
if ((n = virXPathNodeSet("./cputune/vcpupin", ctxt, &nodes)) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -13102,7 +13110,8 @@ virDomainDefFormatInternal(virDomainDefPtr def,
|
||||||
|
|
||||||
if (def->cputune.shares || def->cputune.vcpupin ||
|
if (def->cputune.shares || def->cputune.vcpupin ||
|
||||||
def->cputune.period || def->cputune.quota ||
|
def->cputune.period || def->cputune.quota ||
|
||||||
def->cputune.emulatorpin)
|
def->cputune.emulatorpin ||
|
||||||
|
def->cputune.emulator_period || def->cputune.emulator_quota)
|
||||||
virBufferAddLit(buf, " <cputune>\n");
|
virBufferAddLit(buf, " <cputune>\n");
|
||||||
|
|
||||||
if (def->cputune.shares)
|
if (def->cputune.shares)
|
||||||
|
@ -13114,6 +13123,17 @@ virDomainDefFormatInternal(virDomainDefPtr def,
|
||||||
if (def->cputune.quota)
|
if (def->cputune.quota)
|
||||||
virBufferAsprintf(buf, " <quota>%lld</quota>\n",
|
virBufferAsprintf(buf, " <quota>%lld</quota>\n",
|
||||||
def->cputune.quota);
|
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) {
|
if (def->cputune.vcpupin) {
|
||||||
for (i = 0; i < def->cputune.nvcpupin; i++) {
|
for (i = 0; i < def->cputune.nvcpupin; i++) {
|
||||||
virBufferAsprintf(buf, " <vcpupin vcpu='%u' ",
|
virBufferAsprintf(buf, " <vcpupin vcpu='%u' ",
|
||||||
|
@ -13152,7 +13172,8 @@ virDomainDefFormatInternal(virDomainDefPtr def,
|
||||||
|
|
||||||
if (def->cputune.shares || def->cputune.vcpupin ||
|
if (def->cputune.shares || def->cputune.vcpupin ||
|
||||||
def->cputune.period || def->cputune.quota ||
|
def->cputune.period || def->cputune.quota ||
|
||||||
def->cputune.emulatorpin)
|
def->cputune.emulatorpin ||
|
||||||
|
def->cputune.emulator_period || def->cputune.emulator_quota)
|
||||||
virBufferAddLit(buf, " </cputune>\n");
|
virBufferAddLit(buf, " </cputune>\n");
|
||||||
|
|
||||||
if (def->numatune.memory.nodemask ||
|
if (def->numatune.memory.nodemask ||
|
||||||
|
|
|
@ -1614,6 +1614,8 @@ struct _virDomainDef {
|
||||||
unsigned long shares;
|
unsigned long shares;
|
||||||
unsigned long long period;
|
unsigned long long period;
|
||||||
long long quota;
|
long long quota;
|
||||||
|
unsigned long long emulator_period;
|
||||||
|
long long emulator_quota;
|
||||||
int nvcpupin;
|
int nvcpupin;
|
||||||
virDomainVcpuPinDefPtr *vcpupin;
|
virDomainVcpuPinDefPtr *vcpupin;
|
||||||
virDomainVcpuPinDefPtr emulatorpin;
|
virDomainVcpuPinDefPtr emulatorpin;
|
||||||
|
|
|
@ -564,7 +564,7 @@ int qemuSetupCgroupForVcpu(struct qemud_driver *driver, virDomainObjPtr vm)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->nvcpupids == 0 || priv->vcpupids[0] == vm->pid) {
|
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.
|
* thread, we cannot control each vcpu.
|
||||||
*/
|
*/
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
@ -631,6 +631,8 @@ int qemuSetupCgroupForEmulator(struct qemud_driver *driver,
|
||||||
virCgroupPtr cgroup = NULL;
|
virCgroupPtr cgroup = NULL;
|
||||||
virCgroupPtr cgroup_emulator = NULL;
|
virCgroupPtr cgroup_emulator = NULL;
|
||||||
virDomainDefPtr def = vm->def;
|
virDomainDefPtr def = vm->def;
|
||||||
|
unsigned long long period = vm->def->cputune.emulator_period;
|
||||||
|
long long quota = vm->def->cputune.emulator_quota;
|
||||||
int rc, i;
|
int rc, i;
|
||||||
|
|
||||||
if (driver->cgroup == NULL)
|
if (driver->cgroup == NULL)
|
||||||
|
@ -672,6 +674,13 @@ int qemuSetupCgroupForEmulator(struct qemud_driver *driver,
|
||||||
qemuSetupCgroupEmulatorPin(cgroup_emulator, def->cputune.emulatorpin) < 0)
|
qemuSetupCgroupEmulatorPin(cgroup_emulator, def->cputune.emulatorpin) < 0)
|
||||||
goto cleanup;
|
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_emulator);
|
||||||
virCgroupFree(&cgroup);
|
virCgroupFree(&cgroup);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue