From c96348a8fbff90ef610b0323218e9d585683bdd2 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Fri, 11 Jun 2021 10:00:03 -0700 Subject: drm/msm/dpu: Avoid ABBA deadlock between IRQ modules 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: Bjorn Andersson Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20210611170003.3539059-1-bjorn.andersson@linaro.org Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index 2b23696ee7fd..323a6bce9e64 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -82,14 +82,12 @@ struct dpu_irq_callback { * struct dpu_irq: IRQ structure contains callback registration info * @total_irq: total number of irq_idx obtained from HW interrupts mapping * @irq_cb_tbl: array of IRQ callbacks setting - * @cb_lock: callback lock * @debugfs_file: debugfs file for irq statistics */ struct dpu_irq { u32 total_irqs; struct list_head *irq_cb_tbl; atomic_t *irq_counts; - spinlock_t cb_lock; }; struct dpu_kms { -- cgit v1.2.3