From d5c52d5643268f7ac300f88ab744c92f27ee5baa Mon Sep 17 00:00:00 2001 From: Timo Sandmann Date: Sun, 26 Dec 2021 23:56:56 +0100 Subject: [PATCH 1/2] Bugfix for race condition on RP2040 in vPortEnableInterrupts() RP2040 SMP port: Since spin_unlock() re-enables interrupts, pxYieldSpinLock has to be updated first to avoid a possible race condition. --- portable/ThirdParty/GCC/RP2040/port.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/portable/ThirdParty/GCC/RP2040/port.c b/portable/ThirdParty/GCC/RP2040/port.c index c267a83100..4f943ccce2 100644 --- a/portable/ThirdParty/GCC/RP2040/port.c +++ b/portable/ThirdParty/GCC/RP2040/port.c @@ -375,8 +375,9 @@ void vPortEnableInterrupts( void ) #if ( configSUPPORT_PICO_SYNC_INTEROP == 1 ) if( pxYieldSpinLock ) { - spin_unlock(pxYieldSpinLock, ulYieldSpinLockSaveValue); + spin_lock_t* const pxTmpLock = pxYieldSpinLock; pxYieldSpinLock = NULL; + spin_unlock( pxTmpLock, ulYieldSpinLockSaveValue ); } #endif __asm volatile ( " cpsie i " ::: "memory" ); From 6a5abd85d6c4bc243f7c62c566deadc616864390 Mon Sep 17 00:00:00 2001 From: Timo Sandmann Date: Mon, 27 Dec 2021 00:01:01 +0100 Subject: [PATCH 2/2] Bugfix for invalid sanity checks on RP2040 RP2040 SMP port: Testing pxYieldSpinLock for NULL does not work reliable in these places, because another/new lock might already be set when configASSERT() is executed. --- portable/ThirdParty/GCC/RP2040/port.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/portable/ThirdParty/GCC/RP2040/port.c b/portable/ThirdParty/GCC/RP2040/port.c index 4f943ccce2..a2270b1e90 100644 --- a/portable/ThirdParty/GCC/RP2040/port.c +++ b/portable/ThirdParty/GCC/RP2040/port.c @@ -783,9 +783,6 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) ulYieldSpinLockSaveValue = ulSave; xEventGroupWaitBits( xEventGroup, prvGetEventGroupBit(pxLock->spin_lock), pdTRUE, pdFALSE, portMAX_DELAY); - /* sanity check that interrupts were disabled, then re-enabled during the call, which will have - * taken care of the yield */ - configASSERT( pxYieldSpinLock == NULL); } } @@ -858,9 +855,6 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) xEventGroupWaitBits( xEventGroup, prvGetEventGroupBit(pxLock->spin_lock), pdTRUE, pdFALSE, uxTicksToWait ); - /* sanity check that interrupts were disabled, then re-enabled during the call, which will have - * taken care of the yield */ - configASSERT( pxYieldSpinLock == NULL ); } else {