[PATCH] dmaengine: xilinx_dma: Use readl_poll_timeout() instead of atomic variant

Tomi Valkeinen posted 1 patch 1 month, 4 weeks ago
drivers/dma/xilinx/xilinx_dma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[PATCH] dmaengine: xilinx_dma: Use readl_poll_timeout() instead of atomic variant
Posted by Tomi Valkeinen 1 month, 4 weeks ago
All callers of xilinx_dma_poll_timeout() pass a zero delay and a 1
second timeout (XILINX_DMA_LOOP_COUNT). With a zero delay,
readl_poll_timeout_atomic() does not measure wall clock time, and the
actual timeout can be much more than 1 second.

This is very visible when a channel reset never completes, e.g. with a
VDMA whose stream-side clock isn't running. Probe appears to hang, and
only minutes later fails with:

  xilinx-vdma a0050000.dma: reset timeout, cr 4, sr 0
  xilinx-vdma a0050000.dma: Reset channel failed

Switch to readl_poll_timeout(), which checks the deadline against
ktime_get().

Calling xilinx_dma_poll_timeout() from atomic context is still safe even
after this change, as readl_poll_timeout() with zero delay never sleeps.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
 drivers/dma/xilinx/xilinx_dma.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 404235c17353..6e8c786147f7 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -530,7 +530,7 @@ struct xilinx_dma_device {
 #define to_dma_tx_descriptor(tx) \
 	container_of(tx, struct xilinx_dma_tx_descriptor, async_tx)
 #define xilinx_dma_poll_timeout(chan, reg, val, cond, delay_us, timeout_us) \
-	readl_poll_timeout_atomic(chan->xdev->regs + chan->ctrl_offset + reg, \
+	readl_poll_timeout(chan->xdev->regs + chan->ctrl_offset + reg, \
 				  val, cond, delay_us, timeout_us)
 
 /* IO accessors */

---
base-commit: f5098b6bae761e346ebcd9da7f95622c04733cff
change-id: 20260803-xilinx-dma-poll-fix-15ab556a7f58

Best regards,
--  
Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Re: [PATCH] dmaengine: xilinx_dma: Use readl_poll_timeout() instead of atomic variant
Posted by Alex Bereza 1 month, 4 weeks ago
Hi Tomi,

seems your patch is not based off the current dmaengine tree. Please
have a look at
https://lore.kernel.org/dmaengine/20260402-fix-atomic-poll-timeout-regression-v4-0-f30d6a6c13cb@bereza.email/

BR
Alex
Re: [PATCH] dmaengine: xilinx_dma: Use readl_poll_timeout() instead of atomic variant
Posted by Tomi Valkeinen 1 month, 4 weeks ago
Hi,

On 04/08/2026 10:12, Alex Bereza wrote:
> Hi Tomi,
> 
> seems your patch is not based off the current dmaengine tree. Please
> have a look at
> https://lore.kernel.org/dmaengine/20260402-fix-atomic-poll-timeout-regression-v4-0-f30d6a6c13cb@bereza.email/
Thanks, I missed that. Problem solved, ignore this series!

  Tomi
Re: [PATCH] dmaengine: xilinx_dma: Use readl_poll_timeout() instead of atomic variant
Posted by Tomi Valkeinen 1 month, 4 weeks ago
Hi,

On 03/08/2026 16:20, Tomi Valkeinen wrote:
> All callers of xilinx_dma_poll_timeout() pass a zero delay and a 1
> second timeout (XILINX_DMA_LOOP_COUNT). With a zero delay,
> readl_poll_timeout_atomic() does not measure wall clock time, and the
> actual timeout can be much more than 1 second.
> 
> This is very visible when a channel reset never completes, e.g. with a
> VDMA whose stream-side clock isn't running. Probe appears to hang, and
> only minutes later fails with:
> 
>    xilinx-vdma a0050000.dma: reset timeout, cr 4, sr 0
>    xilinx-vdma a0050000.dma: Reset channel failed
> 
> Switch to readl_poll_timeout(), which checks the deadline against
> ktime_get().
> 
> Calling xilinx_dma_poll_timeout() from atomic context is still safe even
> after this change, as readl_poll_timeout() with zero delay never sleeps.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
> ---
>   drivers/dma/xilinx/xilinx_dma.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
> index 404235c17353..6e8c786147f7 100644
> --- a/drivers/dma/xilinx/xilinx_dma.c
> +++ b/drivers/dma/xilinx/xilinx_dma.c
> @@ -530,7 +530,7 @@ struct xilinx_dma_device {
>   #define to_dma_tx_descriptor(tx) \
>   	container_of(tx, struct xilinx_dma_tx_descriptor, async_tx)
>   #define xilinx_dma_poll_timeout(chan, reg, val, cond, delay_us, timeout_us) \
> -	readl_poll_timeout_atomic(chan->xdev->regs + chan->ctrl_offset + reg, \
> +	readl_poll_timeout(chan->xdev->regs + chan->ctrl_offset + reg, \
>   				  val, cond, delay_us, timeout_us)
As commented by Sashiko, readl_poll_timeout API doc says "Must not be 
called from atomic context if sleep_us or timeout_us are used".

Maybe a better fix is to continue using readl_poll_timeout_atomic, but 
use a small (non-zero) delay_us, and decrease the timeout_us. Using a 
one second timeout when calling from atomic context doesn't sound very 
good in any case.

  Tomi