Skip to content

Commit

Permalink
PCI: mediatek-gen3: Stop acquiring spinlocks in {suspend,resume}_noirq
Browse files Browse the repository at this point in the history
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+ torvalds#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: d537dc1 ("PCI: mediatek-gen3: Add system PM support")
Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
  • Loading branch information
AngeloGioacchino Del Regno authored and tobhe committed Sep 8, 2024
1 parent fce276b commit 5f943c4
Showing 1 changed file with 2 additions and 10 deletions.
12 changes: 2 additions & 10 deletions drivers/pci/controller/pcie-mediatek-gen3.c
Original file line number Diff line number Diff line change
Expand Up @@ -976,8 +976,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++) {
Expand All @@ -986,16 +984,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++) {
Expand All @@ -1004,8 +998,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)
Expand Down Expand Up @@ -1070,8 +1062,8 @@ static int mtk_pcie_resume_noirq(struct device *dev)
}

static const struct dev_pm_ops mtk_pcie_pm_ops = {
NOIRQ_SYSTEM_SLEEP_PM_OPS(mtk_pcie_suspend_noirq,
mtk_pcie_resume_noirq)
.suspend_noirq = mtk_pcie_suspend_noirq,
.resume_noirq = mtk_pcie_resume_noirq,
};

static const struct of_device_id mtk_pcie_of_match[] = {
Expand Down

0 comments on commit 5f943c4

Please sign in to comment.