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

[Xen-devel] [RFC PATCH v1 06/16] xen: Credit1: check for fully idle cores when tickling



Now that we have the information about which cores are fully idle, use
it for tickling pcpus.

This way, if there are cores that are fully idle, we tickle a pcpu from
one of them. This improve the SMT-awareness of the scheduler,
guaranteeing a better distribution of load, right from vcpu wakeup.

Signed-off-by: Dario Faggioli <dfaggioli@xxxxxxxx>
---
Cc: George Dunlap <george.dunlap@xxxxxxxxxxxxx>
---
 xen/common/sched_credit.c |   51 +++++++++++++++++++++++++++------------------
 1 file changed, 31 insertions(+), 20 deletions(-)

diff --git a/xen/common/sched_credit.c b/xen/common/sched_credit.c
index c7ee85d56a..af3b81d377 100644
--- a/xen/common/sched_credit.c
+++ b/xen/common/sched_credit.c
@@ -424,6 +424,15 @@ static inline void __runq_tickle(struct csched_vcpu *new)
                                      cpumask_scratch_cpu(cpu));
             cpumask_and(cpumask_scratch_cpu(cpu),
                         cpumask_scratch_cpu(cpu), &idle_mask);
+
+            /* Let's check fully idle cores first. */
+            if ( cpumask_intersects(cpumask_scratch_cpu(cpu), prv->smt_idle) )
+            {
+                cpumask_and(&mask, cpumask_scratch_cpu(cpu), prv->smt_idle);
+                break;
+            }
+
+            /* Now, let's check all idlers. */
             new_idlers_empty = cpumask_empty(cpumask_scratch_cpu(cpu));
 
             /*
@@ -441,11 +450,6 @@ static inline void __runq_tickle(struct csched_vcpu *new)
              * We have to do it indirectly, via _VPF_migrating (instead
              * of just tickling any idler suitable for cur) because cur
              * is running.
-             *
-             * If there are suitable idlers for new, no matter priorities,
-             * leave cur alone (as it is running and is, likely, cache-hot)
-             * and wake some of them (which is waking up and so is, likely,
-             * cache cold anyway).
              */
             if ( new_idlers_empty && new->pri > cur->pri )
             {
@@ -460,23 +464,19 @@ static inline void __runq_tickle(struct csched_vcpu *new)
                 /* Tickle cpu anyway, to let new preempt cur. */
                 SCHED_STAT_CRANK(tickled_busy_cpu);
                 __cpumask_set_cpu(cpu, &mask);
+                goto tickle;
             }
-            else if ( !new_idlers_empty )
+
+            /*
+             * If there are suitable idlers for new, no matter priorities,
+             * leave cur alone (as it is running and is, likely, cache-hot)
+             * and wake some of them (which is waking up and so is, likely,
+             * cache cold anyway).
+             */
+            if ( !new_idlers_empty )
             {
-                /* Which of the idlers suitable for new shall we wake up? */
                 SCHED_STAT_CRANK(tickled_idle_cpu);
-                if ( opt_tickle_one_idle )
-                {
-                    if ( cpumask_test_cpu(cpu, cpumask_scratch_cpu(cpu)) )
-                        this_cpu(last_tickle_cpu) = cpu;
-                    else
-                        this_cpu(last_tickle_cpu) =
-                            cpumask_cycle(this_cpu(last_tickle_cpu),
-                                          cpumask_scratch_cpu(cpu));
-                    __cpumask_set_cpu(this_cpu(last_tickle_cpu), &mask);
-                }
-                else
-                    cpumask_or(&mask, &mask, cpumask_scratch_cpu(cpu));
+                cpumask_or(&mask, &mask, cpumask_scratch_cpu(cpu));
             }
 
             /* Did we find anyone? */
@@ -485,9 +485,20 @@ static inline void __runq_tickle(struct csched_vcpu *new)
         }
     }
 
- tickle:
     if ( !cpumask_empty(&mask) )
     {
+        /* Which of the idlers suitable for new shall we wake up? */
+        if ( opt_tickle_one_idle )
+        {
+            if ( cpumask_test_cpu(cpu, &mask) )
+                this_cpu(last_tickle_cpu) = cpu;
+            else
+                this_cpu(last_tickle_cpu) =
+                    cpumask_cycle(this_cpu(last_tickle_cpu), &mask);
+            cpumask_copy(&mask, cpumask_of(this_cpu(last_tickle_cpu)));
+        }
+
+ tickle:
         if ( unlikely(tb_init_done) )
         {
             /* Avoid TRACE_*: saves checking !tb_init_done each step */


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

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