[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Fix context_switch(). It is necessary to set_current() and
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 0ba3b9d60da65bcb9a14122c8b17c255354db764 # Parent 8af1199488d3636135f3adf3f7302d4a04e9004e Fix context_switch(). It is necessary to set_current() and then check curr_vcpu all with interrupts disabled. This in turn requires us to hoist the heck of next's vcpu_dirty_cpumask as sending the flush IPI needs us to have interrupts enabled to avoid deadlock. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> diff -r 8af1199488d3 -r 0ba3b9d60da6 xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Mon Jan 9 11:22:17 2006 +++ b/xen/arch/x86/domain.c Mon Jan 9 11:25:05 2006 @@ -689,6 +689,9 @@ struct vcpu *p = percpu_ctxt[cpu].curr_vcpu; struct vcpu *n = current; + ASSERT(p != n); + ASSERT(cpus_empty(n->vcpu_dirty_cpumask)); + if ( !is_idle_domain(p->domain) ) { memcpy(&p->arch.guest_context.user_regs, @@ -748,24 +751,31 @@ void context_switch(struct vcpu *prev, struct vcpu *next) { unsigned int cpu = smp_processor_id(); + cpumask_t dirty_mask = next->vcpu_dirty_cpumask; ASSERT(local_irq_is_enabled()); + /* Allow at most one CPU at a time to be dirty. */ + ASSERT(cpus_weight(dirty_mask) <= 1); + if ( unlikely(!cpu_isset(cpu, dirty_mask) && !cpus_empty(dirty_mask)) ) + { + /* Other cpus call __sync_lazy_execstate from flush ipi handler. */ + flush_tlb_mask(dirty_mask); + } + + local_irq_disable(); + set_current(next); - if ( (percpu_ctxt[cpu].curr_vcpu != next) && - !is_idle_domain(next->domain) ) - { - /* This may happen if next has been migrated by the scheduler. */ - if ( unlikely(!cpus_empty(next->vcpu_dirty_cpumask)) ) - { - ASSERT(!cpu_isset(cpu, next->vcpu_dirty_cpumask)); - sync_vcpu_execstate(next); - ASSERT(cpus_empty(next->vcpu_dirty_cpumask)); - } - - local_irq_disable(); + if ( (percpu_ctxt[cpu].curr_vcpu == next) || is_idle_domain(next->domain) ) + { + local_irq_enable(); + } + else + { __context_switch(); + + /* Re-enable interrupts before restoring state which may fault. */ local_irq_enable(); if ( VMX_DOMAIN(next) ) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |