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

[Xen-devel] [PATCH v4 5/5] sched: credit2: add soft affinity awareness to function runq_tickle



by adding two two-step affinity loops.

The first looks for an idle, non-tickled cpu in the given vcpu's soft
affinity, and then in it's hard affinity.

If no cpu was found, the second two-step loop first looks for the non-idle,
non-tickled cpu with the lowest credit in the vcpu's soft affinity. If the
vcpu on the found cpu has less credit than the given vcpu, then that cpu is
chosen. Finally, if no cpu was picked yet, the second step looks for the
non-idle, non-tickled cpu with the lowest credit in the vcpu's hard affinity.

Signed-off-by: Justin T. Weaver <jtweaver@xxxxxxxxxx>
---
Changes in v4:
 * removed "indent only" patch and integrated its changes into this patch
 * renamed all uses of csched2_cpumask to scratch_mask
 * moved comment outside of for_each_sched_balance_step loop and updated the
   comment for soft affinity in the "idle, not tickled" section
 * updated the functionality of the "not idle, not tickled" section; it now
   breaks out of the for_each_sched_balance_step loop if the vcpu on the cpu
   found during the soft affinity step has less credit than vcpu new
 * updated the comment above the "not idle, not tickled" section explaining
   the new functionality
Changes in v3:
 * replaced use of the on-stack cpumask_t with the per-vcpu scratch_mask
 * added two balance loops, one for finding idle, but not tickled, and other
   for finding non-idle with lowest credit
Changes in v2:
 * Not submitted in version 2; focus was on the hard affinity patch
---
 xen/common/sched_credit2.c |  112 ++++++++++++++++++++++++++++----------------
 1 file changed, 71 insertions(+), 41 deletions(-)

diff --git a/xen/common/sched_credit2.c b/xen/common/sched_credit2.c
index 66f0a20..cd44ac3 100644
--- a/xen/common/sched_credit2.c
+++ b/xen/common/sched_credit2.c
@@ -534,8 +534,8 @@ runq_tickle(const struct scheduler *ops, unsigned int cpu, 
struct csched2_vcpu *
     int i, ipid=-1;
     s_time_t lowest=(1<<30);
     struct csched2_runqueue_data *rqd = RQD(ops, cpu);
-    cpumask_t mask;
     struct csched2_vcpu * cur;
+    int balance_step;
 
     d2printk("rqt %pv curr %pv\n", new->vcpu, current);
 
@@ -552,57 +552,87 @@ runq_tickle(const struct scheduler *ops, unsigned int 
cpu, struct csched2_vcpu *
         goto tickle;
     }
     
-    /* Get a mask of idle, but not tickled, that new is allowed to run on. */
-    cpumask_andnot(&mask, &rqd->idle, &rqd->tickled);
-    cpumask_and(&mask, &mask, new->vcpu->cpu_hard_affinity);
-    
-    /* If it's not empty, choose one */
-    i = cpumask_cycle(cpu, &mask);
-    if ( i < nr_cpu_ids )
+    /*
+     * Look for an idle, untickled cpu in the vcpu's soft affinity, then in
+     * its hard affinity.
+     */
+    for_each_sched_balance_step ( balance_step )
     {
-        ipid = i;
-        goto tickle;
-    }
+        if ( balance_step == SCHED_BALANCE_SOFT_AFFINITY
+            && !__vcpu_has_soft_affinity(new->vcpu,
+                new->vcpu->cpu_hard_affinity) )
+            continue;
+
+        sched_balance_cpumask(new->vcpu, balance_step, scratch_mask);
+        cpumask_and(scratch_mask, scratch_mask, &rqd->idle);
+        cpumask_andnot(scratch_mask, scratch_mask, &rqd->tickled);
 
-    /* Otherwise, look for the non-idle cpu with the lowest credit,
-     * skipping cpus which have been tickled but not scheduled yet,
-     * that new is allowed to run on. */
-    cpumask_andnot(&mask, &rqd->active, &rqd->idle);
-    cpumask_andnot(&mask, &mask, &rqd->tickled);
-    cpumask_and(&mask, &mask, new->vcpu->cpu_hard_affinity);
+        /* If it's not empty, choose one */
+        i = cpumask_cycle(cpu, scratch_mask);
+        if ( i < nr_cpu_ids )
+        {
+            ipid = i;
+            goto tickle;
+        }
+    }
 
-    for_each_cpu(i, &mask)
+    /*
+     * Otherwise, look for the non-idle cpu whose vcpu has the lowest credit,
+     * skipping cpus which have been tickled but not scheduled yet.
+     * First look in new's soft affinity, and choose the cpu if its currently
+     * running vcpu's credit is lower than new's credit.
+     * If a cpu was not found using new's soft affinity, choose the cpu in
+     * new's hard affinity with the lowest credit.
+     */
+    for_each_sched_balance_step ( balance_step )
     {
-        struct csched2_vcpu * cur;
+        if ( balance_step == SCHED_BALANCE_HARD_AFFINITY
+            && lowest < new->credit )
+            goto tickle;
 
-        /* Already looked at this one above */
-        if ( i == cpu )
+        if ( balance_step == SCHED_BALANCE_SOFT_AFFINITY
+            && !__vcpu_has_soft_affinity(new->vcpu,
+                                         new->vcpu->cpu_hard_affinity) )
             continue;
 
-        cur = CSCHED2_VCPU(curr_on_cpu(i));
+        sched_balance_cpumask(new->vcpu, balance_step, scratch_mask);
+        cpumask_and(scratch_mask, scratch_mask, &rqd->active);
+        cpumask_andnot(scratch_mask, scratch_mask, &rqd->idle);
+        cpumask_andnot(scratch_mask, scratch_mask, &rqd->tickled);
+
+        for_each_cpu(i, scratch_mask)
+        {
+            struct csched2_vcpu * cur;
 
-        BUG_ON(is_idle_vcpu(cur->vcpu));
+            /* Already looked at this one above */
+            if ( i == cpu )
+                continue;
 
-        /* Update credits for current to see if we want to preempt */
-        burn_credits(rqd, cur, now);
+            cur = CSCHED2_VCPU(curr_on_cpu(i));
 
-        if ( cur->credit < lowest )
-        {
-            ipid = i;
-            lowest = cur->credit;
-        }
+            BUG_ON(is_idle_vcpu(cur->vcpu));
 
-        /* TRACE */ {
-            struct {
-                unsigned dom:16,vcpu:16;
-                unsigned credit;
-            } d;
-            d.dom = cur->vcpu->domain->domain_id;
-            d.vcpu = cur->vcpu->vcpu_id;
-            d.credit = cur->credit;
-            trace_var(TRC_CSCHED2_TICKLE_CHECK, 1,
-                      sizeof(d),
-                      (unsigned char *)&d);
+            /* Update credits for current to see if we want to preempt */
+            burn_credits(rqd, cur, now);
+
+            if ( cur->credit < lowest )
+            {
+                ipid = i;
+                lowest = cur->credit;
+            }
+
+            /* TRACE */ {
+                struct {
+                    unsigned dom:16,vcpu:16;
+                    unsigned credit;
+                } d;
+                d.dom = cur->vcpu->domain->domain_id;
+                d.vcpu = cur->vcpu->vcpu_id;
+                d.credit = cur->credit;
+                trace_var(TRC_CSCHED2_TICKLE_CHECK, 1,
+                          sizeof(d),
+                          (unsigned char *)&d);
+            }
         }
     }
 
-- 
1.7.10.4


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


 


Rackspace

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