From d03495677c8f8d35d3d1ba7e33959f1ae6caf03b Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty Date: Wed, 25 Sep 2024 15:38:39 +0200 Subject: [PATCH] fix(freertos/smp): Prevent prvCheckForRunStateChange() in a nested critical section This commit adds a check in vTaskSuspendAll() to avoid calling prvCheckForRunStateChange() if we are in a nested critical section. This can happen if we have aquired a lock in another data group (such as queue) and then we take the kernel lock via the vTaskSuspendAll() call. --- tasks.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/tasks.c b/tasks.c index 734d6c9c01..75384f196e 100644 --- a/tasks.c +++ b/tasks.c @@ -529,15 +529,15 @@ PRIVILEGED_DATA static volatile configRUN_TIME_COUNTER_TYPE ulTotalRunTime[ conf /* Helper macros to lock (critical section) the kernel data group . */ #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) - #define taskLOCK_KERNEL_DATA_GROUP() \ - portDISABLE_INTERRUPTS(); \ - portGET_SPINLOCK( &xTaskSpinlock ); \ + #define taskLOCK_KERNEL_DATA_GROUP() \ + portDISABLE_INTERRUPTS(); \ + portGET_SPINLOCK( &xTaskSpinlock ); \ if( ( xSchedulerRunning != pdFALSE ) && ( portGET_CRITICAL_NESTING_COUNT() == 0U ) ) \ - { \ - prvCheckForRunStateChange(); \ - } \ - portINCREMENT_CRITICAL_NESTING_COUNT(); \ - portGET_SPINLOCK( &xISRSpinlock ); \ + { \ + prvCheckForRunStateChange(); \ + } \ + portINCREMENT_CRITICAL_NESTING_COUNT(); \ + portGET_SPINLOCK( &xISRSpinlock ); \ portINCREMENT_CRITICAL_NESTING_COUNT(); #define taskUNLOCK_KERNEL_DATA_GROUP() \ @@ -4044,7 +4044,11 @@ void vTaskSuspendAll( void ) /* uxSchedulerSuspended is increased after prvCheckForRunStateChange. The * purpose is to prevent altering the variable when fromISR APIs are readying * it. */ - if( uxSchedulerSuspended == 0U ) + if( ( uxSchedulerSuspended == 0U ) + #if ( portUSING_GRANULAR_LOCKS == 1 ) + && ( portGET_CRITICAL_NESTING_COUNT() == 0U ) + #endif /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */ + ) { prvCheckForRunStateChange(); } @@ -4305,7 +4309,7 @@ BaseType_t xTaskResumeAll( void ) #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) && ( pxCurrentTCBs[ xCoreID ]->xPreemptionDisable == 0U ) #endif - ) + ) { #if ( configUSE_PREEMPTION != 0 ) {