All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Getting and setting SEDF scheduling parameters
@ 2006-01-05 19:26 John L Griffin
  2006-01-06 10:37 ` Keir Fraser
  2006-01-12  7:29 ` Stephan Diestelhorst
  0 siblings, 2 replies; 5+ messages in thread
From: John L Griffin @ 2006-01-05 19:26 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: Type: text/plain, Size: 1268 bytes --]

This patch addresses three problems in the function sedf_adjdom():

1) Setting certain values during the DOM0_ADJUSTDOM hypercall causes an 
immediate system lockup.  Specifically, the lockup occurs during a 
SCHED_INFO_PUT operation if the user-specified value for period is 
nonzero, extratime is 1, and weight is zero.  (If you'd like my test code 
to verify this, mail me off-list.)  The attached patch tests for the 
invalid combination of (extratime == 1) && (weight == 0), and returns 
-EINVAL if encountered.

2) During the SCHED_SEDF / SCHED_INFO_GET hypercall, an incorrect value is 
returned for weight when (extratime == 1).  The attached patch fixes this 
problem.

3) The code logic in this function is cryptic, and there is not much 
documentation on how the scheduling parameters should be used.  The 
attached patch adds comments to the sedf_adjdom() function, and 
reorders/rewrites the logic of the SCHED_INFO_PUT handling to make the 
code more self-documenting.

Note that this patch makes strong assumptions about how the scheduling 
parameters are used.  So, I recommend someone take a really close look at 
my comments to make sure I've preserved the Xen team's intentions for how 
the SEDF scheduler works. :-)

Signed-off-by: jlg@us.ibm.com


