This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit d8deca6c52bc77df8dd408b14bb82a1391b272b7 Author: Jukka Laitinen <[email protected]> AuthorDate: Fri Sep 11 10:35:08 2026 +0300 arch/arm/imx9, arch/arm64/imx9: Release eDMA lock before callbacks Fix a potential deadlock in the DMA driver. DMA completion callbacks may immediately submit another transfer, for example: imx9_dmaterminate() -> imx9_dma_txcallback() -> imx9_dma_txavailable() -> uart_xmitchars_dma() -> imx9_dma_send() -> imx9_dmach_stop() -> imx9_dmaterminate() Resulting dmaterminate to take the same spinlock again. Fix this by moving the spin_unlock_irqrestore_nopreempt before calling the callback. It is not necessary to keep dma channel locked during the callback; the channel is already free at this point. This doesn't directly affect arch/arm/imx9 (the cortex-m version) because it is not SMP (the spinlock is reduced to blocking irqs), but it is worth fixing at the same to keep drivers in sync. Signed-off-by: Jukka Laitinen <[email protected]> --- arch/arm/src/imx9/imx9_edma.c | 4 ++-- arch/arm64/src/imx9/imx9_edma.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/src/imx9/imx9_edma.c b/arch/arm/src/imx9/imx9_edma.c index c045c120a92..c6efff7b3a2 100644 --- a/arch/arm/src/imx9/imx9_edma.c +++ b/arch/arm/src/imx9/imx9_edma.c @@ -548,12 +548,12 @@ static void imx9_dmaterminate(struct imx9_dmach_s *dmach, int result) dmach->arg = NULL; dmach->state = IMX9_DMA_IDLE; + spin_unlock_irqrestore_nopreempt(&g_edma.lock, flags); + if (callback) { callback((DMACH_HANDLE)dmach, arg, true, result); } - - spin_unlock_irqrestore_nopreempt(&g_edma.lock, flags); } /**************************************************************************** diff --git a/arch/arm64/src/imx9/imx9_edma.c b/arch/arm64/src/imx9/imx9_edma.c index af85d41dafa..08327f5d092 100644 --- a/arch/arm64/src/imx9/imx9_edma.c +++ b/arch/arm64/src/imx9/imx9_edma.c @@ -499,12 +499,12 @@ static void imx9_dmaterminate(struct imx9_dmach_s *dmach, int result) dmach->arg = NULL; dmach->state = IMX9_DMA_IDLE; + spin_unlock_irqrestore_nopreempt(&g_edma.lock, flags); + if (callback) { callback((DMACH_HANDLE)dmach, arg, true, result); } - - spin_unlock_irqrestore_nopreempt(&g_edma.lock, flags); } /****************************************************************************
