• Bjorn Andersson's avatar
    drm/msm/dpu: Avoid ABBA deadlock between IRQ modules · c96348a8
    Bjorn Andersson authored
    Handling of the interrupt callback lists is done in dpu_core_irq.c,
    under the "cb_lock" spinlock. When these operations results in the need
    for enableing or disabling the IRQ in the hardware the code jumps to
    dpu_hw_interrupts.c, which protects its operations with "irq_lock"
    spinlock.
    
    When an interrupt fires, dpu_hw_intr_dispatch_irq() inspects the
    hardware state while holding the "irq_lock" spinlock and jumps to
    dpu_core_irq_callback_handler() to invoke the registered handlers, which
    traverses the callback list under the "cb_lock" spinlock.
    
    As such, in the event that these happens concurrently we'll end up with
    a deadlock.
    
    Prior to '1c1e7763a6d4 ("drm/msm/dpu: simplify IRQ enabling/disabling")'
    the enable/disable of the hardware interrupt was done outside the
    "cb_lock" region, optimitically by using an atomic enable-counter for
    each interrupt and an warning print if someone changed the list between
    the atomic_read and the time the operation concluded.
    
    Rather than re-introducing the large array of atomics, this change
    embraces the fact that dpu_core_irq and dpu_hw_interrupts are deeply
    entangled and make them share the single "irq_lock".
    
    Following this step it's suggested that we squash the two parts into a
    single irq handling thing.
    
    Fixes: 1c1e7763a6d4 ("drm/msm/dpu: simplify IRQ enabling/disabling")
    Signed-off-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
    Reviewed-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
    Link: https://lore.kernel.org/r/20210611170003.3539059-1-bjorn.andersson@linaro.orgSigned-off-by: default avatarRob Clark <robdclark@chromium.org>
    c96348a8
dpu_hw_interrupts.c 10.3 KB