From 85b6ff0b0bcc7f86cad1f360a63121b18726391f Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Mon, 26 May 2025 15:34:15 +0300 Subject: [PATCH] drivers: dma: sdma: Make access to DMA channel stats atomic DMA channel stats like pending_length or free is not protected and can be modified in parallel by a consumer and a producer. This can result in non-atomic updates which in turn will result in using stale data. Fix this by making regions of code accessing dma stats atomic. Fixes: e94c86f3951 ("drivers: dma: Add initial support for NXP SDMA") Signed-off-by: Daniel Baluta --- drivers/dma/dma_nxp_sdma.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/dma/dma_nxp_sdma.c b/drivers/dma/dma_nxp_sdma.c index fb91605d192..51885d60f46 100644 --- a/drivers/dma/dma_nxp_sdma.c +++ b/drivers/dma/dma_nxp_sdma.c @@ -376,11 +376,14 @@ static int dma_nxp_sdma_get_status(const struct device *dev, uint32_t channel, { struct sdma_dev_data *dev_data = dev->data; struct sdma_channel_data *chan_data; + unsigned int key; chan_data = &dev_data->chan[channel]; + key = irq_lock(); stat->free = chan_data->stat.free; stat->pending_length = chan_data->stat.pending_length; + irq_unlock(key); return 0; } @@ -390,6 +393,7 @@ static int dma_nxp_sdma_reload(const struct device *dev, uint32_t channel, uint3 { struct sdma_dev_data *dev_data = dev->data; struct sdma_channel_data *chan_data; + unsigned int key; chan_data = &dev_data->chan[channel]; @@ -397,11 +401,13 @@ static int dma_nxp_sdma_reload(const struct device *dev, uint32_t channel, uint3 return 0; } + key = irq_lock(); if (chan_data->direction == MEMORY_TO_PERIPHERAL) { dma_nxp_sdma_produce(chan_data, size); } else { dma_nxp_sdma_consume(chan_data, size); } + irq_unlock(key); return 0; }