credit2: Don't migrate cpus unnecessarily
authorKeir Fraser <keir@xen.org>
Fri, 10 Dec 2010 10:51:04 +0000 (10:51 +0000)
committerKeir Fraser <keir@xen.org>
Fri, 10 Dec 2010 10:51:04 +0000 (10:51 +0000)
Modern processors have one or two L3's per socket, and generally only
one core per L2.  Credit2's design relies on having credit shared
across several.  So as a first step to sharing a queue across L3 while
avoiding excessive cross-L2 migration

Step one: If the vcpu's current cpu is acceptable, just run it there.

Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
xen/common/sched_credit2.c

index 97b9e400fa8f3a0af14ed48a10481eacce0d053b..e81d8c855a8c8eea14a9bda9b92c5ac79bb11269 100644 (file)
@@ -334,6 +334,7 @@ runq_tickle(const struct scheduler *ops, unsigned int cpu, struct csched_vcpu *n
     s_time_t lowest=(1<<30);
     struct csched_runqueue_data *rqd = RQD(ops, cpu);
     cpumask_t *online, mask;
+    struct csched_vcpu * cur;
 
     d2printk("rqt d%dv%d cd%dv%d\n",
              new->vcpu->domain->domain_id,
@@ -341,8 +342,18 @@ runq_tickle(const struct scheduler *ops, unsigned int cpu, struct csched_vcpu *n
              current->domain->domain_id,
              current->vcpu_id);
 
-    online = CSCHED_CPUONLINE(per_cpu(cpupool, cpu));
+    BUG_ON(new->vcpu->processor != cpu);
+
+    /* Look at the cpu it's running on first */
+    cur = CSCHED_VCPU(per_cpu(schedule_data, cpu).curr);
+    burn_credits(rqd, cur, now);
 
+    if ( cur->credit < new->credit )
+    {
+        ipid = cpu;
+        goto tickle;
+    }
+    
     /* Get a mask of idle, but not tickled */
     cpus_andnot(mask, rqd->idle, rqd->tickled);
     
@@ -355,6 +366,8 @@ runq_tickle(const struct scheduler *ops, unsigned int cpu, struct csched_vcpu *n
 
     /* Otherwise, look for the non-idle cpu with the lowest credit,
      * skipping cpus which have been tickled but not scheduled yet */
+    online = CSCHED_CPUONLINE(per_cpu(cpupool, cpu));
+
     cpus_andnot(mask, *online, rqd->idle);
     cpus_andnot(mask, mask, rqd->tickled);
 
@@ -362,6 +375,10 @@ runq_tickle(const struct scheduler *ops, unsigned int cpu, struct csched_vcpu *n
     {
         struct csched_vcpu * cur;
 
+        /* Already looked at this one above */
+        if ( i == cpu )
+            continue;
+
         cur = CSCHED_VCPU(per_cpu(schedule_data, i).curr);
 
         BUG_ON(is_idle_vcpu(cur->vcpu));