drivers/dma/mediatek/mtk-uart-apdma.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
The synchronize_irq(c->irq) will not return until the IRQ handler
mtk_uart_apdma_irq_handler() is completed. If the synchronize_irq()
holds a spin_lock and waits the IRQ handler to complete, but the
IRQ handler also needs the same spin_lock. The deadlock will happen.
The process is shown below:
cpu0 cpu1
mtk_uart_apdma_device_pause() | mtk_uart_apdma_irq_handler()
spin_lock_irqsave() |
| spin_lock_irqsave()
//hold the lock to wait |
synchronize_irq() |
This patch reorders the synchronize_irq(c->irq) outside the spin_lock
in order to mitigate the bug.
Fixes: 9135408c3ace ("dmaengine: mediatek: Add MediaTek UART APDMA support")
Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
---
drivers/dma/mediatek/mtk-uart-apdma.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/dma/mediatek/mtk-uart-apdma.c b/drivers/dma/mediatek/mtk-uart-apdma.c
index a1517ef1f4a..0acf6a92a4a 100644
--- a/drivers/dma/mediatek/mtk-uart-apdma.c
+++ b/drivers/dma/mediatek/mtk-uart-apdma.c
@@ -451,9 +451,8 @@ static int mtk_uart_apdma_device_pause(struct dma_chan *chan)
mtk_uart_apdma_write(c, VFF_EN, VFF_EN_CLR_B);
mtk_uart_apdma_write(c, VFF_INT_EN, VFF_INT_EN_CLR_B);
- synchronize_irq(c->irq);
-
spin_unlock_irqrestore(&c->vc.lock, flags);
+ synchronize_irq(c->irq);
return 0;
}
--
2.17.1
On Sun, 06 Aug 2023 11:25:11 +0800, Duoming Zhou wrote: > The synchronize_irq(c->irq) will not return until the IRQ handler > mtk_uart_apdma_irq_handler() is completed. If the synchronize_irq() > holds a spin_lock and waits the IRQ handler to complete, but the > IRQ handler also needs the same spin_lock. The deadlock will happen. > The process is shown below: > > cpu0 cpu1 > mtk_uart_apdma_device_pause() | mtk_uart_apdma_irq_handler() > spin_lock_irqsave() | > | spin_lock_irqsave() > //hold the lock to wait | > synchronize_irq() | > > [...] Applied, thanks! [1/1] dmaengine: mediatek: Fix deadlock caused by synchronize_irq() commit: 01f1ae2733e2bb4de92fefcea5fda847d92aede1 Best regards, -- ~Vinod
On 8/6/23 06:25, Duoming Zhou wrote: > The synchronize_irq(c->irq) will not return until the IRQ handler > mtk_uart_apdma_irq_handler() is completed. If the synchronize_irq() > holds a spin_lock and waits the IRQ handler to complete, but the > IRQ handler also needs the same spin_lock. The deadlock will happen. > The process is shown below: > > cpu0 cpu1 > mtk_uart_apdma_device_pause() | mtk_uart_apdma_irq_handler() > spin_lock_irqsave() | > | spin_lock_irqsave() > //hold the lock to wait | > synchronize_irq() | > > This patch reorders the synchronize_irq(c->irq) outside the spin_lock > in order to mitigate the bug. > > Fixes: 9135408c3ace ("dmaengine: mediatek: Add MediaTek UART APDMA support") > Signed-off-by: Duoming Zhou <duoming@zju.edu.cn> > --- > drivers/dma/mediatek/mtk-uart-apdma.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/drivers/dma/mediatek/mtk-uart-apdma.c b/drivers/dma/mediatek/mtk-uart-apdma.c > index a1517ef1f4a..0acf6a92a4a 100644 > --- a/drivers/dma/mediatek/mtk-uart-apdma.c > +++ b/drivers/dma/mediatek/mtk-uart-apdma.c > @@ -451,9 +451,8 @@ static int mtk_uart_apdma_device_pause(struct dma_chan *chan) > mtk_uart_apdma_write(c, VFF_EN, VFF_EN_CLR_B); > mtk_uart_apdma_write(c, VFF_INT_EN, VFF_INT_EN_CLR_B); > > - synchronize_irq(c->irq); > - > spin_unlock_irqrestore(&c->vc.lock, flags); > + synchronize_irq(c->irq); > > return 0; > } Reviewed-by: Eugen Hristev <eugen.hristev@collabora.com>
© 2016 - 2024 Red Hat, Inc.