mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
[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>
This commit is contained in:
1 parent
c3c52fdfa0
commit
fe9a681dcf
1 file changed
+24
-22
+24
-22
@@ -987,36 +987,38 @@ 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);
|
||||
return snext;
|
||||
|
||||