drivers/uart: stm32: fix dead lock on poll_out

A dead lock could happen if 2 threads with differents priorities use
poll_out. In fact, the lock data->tx_lock could be lock by a thread with
lower priority and then a thread with higher priority can't take the
lock. There was a race condition here:

/* Wait for TXE flag to be raised */
while (1) {
	if (atomic_cas(&data->tx_lock, 0, 1)) {
		/* !!!!!!!! RACE CONDITION !!!!!!!!!!!!!!
		if (LL_USART_IsActiveFlag_TXE(UartInstance)) {
			break;
		}
		atomic_set(&data->tx_lock, 0);
	}
}

To fix race condition, the interrupts are locked in poll_out.

Signed-off-by: Julien D'ascenzio <julien.dascenzio@paratronic.fr>
This commit is contained in:
Julien D'ascenzio 2021-12-01 10:19:44 +01:00 committed by Christopher Friedt
commit e4234aeb89
2 changed files with 50 additions and 11 deletions

View file

@ -57,7 +57,6 @@ struct uart_stm32_data {
uint32_t baud_rate;
/* clock device */
const struct device *clock;
atomic_t tx_lock;
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
uart_irq_callback_user_data_t user_cb;
void *user_data;
@ -74,6 +73,7 @@ struct uart_stm32_data {
#endif
#ifdef CONFIG_PM
bool tx_poll_stream_on;
bool tx_int_stream_on;
bool pm_constraint_on;
#endif
};