Safely change next->processor if necessary. Credit2's shared runqueue means that a vcpu may switch from one pcpu to another without an explicit migration. We need to change v->processor to match. However, this must be done with the current v->processor schedule lock held. To avoid deadlock, do this after we've released the current processor's schedule lock. Signed-off-by: George Dunlap diff -r 669448fb9d0c xen/common/schedule.c --- a/xen/common/schedule.c Wed Jan 13 13:47:16 2010 +0000 +++ b/xen/common/schedule.c Wed Jan 13 14:15:51 2010 +0000 @@ -305,6 +305,23 @@ vcpu_wake(v); } +/* Safely change v->processor when running on a different cpu sharing the same runqueue */ +static void __vcpu_processor_sync(struct vcpu *next) +{ + unsigned long flags; + int old_cpu; + int this_cpu = smp_processor_id(); + + vcpu_schedule_lock_irqsave(next, flags); + + /* Switch to new CPU, then unlock old CPU. */ + old_cpu = next->processor; + next->processor = this_cpu; + + spin_unlock_irqrestore( + &per_cpu(schedule_data, old_cpu).schedule_lock, flags); +} + /* * Force a VCPU through a deschedule/reschedule path. * For example, using this when setting the periodic timer period means that @@ -852,6 +869,11 @@ spin_unlock_irq(&sd->schedule_lock); + /* Safely change v->processor if necessary. Do this after + * releasing this cpu's lock to avoid deadlock. */ + if ( next->processor != smp_processor_id() ) + __vcpu_processor_sync(next); + perfc_incr(sched_ctx); stop_timer(&prev->periodic_timer);