aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/schedule.c
diff options
context:
space:
mode:
authorJuergen Gross <juergen.gross@ts.fujitsu.com>2011-03-15 10:14:27 +0000
committerJuergen Gross <juergen.gross@ts.fujitsu.com>2011-03-15 10:14:27 +0000
commite1255ac77ed688d843b207ebdf2d0e6ca3fc6583 (patch)
treecb989606ee8405334cf8f22a50a18c6e9e7c2ec8 /xen/common/schedule.c
parent436308d761e9f1a580f35cc69abb4d594b6fe4fb (diff)
downloadxen-e1255ac77ed688d843b207ebdf2d0e6ca3fc6583.tar.gz
xen-e1255ac77ed688d843b207ebdf2d0e6ca3fc6583.tar.bz2
xen-e1255ac77ed688d843b207ebdf2d0e6ca3fc6583.zip
Avoid endless loop for vcpu migration.
Only call SCHED_OP(pick_cpu) if a previously picked cpu is not suitable on the current iteration of the retry loop. Signed-off-by: Juergen Gross <juergen.gross@ts.fujitsu.com> Signed-off-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/common/schedule.c')
-rw-r--r--xen/common/schedule.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/xen/common/schedule.c b/xen/common/schedule.c
index e89da7a34b..129abe44e4 100644
--- a/xen/common/schedule.c
+++ b/xen/common/schedule.c
@@ -395,6 +395,7 @@ static void vcpu_migrate(struct vcpu *v)
unsigned long flags;
unsigned int old_cpu, new_cpu;
spinlock_t *old_lock, *new_lock;
+ bool_t pick_called = 0;
old_cpu = new_cpu = v->processor;
for ( ; ; )
@@ -426,14 +427,33 @@ static void vcpu_migrate(struct vcpu *v)
spin_lock(old_lock);
}
- /* Select new CPU. */
old_cpu = v->processor;
if ( old_lock == per_cpu(schedule_data, old_cpu).schedule_lock )
{
+ /*
+ * If we selected a CPU on the previosu iteration, check if it
+ * remains suitable for running this vCPU.
+ */
+ if ( pick_called &&
+ (new_lock == per_cpu(schedule_data, new_cpu).schedule_lock) &&
+ cpu_isset(new_cpu, v->cpu_affinity) &&
+ cpu_isset(new_cpu, v->domain->cpupool->cpu_valid) )
+ break;
+
+ /* Select a new CPU. */
new_cpu = SCHED_OP(VCPU2OP(v), pick_cpu, v);
if ( (new_lock == per_cpu(schedule_data, new_cpu).schedule_lock) &&
cpu_isset(new_cpu, v->domain->cpupool->cpu_valid) )
break;
+ pick_called = 1;
+ }
+ else
+ {
+ /*
+ * We do not hold the scheduler lock appropriate for this vCPU.
+ * Thus we cannot select a new CPU on this iteration. Try again.
+ */
+ pick_called = 0;
}
if ( old_lock != new_lock )