[Cbe-oss-dev] No Subject
Benjamin Herrenschmidt
benh at kernel.crashing.org
Tue Feb 26 16:44:12 EST 2008
On Tue, 2008-02-26 at 06:14 +0100, Arnd Bergmann wrote:
> Subject: spufs: synchronize IRQ when disabling
>
> There is a small race between the context save procedure
> and the SPU interrupt handling, where we expect all interrupt
> processing to have finished after disabling them, while
> an interrupt is still being processed on another CPU.
>
> The obvious fix is to call synchronize_irq() after disabling
> the interrupts at the start of the context save procedure
> to make sure we never access the SPU any more during an
> ongoing save or even after that.
>
> Thanks to Benjamin Herrenschmidt for pointing this out.
>
Acked-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>
>
> ---
>
> Index: linux-2.6/arch/powerpc/platforms/cell/spufs/switch.c
> ===================================================================
> --- linux-2.6.orig/arch/powerpc/platforms/cell/spufs/switch.c
> +++ linux-2.6/arch/powerpc/platforms/cell/spufs/switch.c
> @@ -34,6 +34,7 @@
>
> #include <linux/module.h>
> #include <linux/errno.h>
> +#include <linux/hardirq.h>
> #include <linux/sched.h>
> #include <linux/kernel.h>
> #include <linux/mm.h>
> @@ -117,6 +118,8 @@ static inline void disable_interrupts(st
> * Write INT_MASK_class1 with value of 0.
> * Save INT_Mask_class2 in CSA.
> * Write INT_MASK_class2 with value of 0.
> + * Synchronize all three interrupts to be sure
> + * we no longer execute a handler on another CPU.
> */
> spin_lock_irq(&spu->register_lock);
> if (csa) {
> @@ -129,6 +132,9 @@ static inline void disable_interrupts(st
> spu_int_mask_set(spu, 2, 0ul);
> eieio();
> spin_unlock_irq(&spu->register_lock);
> + synchronize_irq(spu->irqs[0]);
> + synchronize_irq(spu->irqs[1]);
> + synchronize_irq(spu->irqs[2]);
> }
>
> static inline void set_watchdog_timer(struct spu_state *csa, struct spu *spu)
More information about the cbe-oss-dev
mailing list