[-- Attachment #2: 2006-01-05-jlg-sedf-scheduling.patch --]
[-- Type: application/octet-stream, Size: 7477 bytes --]

--- orig.xen/common/sched_sedf.c	2006-01-05 11:38:42.000000000 -0500
+++ xen/common/sched_sedf.c	2006-01-05 13:53:14.000000000 -0500
@@ -1378,7 +1378,40 @@ static inline int sedf_adjust_weights(st
     return 0;
 }
 
-/* set or fetch domain scheduling parameters */
+/* sedf_adjdom: set or fetch domain scheduling parameters
+ *
+ * This function is called indirectly by the statement
+ *     SCHED_OP(adjdom, d, cmd);
+ * in $(XEN_ROOT)/xen/common/schedule.c, whenever SEDF scheduling is set
+ * for this domain.
+ *
+ * There are three modes of scheduling supported by the SEDF scheduler:
+ * best-effort, weight-driven, and time-driven.  The mode is selected by
+ * the values given to four of the five domain scheduling parameters
+ * (<period>, <slice>, <extratime>, and <weight>).  The <latency>
+ * parameter is used by the SEDF scheduler, but its value does not
+ * affect which mode is selected.
+ *
+ * Best-effort/scenario 1: If the EXTRA_AWARE bit in the <extratime>
+ * variable is set, then best-effort scheduling of this domain is
+ * selected.  This domain will receive a weighted share of any unused
+ * CPU time after all real-time domains [scenarios 2 and 3] consume
+ * their shares.  The value set for <weight> must be nonzero.  (Any values
+ * set for <period> or <slice> are ignored.)
+ *
+ * Weight-driven/scenario 2: If scenario 1 does not apply [the
+ * EXTRA_AWARE bit is not set], and if a value is set for <weight>, then
+ * weight-driven real-time scheduling of this domain is selected.  This
+ * domain will receive a weighted share of any unallocated CPU time
+ * after all time-driven real-time domains [scenario 3] are allocated
+ * their shares.  (Any values set for <period> or <slice> are ignored.)
+ *
+ * Time-driven/scenario 3: If scenarios 1 and 2 do not apply [the
+ * EXTRA_AWARE bit is not set, and no value is set for <weight>], and if
+ * a value is set for <period>, then time-driven real-time scheduling of
+ * this domain is selected.  This domain will receive <slice>
+ * nanoseconds of processing during every <period>-nanosecond slot.
+ */
 static int sedf_adjdom(struct domain *p, struct sched_adjdom_cmd *cmd) {
     struct vcpu *v;
 
@@ -1386,61 +1419,95 @@ static int sedf_adjdom(struct domain *p,
           "new slice %"PRIu64"\nlatency %"PRIu64" extra:%s\n",
           p->domain_id, cmd->u.sedf.period, cmd->u.sedf.slice,
           cmd->u.sedf.latency, (cmd->u.sedf.extratime)?"yes":"no");
-    if ( cmd->direction == SCHED_INFO_PUT )
-    {
-        /*check for sane parameters*/
-        if (!cmd->u.sedf.period && !cmd->u.sedf.weight)
-            return -EINVAL;
-        if (cmd->u.sedf.weight) {
-            if ((cmd->u.sedf.extratime & EXTRA_AWARE) &&
-                (! cmd->u.sedf.period)) {
-                /*weight driven domains with xtime ONLY!*/
-                for_each_vcpu(p, v) {
-                    EDOM_INFO(v)->extraweight = cmd->u.sedf.weight;
-                    EDOM_INFO(v)->weight = 0;
-                    EDOM_INFO(v)->slice = 0;
-                    EDOM_INFO(v)->period = WEIGHT_PERIOD;
-                }
-            } else {
-                /*weight driven domains with real-time execution*/
-                for_each_vcpu(p, v)
-                    EDOM_INFO(v)->weight = cmd->u.sedf.weight;
+
+    switch (cmd->direction) {
+
+    case SCHED_INFO_PUT:
+
+        if (cmd->u.sedf.extratime & EXTRA_AWARE) {
+            /* Scenario 1/4: Extratime scheduling is indicated.  This
+             * means that the domain should run in "best-effort" mode.
+             */
+
+            if (!(cmd->u.sedf.weight))
+                return -EINVAL;
+
+            for_each_vcpu(p, v) {
+                EDOM_INFO(v)->period      = WEIGHT_PERIOD;
+                EDOM_INFO(v)->slice       = 0;
+                EDOM_INFO(v)->latency     = cmd->u.sedf.latency;
+                EDOM_INFO(v)->weight      = 0;
+                EDOM_INFO(v)->extraweight = cmd->u.sedf.weight;
+
+                EDOM_INFO(v)->status |= EXTRA_AWARE;  /* Set bit */
+                extraq_check(v);
             }
         }
-        else {
-            /*time driven domains*/
+        else if (cmd->u.sedf.weight) {
+            /* Scenario 2/4: A scheduling weight is provided, indicating
+             * weight-driven real-time scheduling for this domain. */
+
             for_each_vcpu(p, v) {
-                /* sanity checking! */
-                if(cmd->u.sedf.slice > cmd->u.sedf.period )
-                    return -EINVAL;
-                EDOM_INFO(v)->weight = 0;
+                /* EDOM_INFO(v)->period set by sedf_adjust_weights() */
+                /* EDOM_INFO(v)->slice  set by sedf_adjust_weights() */
+                EDOM_INFO(v)->latency     = cmd->u.sedf.latency;
+                EDOM_INFO(v)->weight      = cmd->u.sedf.weight;
                 EDOM_INFO(v)->extraweight = 0;
-                EDOM_INFO(v)->period_orig = 
-                    EDOM_INFO(v)->period   = cmd->u.sedf.period;
-                EDOM_INFO(v)->slice_orig  = 
-                    EDOM_INFO(v)->slice    = cmd->u.sedf.slice;
+
+                EDOM_INFO(v)->status &= ~EXTRA_AWARE;  /* Unset bit */
+                extraq_check(v);
             }
         }
-        if (sedf_adjust_weights(cmd))
+        else if (cmd->u.sedf.period) {
+            /* Scenario 3/4: A scheduling period is provided, indicating
+             * time-driven real-time scheduling for this domain. */
+
+            if (cmd->u.sedf.slice > cmd->u.sedf.period)
+                return -EINVAL;
+
+            for_each_vcpu(p, v) {
+                EDOM_INFO(v)->period_orig= 
+                    EDOM_INFO(v)->period  = cmd->u.sedf.period;
+                EDOM_INFO(v)->slice_orig = 
+                    EDOM_INFO(v)->slice   = cmd->u.sedf.slice;
+                EDOM_INFO(v)->latency     = cmd->u.sedf.latency;
+                EDOM_INFO(v)->weight      = 0;
+                EDOM_INFO(v)->extraweight = 0;
+
+                EDOM_INFO(v)->status &= ~EXTRA_AWARE;  /* Unset bit */
+                extraq_check(v);
+            }
+        }
+        else {
+            /* Scenario 4/4: If none of the above scenarios apply, then
+             * the parameters provided are invalid. */
+
             return -EINVAL;
-   
-        for_each_vcpu(p, v) {
-            EDOM_INFO(v)->status  = 
-                (EDOM_INFO(v)->status &
-                 ~EXTRA_AWARE) | (cmd->u.sedf.extratime & EXTRA_AWARE);
-            EDOM_INFO(v)->latency = cmd->u.sedf.latency;
-            extraq_check(v);
         }
-    }
-    else if ( cmd->direction == SCHED_INFO_GET )
-    {
+
+        sedf_adjust_weights(cmd);
+
+        break;
+
+    case SCHED_INFO_GET:
+
         cmd->u.sedf.period    = EDOM_INFO(p->vcpu[0])->period;
         cmd->u.sedf.slice     = EDOM_INFO(p->vcpu[0])->slice;
-        cmd->u.sedf.extratime = EDOM_INFO(p->vcpu[0])->status
-            & EXTRA_AWARE;
         cmd->u.sedf.latency   = EDOM_INFO(p->vcpu[0])->latency;
-        cmd->u.sedf.weight    = EDOM_INFO(p->vcpu[0])->weight;
+        cmd->u.sedf.extratime = EDOM_INFO(p->vcpu[0])->status & EXTRA_AWARE;
+
+        if (EDOM_INFO(p->vcpu[0])->status & EXTRA_AWARE)
+            cmd->u.sedf.weight = EDOM_INFO(p->vcpu[0])->extraweight;
+        else
+            cmd->u.sedf.weight = EDOM_INFO(p->vcpu[0])->weight;
+
+        break;
+
+    default:
+
+        return -EINVAL;
     }
+
     PRINT(2,"sedf_adjdom_finished\n");
     return 0;
 }

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2006-01-12  7:45 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-01-05 19:26 [PATCH] Getting and setting SEDF scheduling parameters John L Griffin
2006-01-06 10:37 ` Keir Fraser
2006-01-09 20:42   ` John L Griffin
2006-01-12  7:45     ` Stephan Diestelhorst
2006-01-12  7:29 ` Stephan Diestelhorst

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.