drivers: serial: stm32: prevent race condition
The async_user_callback could be triggered from both the DMA transfer complete interrupt and a k_work queue timeout. Since the timeout runs outside of an ISR context, it could be interrupted by the DMA ISR. This might leads to a race condition where both paths access and modify shared DMA buffer state (offset and length) simultaneously, causing data corruption or out-of-sequence processing. Introduces proper synchronization to prevent concurrent access to shared DMA buffer variables, ensuring consistent and reliable data handling. Signed-off-by: Fabrice DJIATSA <fabrice.djiatsa-ext@st.com>
This commit is contained in:
parent
21daac55ed
commit
26a43ca88e
1 changed files with 10 additions and 0 deletions
|
@ -1806,11 +1806,21 @@ static void uart_stm32_async_rx_timeout(struct k_work *work)
|
|||
|
||||
LOG_DBG("rx timeout");
|
||||
|
||||
/* The DMA is still active and could trigger an interrupt
|
||||
* while we are processing this timeout, which could cause
|
||||
* data corruption when the DMA ISR modifies shared data
|
||||
* as we are operating on it. Prevent data race with ISR by
|
||||
* masking all interrupts until we're done.
|
||||
*/
|
||||
unsigned int key = irq_lock();
|
||||
|
||||
if (data->dma_rx.counter == data->dma_rx.buffer_length) {
|
||||
uart_stm32_async_rx_disable(dev);
|
||||
} else {
|
||||
uart_stm32_dma_rx_flush(dev, STM32_ASYNC_STATUS_TIMEOUT);
|
||||
}
|
||||
|
||||
irq_unlock(key);
|
||||
}
|
||||
|
||||
static void uart_stm32_async_tx_timeout(struct k_work *work)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue