diff -r 75861b50b30a xen/common/sched_credit.c --- a/xen/common/sched_credit.c Wed Jun 16 12:45:13 2010 +0100 +++ b/xen/common/sched_credit.c Wed Jun 16 14:58:02 2010 +0100 @@ -1028,6 +1028,50 @@ 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) { @@ -1198,6 +1242,13 @@ if ( !is_idle_vcpu(snext->vcpu) ) snext->start_time += now; + /* + * 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... */ @@ -1415,3 +1466,13 @@ .tick_suspend = csched_tick_suspend, .tick_resume = csched_tick_resume, }; + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */