[PATCH 1/2] PCI: mediatek-gen3: Stop acquiring spinlocks in {suspend,resume}_noirq

From: AngeloGioacchino Del Regno
Date: Thu May 04 2023 - 07:35:25 EST


In mtk_pcie_suspend_noirq() and mtk_pcie_resume_noirq() we are,
respectively, disabling and enabling generation of interrupts and
then saving and restoring the enabled interrupts register: since
we're using noirq PM callbacks, that can be safely done without
holding any spin lock.

That was noticed because of, and solves, the following issue:

<4>[ 74.185982] ========================================================
<4>[ 74.192629] WARNING: possible irq lock inversion dependency detected
<4>[ 74.199276] 6.3.0-next-20230428+ #51 Tainted: G W
<4>[ 74.205664] --------------------------------------------------------
<4>[ 74.212309] systemd-sleep/809 just changed the state of lock:
<4>[ 74.218347] ffff65a5c34c65a0 (&pcie->irq_lock){+...}-{2:2}, at: mtk_pcie_resume+0x50/0xa8
<4>[ 74.226870] but this lock was taken by another, HARDIRQ-safe lock in the past:
<4>[ 74.234389] (&irq_desc_lock_class){-.-.}-{2:2}
<4>[ 74.234409]
<4>[ 74.234409]
<4>[ 74.234409] and interrupts could create inverse lock ordering between them.
<4>[ 74.234409]
<4>[ 74.251704]
<4>[ 74.251704] other info that might help us debug this:
<4>[ 74.258785] Possible interrupt unsafe locking scenario:
<4>[ 74.258785]
<4>[ 74.266126] CPU0 CPU1
<4>[ 74.270942] ---- ----
<4>[ 74.275758] lock(&pcie->irq_lock);
<4>[ 74.279627] local_irq_disable();
<4>[ 74.285836] lock(&irq_desc_lock_class);
<4>[ 74.292667] lock(&pcie->irq_lock);
<4>[ 74.299061] <Interrupt>
<4>[ 74.301960] lock(&irq_desc_lock_class);
<4>[ 74.306438]
<4>[ 74.306438] *** DEADLOCK ***

Fixes: d537dc125f07 ("PCI: mediatek-gen3: Add system PM support")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@xxxxxxxxxxxxx>
---
drivers/pci/controller/pcie-mediatek-gen3.c | 8 --------
1 file changed, 8 deletions(-)

diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c
index b8612ce5f4d0..52f52ca5db71 100644
--- a/drivers/pci/controller/pcie-mediatek-gen3.c
+++ b/drivers/pci/controller/pcie-mediatek-gen3.c
@@ -963,8 +963,6 @@ static void mtk_pcie_irq_save(struct mtk_gen3_pcie *pcie)
{
int i;

- raw_spin_lock(&pcie->irq_lock);
-
pcie->saved_irq_state = readl_relaxed(pcie->base + PCIE_INT_ENABLE_REG);

for (i = 0; i < PCIE_MSI_SET_NUM; i++) {
@@ -973,16 +971,12 @@ static void mtk_pcie_irq_save(struct mtk_gen3_pcie *pcie)
msi_set->saved_irq_state = readl_relaxed(msi_set->base +
PCIE_MSI_SET_ENABLE_OFFSET);
}
-
- raw_spin_unlock(&pcie->irq_lock);
}

static void mtk_pcie_irq_restore(struct mtk_gen3_pcie *pcie)
{
int i;

- raw_spin_lock(&pcie->irq_lock);
-
writel_relaxed(pcie->saved_irq_state, pcie->base + PCIE_INT_ENABLE_REG);

for (i = 0; i < PCIE_MSI_SET_NUM; i++) {
@@ -991,8 +985,6 @@ static void mtk_pcie_irq_restore(struct mtk_gen3_pcie *pcie)
writel_relaxed(msi_set->saved_irq_state,
msi_set->base + PCIE_MSI_SET_ENABLE_OFFSET);
}
-
- raw_spin_unlock(&pcie->irq_lock);
}

static int mtk_pcie_turn_off_link(struct mtk_gen3_pcie *pcie)
--
2.40.1