diff options
author | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2006-09-14 16:01:46 +0100 |
---|---|---|
committer | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2006-09-14 16:01:46 +0100 |
commit | fe9a681dcffc1b9284c3a4ee5172ca83f2bd9949 (patch) | |
tree | fe1c529980536a253074c96be160c88f4763ac15 | |
parent | c3c52fdfa0bf277dee71f7902a052c4430cc74ce (diff) | |
download | xen-fe9a681dcffc1b9284c3a4ee5172ca83f2bd9949.tar.gz xen-fe9a681dcffc1b9284c3a4ee5172ca83f2bd9949.tar.bz2 xen-fe9a681dcffc1b9284c3a4ee5172ca83f2bd9949.zip |
[XEN] Do not steal work from idle CPUs. This can happen
if a idle CPU is in the process of waking up.
This fix suggested by Anthony Xu <anthony.xu@intel.com> as
it can have a significant boost to HVM performance.
Signed-off-by: Keir Fraser <keir@xensource.com>
-rw-r--r-- | xen/common/sched_credit.c | 46 |
1 files changed, 24 insertions, 22 deletions
diff --git a/xen/common/sched_credit.c b/xen/common/sched_credit.c index d183f2dafa..3465542083 100644 --- a/xen/common/sched_credit.c +++ b/xen/common/sched_credit.c @@ -987,35 +987,37 @@ csched_load_balance(int cpu, struct csched_vcpu *snext) * cause a deadlock if the peer CPU is also load balancing and trying * to lock this CPU. */ - if ( spin_trylock(&per_cpu(schedule_data, peer_cpu).schedule_lock) ) + if ( !spin_trylock(&per_cpu(schedule_data, peer_cpu).schedule_lock) ) { + CSCHED_STAT_CRANK(steal_trylock_failed); + continue; + } - spc = CSCHED_PCPU(peer_cpu); - if ( unlikely(spc == NULL) ) - { - CSCHED_STAT_CRANK(steal_peer_down); - speer = NULL; - } - else - { - speer = csched_runq_steal(spc, cpu, snext->pri); - } - - spin_unlock(&per_cpu(schedule_data, peer_cpu).schedule_lock); - - /* Got one! */ - if ( speer ) - { - CSCHED_STAT_CRANK(vcpu_migrate); - return speer; - } + spc = CSCHED_PCPU(peer_cpu); + if ( unlikely(spc == NULL) ) + { + CSCHED_STAT_CRANK(steal_peer_down); + speer = NULL; + } + else if ( is_idle_vcpu(per_cpu(schedule_data, peer_cpu).curr) ) + { + speer = NULL; } else { - CSCHED_STAT_CRANK(steal_trylock_failed); + /* Try to steal work from an online non-idle CPU. */ + speer = csched_runq_steal(spc, cpu, snext->pri); } - } + spin_unlock(&per_cpu(schedule_data, peer_cpu).schedule_lock); + + /* Got one? */ + if ( speer ) + { + CSCHED_STAT_CRANK(vcpu_migrate); + return speer; + } + } /* Failed to find more important work */ __runq_remove(snext); |