[libvirt] [PATCH v2 5/5] conf: add deadline scheduler

Martin Polednik mpolednik at redhat.com
Mon Nov 21 12:56:08 UTC 2016


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




More information about the libvir-list mailing list