[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.