# HG changeset patch # User Juergen Gross # Date 1300113178 -3600 # Node ID 9d164ce877a75cab847b8a6e0114230807d5acd6 # Parent 84bacd800bf88e37434d49547ad8224be46e2a52 Avoid endless loop for vcpu migration On multi-thread multi-core systems an endless loop can occur in vcpu_migrate() with credit scheduler. Avoid this loop by changing the interface of pick_cpu to indicate a repeated call in this case. Signed-off-by: juergen.gross@xxxxxxxxxxxxxx diff -r 84bacd800bf8 -r 9d164ce877a7 xen/common/sched_arinc653.c --- a/xen/common/sched_arinc653.c Sat Mar 12 13:20:51 2011 +0000 +++ b/xen/common/sched_arinc653.c Mon Mar 14 15:32:58 2011 +0100 @@ -612,7 +612,7 @@ a653sched_do_schedule( * @return Number of selected physical CPU */ static int -a653sched_pick_cpu(const struct scheduler *ops, struct vcpu *vc) +a653sched_pick_cpu(const struct scheduler *ops, struct vcpu *vc, int proposal) { /* this implementation only supports one physical CPU */ return 0; diff -r 84bacd800bf8 -r 9d164ce877a7 xen/common/sched_credit.c --- a/xen/common/sched_credit.c Sat Mar 12 13:20:51 2011 +0000 +++ b/xen/common/sched_credit.c Mon Mar 14 15:32:58 2011 +0100 @@ -459,7 +459,7 @@ __csched_vcpu_is_migrateable(struct vcpu } static int -_csched_cpu_pick(const struct scheduler *ops, struct vcpu *vc, bool_t commit) +csched_cpu_pick(const struct scheduler *ops, struct vcpu *vc, int proposal) { cpumask_t cpus; cpumask_t idlers; @@ -531,7 +531,7 @@ _csched_cpu_pick(const struct scheduler && (weight_cpu * migrate_factor < weight_nxt) ) ) { cpu = cycle_cpu(CSCHED_PCPU(nxt)->idle_bias, nxt_idlers); - if ( commit ) + if ( proposal == -1 ) CSCHED_PCPU(nxt)->idle_bias = cpu; cpus_andnot(cpus, cpus, per_cpu(cpu_sibling_map, cpu)); } @@ -542,12 +542,6 @@ _csched_cpu_pick(const struct scheduler } return cpu; -} - -static int -csched_cpu_pick(const struct scheduler *ops, struct vcpu *vc) -{ - return _csched_cpu_pick(ops, vc, 1); } static inline void @@ -632,7 +626,7 @@ csched_vcpu_acct(struct csched_private * { __csched_vcpu_acct_start(prv, svc); } - else if ( _csched_cpu_pick(ops, current, 0) != cpu ) + else if ( csched_cpu_pick(ops, current, cpu) != cpu ) { CSCHED_VCPU_STAT_CRANK(svc, migrate_r); CSCHED_STAT_CRANK(migrate_running); diff -r 84bacd800bf8 -r 9d164ce877a7 xen/common/sched_credit2.c --- a/xen/common/sched_credit2.c Sat Mar 12 13:20:51 2011 +0000 +++ b/xen/common/sched_credit2.c Mon Mar 14 15:32:58 2011 +0100 @@ -1350,7 +1350,7 @@ out: } static int -csched_cpu_pick(const struct scheduler *ops, struct vcpu *vc) +csched_cpu_pick(const struct scheduler *ops, struct vcpu *vc, int proposal) { struct csched_vcpu * const svc = CSCHED_VCPU(vc); int new_cpu; diff -r 84bacd800bf8 -r 9d164ce877a7 xen/common/sched_sedf.c --- a/xen/common/sched_sedf.c Sat Mar 12 13:20:51 2011 +0000 +++ b/xen/common/sched_sedf.c Mon Mar 14 15:32:58 2011 +0100 @@ -442,7 +442,7 @@ static void sedf_destroy_domain(const st sedf_free_domdata(ops, d->sched_priv); } -static int sedf_pick_cpu(const struct scheduler *ops, struct vcpu *v) +static int sedf_pick_cpu(const struct scheduler *ops, struct vcpu *v, int proposal) { cpumask_t online_affinity; cpumask_t *online; diff -r 84bacd800bf8 -r 9d164ce877a7 xen/common/schedule.c --- a/xen/common/schedule.c Sat Mar 12 13:20:51 2011 +0000 +++ b/xen/common/schedule.c Mon Mar 14 15:32:58 2011 +0100 @@ -393,9 +393,10 @@ static void vcpu_migrate(struct vcpu *v) static void vcpu_migrate(struct vcpu *v) { unsigned long flags; - unsigned int old_cpu, new_cpu; + unsigned int old_cpu, new_cpu, proposal; spinlock_t *old_lock, *new_lock; + proposal = -1; old_cpu = new_cpu = v->processor; for ( ; ; ) { @@ -430,10 +431,11 @@ static void vcpu_migrate(struct vcpu *v) old_cpu = v->processor; if ( old_lock == per_cpu(schedule_data, old_cpu).schedule_lock ) { - new_cpu = SCHED_OP(VCPU2OP(v), pick_cpu, v); + new_cpu = SCHED_OP(VCPU2OP(v), pick_cpu, v, proposal); if ( (new_lock == per_cpu(schedule_data, new_cpu).schedule_lock) && cpu_isset(new_cpu, v->domain->cpupool->cpu_valid) ) break; + proposal = new_cpu; } if ( old_lock != new_lock ) diff -r 84bacd800bf8 -r 9d164ce877a7 xen/include/xen/sched-if.h --- a/xen/include/xen/sched-if.h Sat Mar 12 13:20:51 2011 +0000 +++ b/xen/include/xen/sched-if.h Mon Mar 14 15:32:58 2011 +0100 @@ -167,7 +167,7 @@ struct scheduler { struct task_slice (*do_schedule) (const struct scheduler *, s_time_t, bool_t tasklet_work_scheduled); - int (*pick_cpu) (const struct scheduler *, struct vcpu *); + int (*pick_cpu) (const struct scheduler *, struct vcpu *, int proposal); int (*adjust) (const struct scheduler *, struct domain *, struct xen_domctl_scheduler_op *); int (*adjust_global) (const struct scheduler *,