Introduce XML to allowing adding iothreads to the domain. These can be
used by virtio-blk-pci devices in order to assign a specific thread to
handle the workload for the device. The iothreads are the official
implementation of the virtio-blk Data Plane that's been in tech preview
for QEMU.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
docs/formatdomain.html.in | 26 ++++++++++++++++++++++++++
docs/schemas/domaincommon.rng | 12 ++++++++++++
src/conf/domain_conf.c | 28 ++++++++++++++++++++++++++++
src/conf/domain_conf.h | 2 ++
4 files changed, 68 insertions(+)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 59127bb..0fe10f4 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -470,6 +470,32 @@
</dd>
</dl>
+ <h3><a name="elementsIOThreadsAllocation">IOThreads
Allocation</a></h3>
+ <p>
+ IOThreads are a QEMU feature that will allow supported disk
+ devices to be configured to use a dedicated event loop thread
+ to handle block I/O requests.
+ <span class="since">Since 1.2.8 (QEMU only)</span>
+ </p>
+
+<pre>
+<domain>
+ ...
+ <iothreads>4</iothreads>
+ ...
+</domain>
+</pre>
+
+ <dl>
+ <dt><code>iothreads</code></dt>
+ <dd>
+ The content of this optional element defines the number
+ of IOThreads to be assigned to the domain for use by
+ virtio-blk-pci target storage devices. There should be
+ only 1 or 2 IOThreads per host CPU and 1 IOThread per
+ supported device.
+ </dd>
+ </dl>
<h3><a name="elementsCPUTuning">CPU
Tuning</a></h3>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 9a89dd8..b4ac483 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -632,6 +632,12 @@
</optional>
<optional>
+ <element name="iothreads">
+ <ref name="countIOThreads"/>
+ </element>
+ </optional>
+
+ <optional>
<ref name="blkiotune"/>
</optional>
@@ -4747,6 +4753,12 @@
<param name="minInclusive">1</param>
</data>
</define>
+ <define name="countIOThreads">
+ <data type="unsignedInt">
+ <param name="pattern">[0-9]+</param>
+ <param name="minInclusive">0</param>
+ </data>
+ </define>
<define name="vcpuid">
<data type="unsignedShort">
<param name="pattern">[0-9]+</param>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 22a7f7e..671c41c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -11953,6 +11953,23 @@ virDomainDefParseXML(xmlDocPtr xml,
}
}
+ /* Optional - iothreads */
+ n = virXPathULong("string(./iothreads[1])", ctxt, &count);
+ if (n == -2) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("iothreads count must be an integer"));
+ goto error;
+ } else if (n < 0) {
+ def->iothreads = 0;
+ } else {
+ if ((unsigned int) count != count) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("invalid iothreads count '%lu'"), count);
+ goto error;
+ }
+ def->iothreads = count;
+ }
+
/* Extract cpu tunables. */
if ((n = virXPathULong("string(./cputune/shares[1])", ctxt,
&def->cputune.shares)) < -1) {
@@ -14461,6 +14478,14 @@ virDomainDefCheckABIStability(virDomainDefPtr src,
goto error;
}
+ if (src->iothreads != dst->iothreads) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Target domain iothreads count %u does not "
+ "match source %u"),
+ dst->iothreads, src->iothreads);
+ goto error;
+ }
+
if (STRNEQ(src->os.type, dst->os.type)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target domain OS type %s does not match source %s"),
@@ -17874,6 +17899,9 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virBufferAsprintf(buf, " current='%u'", def->vcpus);
virBufferAsprintf(buf, ">%u</vcpu>\n", def->maxvcpus);
+ if (def->iothreads > 0)
+ virBufferAsprintf(buf, "<iothreads>%u</iothreads>\n",
def->iothreads);
+
if (def->cputune.sharesSpecified ||
(def->cputune.nvcpupin && !virDomainIsAllVcpupinInherited(def)) ||
def->cputune.period || def->cputune.quota ||
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 36ccf10..705ce32 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1908,6 +1908,8 @@ struct _virDomainDef {
int placement_mode;
virBitmapPtr cpumask;
+ unsigned int iothreads;
+
struct {
unsigned long shares;
bool sharesSpecified;
--
1.9.3