• Lior Amsalem's avatar
    irqchip: armada-370-xp: fix IPI race condition · 86f06cac
    Lior Amsalem authored
    commit a6f089e95b1e08cdea9633d50ad20aa5d44ba64d upstream.
    
    In the Armada 370/XP driver, when we receive an IRQ 0, we read the
    list of doorbells that caused the interrupt from register
    ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS. This gives the list of IPIs that
    were generated. However, instead of acknowledging only the IPIs that
    were generated, we acknowledge *all* the IPIs, by writing
    ~IPI_DOORBELL_MASK in the ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS register.
    
    This creates a race condition: if a new IPI that isn't part of the
    ones read into the temporary "ipimask" variable is fired before we
    acknowledge all IPIs, then we will simply loose it. This is causing
    scheduling hangs on SMP intensive workloads.
    
    It is important to mention that this ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS
    register has the following behavior: "A CPU write of 0 clears the bits
    in this field. A CPU write of 1 has no effect". This is what allows us
    to simply write ~ipimask to acknoledge the handled IPIs.
    
    Notice that the same problem is present in the MSI implementation, but
    it will be fixed as a separate patch, so that this IPI fix can be
    pushed to older stable versions as appropriate (all the way to 3.8),
    while the MSI code only appeared in 3.13.
    Signed-off-by: default avatarLior Amsalem <alior@marvell.com>
    Signed-off-by: default avatarThomas Petazzoni <thomas.petazzoni@free-electrons.com>
    Fixes: 344e873e 'arm: mvebu: Add IPI support via doorbells'
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: default avatarJason Cooper <jason@lakedaemon.net>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    86f06cac
Name
Last commit
Last update
..
Kconfig Loading commit data...
Makefile Loading commit data...
exynos-combiner.c Loading commit data...
irq-armada-370-xp.c Loading commit data...
irq-bcm2835.c Loading commit data...
irq-gic.c Loading commit data...
irq-metag-ext.c Loading commit data...
irq-metag.c Loading commit data...
irq-mxs.c Loading commit data...
irq-renesas-intc-irqpin.c Loading commit data...
irq-renesas-irqc.c Loading commit data...
irq-s3c24xx.c Loading commit data...
irq-sirfsoc.c Loading commit data...
irq-sun4i.c Loading commit data...
irq-versatile-fpga.c Loading commit data...
irq-vic.c Loading commit data...
irq-vt8500.c Loading commit data...
irqchip.c Loading commit data...
irqchip.h Loading commit data...
spear-shirq.c Loading commit data...