• Alistair Popple's avatar
    powerpc/powernv/npu: Fix deadlock in mmio_invalidate() · 2b74e2a9
    Alistair Popple authored
    When sending TLB invalidates to the NPU we need to send extra flushes due
    to a hardware issue. The original implementation would lock the all the
    ATSD MMIO registers sequentially before unlocking and relocking each of
    them sequentially to do the extra flush.
    
    This introduced a deadlock as it is possible for one thread to hold one
    ATSD register whilst waiting for another register to be freed while the
    other thread is holding that register waiting for the one in the first
    thread to be freed.
    
    For example if there are two threads and two ATSD registers:
    
      Thread A	Thread B
      ----------------------
      Acquire 1
      Acquire 2
      Release 1	Acquire 1
      Wait 1	Wait 2
    
    Both threads will be stuck waiting to acquire a register resulting in an
    RCU stall warning or soft lockup.
    
    This patch solves the deadlock by refactoring the code to ensure registers
    are not released between flushes and to ensure all registers are either
    acquired or released together and in order.
    
    Fixes: bbd5ff50 ("powerpc/powernv/npu-dma: Add explicit flush when sending an ATSD")
    Signed-off-by: default avatarAlistair Popple <alistair@popple.id.au>
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    2b74e2a9
npu-dma.c 22.9 KB