Add a new disk "driver" attribute "iothread" to be parsed as the
thread
number for the disk to use. In order to more easily facilitate the usage
and configuration of the iothread, a "zero" for the attribute indicates
iothreads are not supported for the device and a positive value indicates
the specific thread to try and use.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
docs/formatdomain.html.in | 8 ++++++++
docs/schemas/domaincommon.rng | 8 ++++++++
src/conf/domain_conf.c | 27 ++++++++++++++++++++++++++-
src/conf/domain_conf.h | 2 ++
4 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index b584a08..132952d 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2160,6 +2160,14 @@
(ignore the discard request).
<span class='since'>Since 1.0.6 (QEMU and KVM
only)</span>
</li>
+ <li>
+ The optional <code>iothread</code> attribute will assign the
+ disk to an IOThread as defined by the range for the domain
+ <a
href="#elementsIOThreadsAllocation"><code>iothreads</code></a>
+ value. Each device must use a unique IOThread and threads will
+ be numbered from 1 to the domain iothreads value.
+ <span class='since'>Since 1.2.8 (QEMU only)</span>
+ </li>
</ul>
</dd>
<dt><code>boot</code></dt>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 5f1c226..cedceae 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1572,6 +1572,9 @@
<optional>
<ref name="discard"/>
</optional>
+ <optional>
+ <ref name="driverIOThread"/>
+ </optional>
<empty/>
</element>
</define>
@@ -1659,6 +1662,11 @@
</choice>
</attribute>
</define>
+ <define name="driverIOThread">
+ <attribute name='iothread'>
+ <ref name="unsignedInt"/>
+ </attribute>
+ </define>
<define name="controller">
<element name="controller">
<attribute name="index">
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 81a3fdf..14b8f4a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2109,6 +2109,7 @@ void virDomainDefFree(virDomainDefPtr def)
VIR_FREE(def->name);
virBitmapFree(def->cpumask);
+ virBitmapFree(def->iothreadmap);
VIR_FREE(def->emulator);
VIR_FREE(def->description);
VIR_FREE(def->title);
@@ -5403,6 +5404,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
char *ioeventfd = NULL;
char *event_idx = NULL;
char *copy_on_read = NULL;
+ char *driverIOThread = NULL;
char *devaddr = NULL;
virStorageEncryptionPtr encryption = NULL;
char *serial = NULL;
@@ -5551,6 +5553,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
event_idx = virXMLPropString(cur, "event_idx");
copy_on_read = virXMLPropString(cur, "copy_on_read");
discard = virXMLPropString(cur, "discard");
+ driverIOThread = virXMLPropString(cur, "iothread");
} else if (!def->mirror &&
xmlStrEqual(cur->name, BAD_CAST "mirror") &&
!(flags & VIR_DOMAIN_XML_INACTIVE)) {
@@ -6084,6 +6087,15 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
}
}
+ if (driverIOThread) {
+ if (virStrToLong_uip(driverIOThread, NULL, 10, &def->iothread) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Invalid iothread attribute in disk driver "
+ "element: %s"), driverIOThread);
+ goto error;
+ }
+ }
+
if (devaddr) {
if (virDomainParseLegacyDeviceAddress(devaddr,
&def->info.addr.pci) < 0) {
@@ -6184,6 +6196,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
VIR_FREE(event_idx);
VIR_FREE(copy_on_read);
VIR_FREE(discard);
+ VIR_FREE(driverIOThread);
VIR_FREE(devaddr);
VIR_FREE(serial);
virStorageEncryptionFree(encryption);
@@ -11966,6 +11979,16 @@ virDomainDefParseXML(xmlDocPtr xml,
}
VIR_FREE(tmp);
+ if (def->iothreads) {
+ /* Create a bitmap for inuse threads - noting that entries are
+ * numbered 1..def->iothreads since 0 (zero) iothreads means
+ * nothing and assigning a disk to an IOThread requires at least a
+ * thread# > 0 since a zero would indicate no IOThread for the disk
+ */
+ if (!(def->iothreadmap = virBitmapNew(def->iothreads+1)))
+ goto error;
+ }
+
/* Extract cpu tunables. */
if ((n = virXPathULong("string(./cputune/shares[1])", ctxt,
&def->cputune.shares)) < -1) {
@@ -15606,7 +15629,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
if (def->src->driverName || def->src->format > 0 || def->cachemode
||
def->error_policy || def->rerror_policy || def->iomode ||
def->ioeventfd || def->event_idx || def->copy_on_read ||
- def->discard) {
+ def->discard || def->iothread) {
virBufferAddLit(buf, "<driver");
if (def->src->driverName)
virBufferAsprintf(buf, " name='%s'",
def->src->driverName);
@@ -15629,6 +15652,8 @@ virDomainDiskDefFormat(virBufferPtr buf,
virBufferAsprintf(buf, " copy_on_read='%s'",
copy_on_read);
if (def->discard)
virBufferAsprintf(buf, " discard='%s'", discard);
+ if (def->iothread)
+ virBufferAsprintf(buf, " iothread='%u'",
def->iothread);
virBufferAddLit(buf, "/>\n");
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 23b117d..a543fc7 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -667,6 +667,7 @@ struct _virDomainDiskDef {
int rawio; /* no = 0, yes = 1 */
int sgio; /* enum virDomainDeviceSGIO */
int discard; /* enum virDomainDiskDiscard */
+ unsigned int iothread; /* unused = 0, > 0 specific thread # */
};
@@ -1916,6 +1917,7 @@ struct _virDomainDef {
virBitmapPtr cpumask;
unsigned int iothreads;
+ virBitmapPtr iothreadmap;
struct {
unsigned long shares;
--
1.9.3