1. 21 1月, 2014 1 次提交
  2. 14 12月, 2013 2 次提交
    • L
      irqchip: armada-370-xp: fix MSI race condition · c7f7bd4a
      Lior Amsalem 提交于
      In the Armada 370/XP driver, when we receive an IRQ 1, we read the
      list of doorbells that caused the interrupt from register
      ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS. This gives the list of MSIs that
      were generated. However, instead of acknowledging only the MSIs that
      were generated, we acknowledge *all* the MSIs, by writing
      ~MSI_DOORBELL_MASK in the ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS register.
      
      This creates a race condition: if a new MSI that isn't part of the
      ones read into the temporary "msimask" variable is fired before we
      acknowledge all MSIs, then we will simply loose it.
      
      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 ~msimask to acknoledge the handled MSIs.
      
      Notice that the same problem is present in the IPI implementation, but
      it is 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: NLior Amsalem <alior@marvell.com>
      Signed-off-by: NThomas Petazzoni <thomas.petazzoni@free-electrons.com>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Signed-off-by: NJason Cooper <jason@lakedaemon.net>
      c7f7bd4a
    • L
      irqchip: armada-370-xp: fix IPI race condition · a6f089e9
      Lior Amsalem 提交于
      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: NLior Amsalem <alior@marvell.com>
      Signed-off-by: NThomas Petazzoni <thomas.petazzoni@free-electrons.com>
      Cc: stable@vger.kernel.org # v3.8+
      Fixes: 344e873e 'arm: mvebu: Add IPI support via doorbells'
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Signed-off-by: NJason Cooper <jason@lakedaemon.net>
      a6f089e9
  3. 30 9月, 2013 2 次提交
  4. 16 4月, 2013 4 次提交
  5. 11 4月, 2013 1 次提交
    • G
      arm: mvebu: Fix the irq map function in SMP mode · 600468d0
      Gregory CLEMENT 提交于
      This patch fix the regression introduced by the commit 3202bf01
      "arm: mvebu: Improve the SMP support of the interrupt controller":
      GPIO IRQ were no longer delivered to the CPUs.
      
      To be delivered to a CPU an interrupt must be enabled at CPU level and
      at interrupt source level. Before the offending patch, all the
      interrupts were enabled at source level during map() function. Mask()
      and unmask() was done by handling the per-CPU part. It was fine when
      running in UP with only one CPU.
      
      The offending patch added support for SMP, in this case mask() and
      unmask() was done by handling the interrupt source level part. The
      per-CPU level part was handled by the affinity API to select the CPU
      which will receive the interrupt. (Due to some hardware limitation
      only one CPU at a time can received a given interrupt).
      
      For "normal" interrupt __setup_irq() was called when an irq was
      registered. irq_set_affinity() is called from this function, which
      enabled the interrupt on one of the CPUs. Whereas for GPIO IRQ which
      were chained interrupts, the irq_set_affinity() was never called and
      none of the CPUs was selected to receive the interrupt.
      
      With this patch all the interrupt are enable on the current CPU during
      map() function. Enabling the interrupts on a CPU doesn't depend
      anymore on irq_set_affinity() and then the chained irq are not anymore
      a special case. However the CPU which will receive the irq can still
      be modify later using irq_set_affinity().
      
      Tested with Mirabox (A370) and Openblocks AX3 (AXP), rootfs mounted
      over NFS, compiled with CONFIG_SMP=y/N.
      Signed-off-by: NGregory CLEMENT <gregory.clement@free-electrons.com>
      Reported-by: NRyan Press <ryan@presslab.us>
      Investigated-by: NEzequiel Garcia <ezequiel.garcia@free-electrons.com>
      Tested-by: NEzequiel Garcia <ezequiel.garcia@free-electrons.com>
      Tested-by: NRyan Press <ryan@presslab.us>
      Signed-off-by: NJason Cooper <jason@lakedaemon.net>
      600468d0
  6. 29 3月, 2013 1 次提交
  7. 18 3月, 2013 1 次提交
  8. 01 3月, 2013 2 次提交
  9. 27 11月, 2012 1 次提交
  10. 21 11月, 2012 1 次提交
  11. 10 7月, 2012 2 次提交