ia64/xen-unstable

changeset 7121:f9a806ba838a

This patch fixes a race between when the disable cpu is marked online
and binding IPIs back to the CPU. In some cases, an IPI would be sent
to CPU1 before it had allocated a new evtchn. Moving smp_resume() call
before setting the cpu online fixes this race. This fixes bug #228
(http://bugzilla.xensource.com/bugzilla/show_bug.cgi?id=228).

Signed-off-by: Ryan Harper <ryanh@us.ibm.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed Sep 28 18:03:20 2005 +0100 (2005-09-28)
parents c7f58e86446f
children 081b326162bc
files linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c	Wed Sep 28 18:01:40 2005 +0100
     1.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c	Wed Sep 28 18:03:20 2005 +0100
     1.3 @@ -112,6 +112,10 @@ void xen_idle(void)
     1.4  
     1.5  #ifdef CONFIG_HOTPLUG_CPU
     1.6  #include <asm/nmi.h>
     1.7 +#ifdef CONFIG_SMP
     1.8 +extern void smp_suspend(void);
     1.9 +extern void smp_resume(void);
    1.10 +#endif
    1.11  /* We don't actually take CPU down, just spin without interrupts. */
    1.12  static inline void play_dead(void)
    1.13  {
    1.14 @@ -120,6 +124,13 @@ static inline void play_dead(void)
    1.15  		HYPERVISOR_yield();
    1.16  
    1.17  	__flush_tlb_all();
    1.18 +   /* 
    1.19 +    * Restore IPI/IRQ mappings before marking online to prevent 
    1.20 +    * race between pending interrupts and restoration of handler. 
    1.21 +    */
    1.22 +#ifdef CONFIG_SMP
    1.23 +	smp_resume();
    1.24 +#endif
    1.25  	cpu_set(smp_processor_id(), cpu_online_map);
    1.26  }
    1.27  #else
    1.28 @@ -135,10 +146,6 @@ static inline void play_dead(void)
    1.29   * low exit latency (ie sit in a loop waiting for
    1.30   * somebody to say that they'd like to reschedule)
    1.31   */
    1.32 -#ifdef CONFIG_SMP
    1.33 -extern void smp_suspend(void);
    1.34 -extern void smp_resume(void);
    1.35 -#endif
    1.36  void cpu_idle (void)
    1.37  {
    1.38  	int cpu = _smp_processor_id();
    1.39 @@ -166,9 +173,6 @@ void cpu_idle (void)
    1.40  				HYPERVISOR_vcpu_down(cpu);
    1.41  #endif
    1.42  				play_dead();
    1.43 -#ifdef CONFIG_SMP
    1.44 -				smp_resume();
    1.45 -#endif
    1.46  				local_irq_enable();
    1.47  			}
    1.48