[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 07/24] xen: sched: don't rate limit context switches in case of yields



In both Credit1 and Credit2, if a vcpu yields, let it...
well... yield!

In fact, context switch rate limiting has been primarily
introduced to avoid too heavy context switch rate due to
interrupts, and, in general, asynchronous events.

In a vcpu "voluntarily" yields, we really should let it
give up the cpu for a while. For instance, the reason may
be that it's about to start spinning, and there's few
point in forcing a vcpu to spin for (potentially) the
entire rate-limiting period.

Signed-off-by: Dario Faggioli <dario.faggioli@xxxxxxxxxx>
---
Cc: George Dunlap <george.dunlap@xxxxxxxxxxxxx>
Cc: Anshul Makkar <anshul.makkar@xxxxxxxxxx>
---
 xen/common/sched_credit.c  |   20 +++++++++++--------
 xen/common/sched_credit2.c |   47 +++++++++++++++++++++++---------------------
 2 files changed, 37 insertions(+), 30 deletions(-)

diff --git a/xen/common/sched_credit.c b/xen/common/sched_credit.c
index 3f439a0..ca04732 100644
--- a/xen/common/sched_credit.c
+++ b/xen/common/sched_credit.c
@@ -1771,9 +1771,18 @@ csched_schedule(
      *   cpu and steal it.
      */
 
-    /* If we have schedule rate limiting enabled, check to see
-     * how long we've run for. */
-    if ( !tasklet_work_scheduled
+    /*
+     * If we have schedule rate limiting enabled, check to see
+     * how long we've run for.
+     *
+     * If scurr is yielding, however, we don't let rate limiting kick in.
+     * In fact, it may be the case that scurr is about to spin, and there's
+     * no point forcing it to do so until rate limiting expires.
+     *
+     * While there, take the chance for clearing the yield flag at once.
+     */
+    if ( !test_and_clear_bit(CSCHED_FLAG_VCPU_YIELD, &scurr->flags)
+         && !tasklet_work_scheduled
          && prv->ratelimit_us
          && vcpu_runnable(current)
          && !is_idle_vcpu(current)
@@ -1808,11 +1817,6 @@ csched_schedule(
     }
 
     /*
-     * Clear YIELD flag before scheduling out
-     */
-    clear_bit(CSCHED_FLAG_VCPU_YIELD, &scurr->flags);
-
-    /*
      * SMP Load balance:
      *
      * If the next highest priority local runnable VCPU has already eaten
diff --git a/xen/common/sched_credit2.c b/xen/common/sched_credit2.c
index 569174b..c8e0ee7 100644
--- a/xen/common/sched_credit2.c
+++ b/xen/common/sched_credit2.c
@@ -2267,36 +2267,40 @@ runq_candidate(struct csched2_runqueue_data *rqd,
     struct list_head *iter;
     struct csched2_vcpu *snext = NULL;
     struct csched2_private *prv = CSCHED2_PRIV(per_cpu(scheduler, cpu));
-    int yield_bias = 0;
-
-    /* Default to current if runnable, idle otherwise */
-    if ( vcpu_runnable(scurr->vcpu) )
-    {
-        /*
-         * The way we actually take yields into account is like this:
-         * if scurr is yielding, when comparing its credits with other
-         * vcpus in the runqueue, act like those other vcpus had yield_bias
-         * more credits.
-         */
-        if ( unlikely(scurr->flags & CSFLAG_vcpu_yield) )
-            yield_bias = CSCHED2_YIELD_BIAS;
-
-        snext = scurr;
-    }
-    else
-        snext = CSCHED2_VCPU(idle_vcpu[cpu]);
+    /*
+     * The way we actually take yields into account is like this:
+     * if scurr is yielding, when comparing its credits with other vcpus in
+     * the runqueue, act like those other vcpus had yield_bias more credits.
+     */
+    int yield_bias = __test_and_clear_bit(__CSFLAG_vcpu_yield, &scurr->flags) ?
+                     CSCHED2_YIELD_BIAS : 0;
 
     /*
      * Return the current vcpu if it has executed for less than ratelimit.
      * Adjuststment for the selected vcpu's credit and decision
      * for how long it will run will be taken in csched2_runtime.
+     *
+     * Note that, if scurr is yielding, we don't let rate limiting kick in.
+     * In fact, it may be the case that scurr is about to spin, and there's
+     * no point forcing it to do so until rate limiting expires.
+     *
+     * To check whether we are yielding, it's enough to look at yield_bias
+     * (as CSCHED2_YIELD_BIAS can't be zero). Also, note that the yield flag
+     * has been cleared already above.
      */
-    if ( prv->ratelimit_us && !is_idle_vcpu(scurr->vcpu) &&
+    if ( !yield_bias &&
+         prv->ratelimit_us && !is_idle_vcpu(scurr->vcpu) &&
          vcpu_runnable(scurr->vcpu) &&
          (now - scurr->vcpu->runstate.state_entry_time) <
           MICROSECS(prv->ratelimit_us) )
         return scurr;
 
+    /* Default to current if runnable, idle otherwise */
+    if ( vcpu_runnable(scurr->vcpu) )
+        snext = scurr;
+    else
+        snext = CSCHED2_VCPU(idle_vcpu[cpu]);
+
     list_for_each( iter, &rqd->runq )
     {
         struct csched2_vcpu * svc = list_entry(iter, struct csched2_vcpu, 
runq_elem);
@@ -2423,7 +2427,8 @@ csched2_schedule(
      */
     if ( tasklet_work_scheduled )
     {
-        trace_var(TRC_CSCHED2_SCHED_TASKLET, 1, 0,  NULL);
+        __clear_bit(__CSFLAG_vcpu_yield, &scurr->flags);
+        trace_var(TRC_CSCHED2_SCHED_TASKLET, 1, 0, NULL);
         snext = CSCHED2_VCPU(idle_vcpu[cpu]);
     }
     else
@@ -2436,8 +2441,6 @@ csched2_schedule(
          && vcpu_runnable(current) )
         __set_bit(__CSFLAG_delayed_runq_add, &scurr->flags);
 
-    __clear_bit(__CSFLAG_vcpu_yield, &scurr->flags);
-
     ret.migrated = 0;
 
     /* Accounting for non-idle tasks */


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.