As the code for changing task scheduler is now able to choose deadline
scheduler, we can update domain configuration to parse the scheduler.
---
docs/formatdomain.html.in | 15 +++---
docs/schemas/domaincommon.rng | 16 +++++++
src/conf/domain_conf.c | 108 ++++++++++++++++++++++++++++++++++++++++--
3 files changed, 130 insertions(+), 9 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 4e40aa1..2f654f9 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -799,12 +799,12 @@
<dd>
The optional <code>vcpusched</code> elements specifies the scheduler
type (values <code>batch</code>, <code>idle</code>,
<code>fifo</code>,
- <code>rr</code>) for particular vCPU/IOThread threads (based on
- <code>vcpus</code> and <code>iothreads</code>, leaving
out
- <code>vcpus</code>/<code>iothreads</code> sets the
default). Valid
- <code>vcpus</code> values start at 0 through one less than the
- number of vCPU's defined for the domain. Valid
<code>iothreads</code>
- values are described in the <code>iothreadids</code>
+ <code>rr</code>, <code>deadline</code>) for particular
vCPU/IOThread
+ threads (based on <code>vcpus</code> and
<code>iothreads</code>,
+ leaving out <code>vcpus</code>/<code>iothreads</code>
sets the
+ default). Valid <code>vcpus</code> values start at 0 through one
less
+ than the number of vCPU's defined for the domain. Valid
+ <code>iothreads</code> values are described in the
<code>iothreadids</code>
<a
href="#elementsIOThreadsAllocation"><code>description</code></a>.
If no <code>iothreadids</code> are defined, then libvirt numbers
IOThreads from 1 to the number of <code>iothreads</code> available
@@ -812,6 +812,9 @@
<code>rr</code>), priority must be specified as
well (and is ignored for non-real-time ones). The value range
for the priority depends on the host kernel (usually 1-99).
+ For deadline real-time scheduler, additional parameters runtime,
+ deadline and period must be specified. The value of these parameters is
+ specified in nanoseconds, where minimum is 1024 (1 usec).
<span class="since">Since 1.2.13</span>
</dd>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 19d45fd..1461d34 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -851,6 +851,22 @@
<ref name="unsignedShort"/>
</attribute>
</group>
+ <group>
+ <attribute name="scheduler">
+ <choice>
+ <value>deadline</value>
+ </choice>
+ </attribute>
+ <attribute name="runtime">
+ <ref name="unsignedLong"/>
+ </attribute>
+ <attribute name="deadline">
+ <ref name="unsignedLong"/>
+ </attribute>
+ <attribute name="period">
+ <ref name="unsignedLong"/>
+ </attribute>
+ </group>
</choice>
</define>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 9ec23be..342745e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4518,11 +4518,13 @@ static int
virDomainVcpuDefPostParse(virDomainDefPtr def)
{
virDomainVcpuDefPtr vcpu;
+ virDomainThreadSchedParamPtr sched;
size_t maxvcpus = virDomainDefGetVcpusMax(def);
size_t i;
for (i = 0; i < maxvcpus; i++) {
vcpu = virDomainDefGetVcpu(def, i);
+ sched = &vcpu->sched;
/* impossible but some compilers don't like it */
if (!vcpu)
@@ -4549,6 +4551,35 @@ virDomainVcpuDefPostParse(virDomainDefPtr def)
case VIR_TRISTATE_BOOL_LAST:
break;
}
+
+ switch (sched->policy) {
+ case VIR_PROC_POLICY_NONE:
+ case VIR_PROC_POLICY_BATCH:
+ case VIR_PROC_POLICY_IDLE:
+ case VIR_PROC_POLICY_FIFO:
+ case VIR_PROC_POLICY_RR:
+ break;
+ case VIR_PROC_POLICY_DEADLINE:
+ if (sched->runtime < 1024 || sched->deadline < 1024 ||
sched->period < 1024) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Scheduler runtime, deadline and period must be
"
+ "higher or equal to 1024 (1 us) (runtime(%llu), "
+ "deadline(%llu), period(%llu))"),
+ sched->runtime, sched->deadline, sched->period);
+ return -1;
+ }
+
+ if (!(sched->runtime <= sched->deadline &&
sched->deadline <= sched->period)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Scheduler configuration does not satisfy "
+ "(runtime(%llu) <= deadline(%llu) <=
period(%llu))"),
+ sched->runtime, sched->deadline, sched->period);
+ return -1;
+ }
+ break;
+ case VIR_PROC_POLICY_LAST:
+ break;
+ }
}
return 0;
@@ -15717,7 +15748,10 @@ static virBitmapPtr
virDomainSchedulerParse(xmlNodePtr node,
const char *name,
virProcessSchedPolicy *policy,
- int *priority)
+ int *priority,
+ unsigned long long *runtime,
+ unsigned long long *deadline,
+ unsigned long long *period)
{
virBitmapPtr ret = NULL;
char *tmp = NULL;
@@ -15773,6 +15807,42 @@ virDomainSchedulerParse(xmlNodePtr node,
VIR_FREE(tmp);
}
+ if (pol == VIR_PROC_POLICY_DEADLINE) {
+ if (!(tmp = virXMLPropString(node, "runtime"))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("Missing scheduler runtime"));
+ goto error;
+ }
+ if (virStrToLong_ull(tmp, NULL, 10, runtime) < 0) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("Invalid value for element runtime"));
+ goto error;
+ }
+
+ if (!(tmp = virXMLPropString(node, "deadline"))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("Missing scheduler deadline"));
+ goto error;
+ }
+ if (virStrToLong_ull(tmp, NULL, 10, deadline) < 0) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("Invalid value for element deadline"));
+ goto error;
+ }
+
+ if (!(tmp = virXMLPropString(node, "period"))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("Missing scheduler period"));
+ goto error;
+ }
+ if (virStrToLong_ull(tmp, NULL, 10, period) < 0) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("Invalid value for element period"));
+ goto error;
+ }
+ VIR_FREE(tmp);
+ }
+
return ret;
error:
@@ -15793,9 +15863,13 @@ virDomainThreadSchedParseHelper(xmlNodePtr node,
virDomainThreadSchedParamPtr sched;
virProcessSchedPolicy policy;
int priority;
+ unsigned long long runtime;
+ unsigned long long deadline;
+ unsigned long long period;
int ret = -1;
- if (!(map = virDomainSchedulerParse(node, name, &policy, &priority)))
+ if (!(map = virDomainSchedulerParse(node, name, &policy, &priority,
+ &runtime, &deadline, &period)))
goto cleanup;
while ((next = virBitmapNextSetBit(map, next)) > -1) {
@@ -15811,6 +15885,9 @@ virDomainThreadSchedParseHelper(xmlNodePtr node,
sched->policy = policy;
sched->priority = priority;
+ sched->runtime = runtime;
+ sched->deadline = deadline;
+ sched->period = period;
}
ret = 0;
@@ -23072,6 +23149,15 @@ virDomainSchedPriorityComparator(virDomainThreadSchedParamPtr
baseSched,
return (baseSched->priority == sched->priority);
}
+static bool
+virDomainSchedDeadlineComparator(virDomainThreadSchedParamPtr baseSched,
+ virDomainThreadSchedParamPtr sched)
+{
+ return (baseSched->runtime == sched->priority &&
+ baseSched->deadline == sched->deadline &&
+ baseSched->period == sched->period);
+}
+
static virDomainThreadSchedParamPtr
virDomainSchedSubsetCharacteristic(virDomainDefPtr def,
virBitmapPtr schedMap,
@@ -23164,13 +23250,13 @@ virDomainFormatSchedDef(virDomainDefPtr def,
while (!virBitmapIsAllClear(schedMap)) {
virBitmapPtr currentMap = NULL;
bool hasPriority = false;
+ bool isDeadline = false;
baseSched = NULL;
switch ((virProcessSchedPolicy) i) {
case VIR_PROC_POLICY_NONE:
case VIR_PROC_POLICY_BATCH:
case VIR_PROC_POLICY_IDLE:
- case VIR_PROC_POLICY_DEADLINE:
case VIR_PROC_POLICY_LAST:
currentMap = schedMap;
break;
@@ -23189,6 +23275,19 @@ virDomainFormatSchedDef(virDomainDefPtr def,
currentMap = subsetMap;
break;
+ case VIR_PROC_POLICY_DEADLINE:
+ isDeadline = true;
+
+ baseSched = virDomainSchedSubsetCharacteristic(def,
+ schedMap,
+ subsetMap,
+ func,
+
virDomainSchedDeadlineComparator);
+ if (baseSched == NULL)
+ goto cleanup;
+
+ currentMap = subsetMap;
+ break;
}
/* now we have the complete group */
@@ -23203,6 +23302,9 @@ virDomainFormatSchedDef(virDomainDefPtr def,
if (hasPriority && baseSched != NULL)
virBufferAsprintf(buf, " priority='%d'",
baseSched->priority);
+ if (isDeadline && baseSched != NULL)
+ virBufferAsprintf(buf, " runtime='%llu'
deadline='%llu' period='%llu'",
+ baseSched->runtime, baseSched->deadline,
baseSched->period);
virBufferAddLit(buf, "/>\n");
--
2.8.1