diff -r 7280488d98d1 xen/common/sched_credit.c --- a/xen/common/sched_credit.c Fri Aug 31 15:56:20 2007 +0100 +++ b/xen/common/sched_credit.c Fri Aug 31 16:18:46 2007 +0100 @@ -1066,6 +1066,50 @@ csched_tick(void *_cpu) set_timer(&spc->ticker, NOW() + MILLISECS(CSCHED_MSECS_PER_TICK)); } +static void +csched_distribute_domain_vcpus(int cpu, struct domain * ddom) +{ + const struct csched_pcpu * const pcpu = CSCHED_PCPU(cpu); + struct csched_vcpu *sp; + struct list_head * iter, *n; + + list_for_each_safe( iter, n, &pcpu->runq ) + { + sp = __runq_elem(iter); + if( ( sp->vcpu->domain == ddom ) && vcpu_runnable(sp->vcpu) ) { + /* + * There is a short period of time, between the beginning + * of csched_schedule() and context_switch(), where the + * currently running vcpu (aka prev in schedule.c) is on + * the runqueue, and the newly chosen vcpu (next) is off + * the runqueue but not yet running. Scheduling the + * running vcpu on another cpu before it's context + * switched out is disastrous. + * + * Instead we set the migrating bit. This is checked + * after context_switch() occurs. vcpu_migrate will + * call cpu_pick() to choose another cpu at that time. + */ + if( sp->vcpu->is_running ) + { + __runq_remove(sp); + set_bit(_VPF_migrating, &sp->vcpu->pause_flags); + } + else + { + int peer_cpu = csched_cpu_pick(sp->vcpu); + if ( spin_trylock(&per_cpu(schedule_data, peer_cpu).schedule_lock) ) + { + __runq_remove(sp); + sp->vcpu->processor = peer_cpu; + csched_vcpu_wake(sp->vcpu); + spin_unlock(&per_cpu(schedule_data, peer_cpu).schedule_lock); + } + } + } + } +} + static struct csched_vcpu * csched_runq_steal(int peer_cpu, int cpu, int pri) { @@ -1220,6 +1264,13 @@ csched_schedule(s_time_t now) { cpu_clear(cpu, csched_priv.idlers); } + + /* + * Distrubute vcpus from the same domain from this + * runqueue to others + */ + if( !is_idle_vcpu(snext->vcpu) ) + csched_distribute_domain_vcpus(cpu, snext->vcpu->domain); /* * Return task to run next... @@ -1407,3 +1458,13 @@ struct scheduler sched_credit_def = { .dump_settings = csched_dump, .init = csched_init, }; + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */