| From 516331dc0acf580658daee4dc5cd8819590a9346 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Sun, 6 Aug 2023 11:25:11 +0800 |
| Subject: dmaengine: mediatek: Fix deadlock caused by synchronize_irq() |
| |
| From: Duoming Zhou <duoming@zju.edu.cn> |
| |
| [ Upstream commit 01f1ae2733e2bb4de92fefcea5fda847d92aede1 ] |
| |
| 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> |
| Reviewed-by: Eugen Hristev <eugen.hristev@collabora.com> |
| Link: https://lore.kernel.org/r/20230806032511.45263-1-duoming@zju.edu.cn |
| Signed-off-by: Vinod Koul <vkoul@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| 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 a1517ef1f4a01..0acf6a92a4ad3 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.40.1 |
| |