Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Repeat esp_mqtt_client_start/esp_mqtt_client_stop calls hit Load access fault panic (IDFGH-10652) #11883

Closed
3 tasks done
AxelLin opened this issue Jul 16, 2023 · 10 comments
Closed
3 tasks done
Assignees
Labels
Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Type: Bug bugs in IDF

Comments

@AxelLin
Copy link
Contributor

AxelLin commented Jul 16, 2023

Answers checklist.

  • I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
  • I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
  • I have searched the issue tracker for a similar issue and not found a similar issue.

IDF version.

v5.2-dev-1709-g4fc2e5cb95

Operating System used.

Linux

How did you build your project?

Command line with idf.py

If you are using Windows, please specify command line type.

None

Development Kit.

ESP32C3

Power Supply used.

USB

What is the expected behavior?

Test using mqtt/tcp example code.
Below is the modified code to reproduce this issue.

  • Add a loop to repeatly calling esp_mqtt_client_start/esp_mqtt_client_stop.
  • I add a counter to show test count
index 06ff1ad43e..fc8caa4271 100644
--- a/examples/protocols/mqtt/tcp/main/app_main.c
+++ b/examples/protocols/mqtt/tcp/main/app_main.c
@@ -140,7 +140,13 @@ static void mqtt_app_start(void)
     esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
     /* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
     esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
+    while (1) {
+    static int count = 0;
+    ESP_LOGW(TAG, "count = %d", ++count);
     esp_mqtt_client_start(client);
+    esp_mqtt_client_stop(client);
+    vTaskDelay(500 / portTICK_PERIOD_MS);
+   }
 }
 
 void app_main(void)

What is the actual behavior?

W (1591867) MQTT_EXAMPLE: count = 2648
I (1591867) MQTT_EXAMPLE: Other event id:7
I (1591907) MQTT_EXAMPLE: MQTT_EVENT_CONNECTED
I (1591907) MQTT_EXAMPLE: sent publish successful, msg_id=54938
I (1591917) MQTT_EXAMPLE: sent subscribe successful, msg_id=5151
I (1591917) MQTT_EXAMPLE: sent subscribe successful, msg_id=57498
I (1591927) MQTT_EXAMPLE: sent unsubscribe successful, msg_id=11696
W (1592437) MQTT_EXAMPLE: count = 2649
I (1592437) MQTT_EXAMPLE: Other event id:7
I (1592477) MQTT_EXAMPLE: MQTT_EVENT_CONNECTED
I (1592477) MQTT_EXAMPLE: sent publish successful, msg_id=23433
I (1592487) MQTT_EXAMPLE: sent subscribe successful, msg_id=9000
I (1592487) MQTT_EXAMPLE: sent subscribe successful, msg_id=29009
I (1592497) MQTT_EXAMPLE: sent unsubscribe successful, msg_id=32861
Guru Meditation Error: Core 0 panic'ed (Load access fault). Exception was unhandled.

Stack dump detected
Core 0 register dump:
MEPC : 0x403896e6 RA : 0x40388352 SP : 0x3fca9890 GP : 0x3fc91000
0x403896e6: uxListRemove at /home/axel/esp/esp-idf/components/freertos/FreeRTOS-Kernel/list.c:195

0x40388352: xTaskResumeAll at /home/axel/esp/esp-idf/components/freertos/FreeRTOS-Kernel/tasks.c:2607

TP : 0x3fc846cc T0 : 0x4005890e T1 : 0x40383224 T2 : 0x00000001
0x4005890e: memset in ROM

0x40383224: mutex_unlock_wrapper at /home/axel/esp/esp-idf/components/esp_wifi/esp32c3/esp_adapter.c:197

S0/FP : 0x00000000 S1 : 0x3fc9a950 A0 : 0x00000018 A1 : 0x3fc9a950
A2 : 0x00000021 A3 : 0x3fc97000 A4 : 0x00000005 A5 : 0x3fc93210
A6 : 0x00000001 A7 : 0x00000000 S2 : 0x3fca7454 S3 : 0xffffffff
S4 : 0x00000000 S5 : 0x00000000 S6 : 0x00000000 S7 : 0x00000000
S8 : 0x00000000 S9 : 0x00000000 S10 : 0x00000000 S11 : 0x00000000
T3 : 0x00000000 T4 : 0x0017baed T5 : 0x00000000 T6 : 0x00000000
MSTATUS : 0x00001881 MTVEC : 0x40380001 MCAUSE : 0x00000005 MTVAL : 0x00000028
0x40380001: _vector_table at ??:?

MHARTID : 0x00000000

Backtrace:

uxListRemove (pxItemToRemove=pxItemToRemove@entry=0x18) at /home/axel/esp/esp-idf/components/freertos/FreeRTOS-Kernel/list.c:195
195 List_t * const pxList = pxItemToRemove->pxContainer;
#0 uxListRemove (pxItemToRemove=pxItemToRemove@entry=0x18) at /home/axel/esp/esp-idf/components/freertos/FreeRTOS-Kernel/list.c:195
#1 0x40388352 in xTaskResumeAll () at /home/axel/esp/esp-idf/components/freertos/FreeRTOS-Kernel/tasks.c:2606
#2 0x40389a00 in xEventGroupSetBits (xEventGroup=0x3fca7448, uxBitsToSet=uxBitsToSet@entry=1) at /home/axel/esp/esp-idf/components/freertos/FreeRTOS-Kernel/event_groups.c:647
#3 0x4200ae48 in esp_mqtt_task (pv=0x3fca7224, pv@entry=) at /home/axel/esp/esp-idf/components/mqtt/esp-mqtt/mqtt_client.c:1662
#4 0x40389140 in vPortTaskWrapper (pxCode=, pvParameters=) at /home/axel/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c:213
ELF file SHA256: 3becfaa04e69dbc0

Rebooting...
ESP-ROM:esp32c3-api1-20210207
Build:Feb 7 2021
rst:0xc (RTC_SW_CPU_RST),boot:0xf (SPI_FAST_FLASH_BOOT)
Saved PC:0x40380616
0x40380616: esp_restart_noos at /home/axel/esp/esp-idf/components/esp_system/port/soc/esp32c3/system_internal.c:108 (discriminator 1)

Steps to reproduce.

Just run examples/protocols/mqtt/tcp example code with above modification.

Debug Logs.

No response

More Information.

No response

@AxelLin AxelLin added the Type: Bug bugs in IDF label Jul 16, 2023
@github-actions github-actions bot changed the title Repeat esp_mqtt_client_start/esp_mqtt_client_stop calls hit Load access fault panic Repeat esp_mqtt_client_start/esp_mqtt_client_stop calls hit Load access fault panic (IDFGH-10652) Jul 16, 2023
@espressif-bot espressif-bot added the Status: Opened Issue is new label Jul 16, 2023
@AxelLin
Copy link
Contributor Author

AxelLin commented Jul 17, 2023

Here is another panic log, this just can happen sometimes. (Sometimes it takes much longer time to reproduce).

I (916527) MQTT_EXAMPLE: Other event id:7
I (916557) MQTT_EXAMPLE: MQTT_EVENT_CONNECTED
I (916557) MQTT_EXAMPLE: sent publish successful, msg_id=61748
I (916557) MQTT_EXAMPLE: sent subscribe successful, msg_id=27471
I (916567) MQTT_EXAMPLE: sent subscribe successful, msg_id=35542
I (916577) MQTT_EXAMPLE: sent unsubscribe successful, msg_id=45444
I (916577) MQTT_EXAMPLE: MQTT_EVENT_PUBLISHED, msg_id=61748
W (917107) MQTT_EXAMPLE: count = 689
I (917107) MQTT_EXAMPLE: Other event id:7
I (917127) MQTT_EXAMPLE: MQTT_EVENT_CONNECTED
I (917137) MQTT_EXAMPLE: sent publish successful, msg_id=33371
I (917137) MQTT_EXAMPLE: sent subscribe successful, msg_id=52997
I (917137) MQTT_EXAMPLE: sent subscribe successful, msg_id=2816
I (917147) MQTT_EXAMPLE: sent unsubscribe successful, msg_id=46726
I (917157) MQTT_EXAMPLE: MQTT_EVENT_PUBLISHED, msg_id=33371
W (917717) MQTT_EXAMPLE: count = 690
I (917717) MQTT_EXAMPLE: Other event id:7
I (917747) MQTT_EXAMPLE: MQTT_EVENT_CONNECTED
I (917747) MQTT_EXAMPLE: sent publish successful, msg_id=5732
I (917747) MQTT_EXAMPLE: sent subscribe successful, msg_id=27097
I (917747) MQTT_EXAMPLE: sent subscribe successful, msg_id=37298
I (917757) MQTT_EXAMPLE: sent unsubscribe successful, msg_id=57596
I (917767) MQTT_EXAMPLE: MQTT_EVENT_PUBLISHED, msg_id=5732
Guru Meditation Error: Core  0 panic'ed (Load access fault). Exception was unhandled.

Core  0 register dump:
MEPC    : 0x403896e6  RA      : 0x40388352  SP      : 0x3fca9780  GP      : 0x3fc91000  
TP      : 0x3fc8462c  T0      : 0x4005890e  T1      : 0x40383224  T2      : 0x00000005  
S0/FP   : 0x00000000  S1      : 0x3fc9a950  A0      : 0x00000018  A1      : 0x3fc9a950  
A2      : 0x00000021  A3      : 0x3fc97000  A4      : 0x00000005  A5      : 0x3fc93210  
A6      : 0x00000001  A7      : 0x00000000  S2      : 0x3fca7434  S3      : 0xffffffff  
S4      : 0x00000001  S5      : 0x00000000  S6      : 0x00000000  S7      : 0x00000000  
S8      : 0x00000000  S9      : 0x00000000  S10     : 0x00000000  S11     : 0x00000000  
T3      : 0x00000000  T4      : 0x000dad09  T5      : 0x00000001  T6      : 0x3fca7810  
MSTATUS : 0x00001881  MTVEC   : 0x40380001  MCAUSE  : 0x00000005  MTVAL   : 0x00000028  
MHARTID : 0x00000000  

uxListRemove (pxItemToRemove=pxItemToRemove@entry=0x18) at /home/axel/esp/esp-idf/components/freertos/FreeRTOS-Kernel/list.c:195
195         List_t * const pxList = pxItemToRemove->pxContainer;
#0  uxListRemove (pxItemToRemove=pxItemToRemove@entry=0x18) at /home/axel/esp/esp-idf/components/freertos/FreeRTOS-Kernel/list.c:195
#1  0x40388352 in xTaskResumeAll () at /home/axel/esp/esp-idf/components/freertos/FreeRTOS-Kernel/tasks.c:2606
#2  0x40389a00 in xEventGroupSetBits (xEventGroup=0x3fca7428, uxBitsToSet=uxBitsToSet@entry=1) at /home/axel/esp/esp-idf/components/freertos/FreeRTOS-Kernel/event_groups.c:647
#3  0x4200ae48 in esp_mqtt_task (pv=0x3fca7224, pv@entry=<error reading variable: value has been optimized out>) at /home/axel/esp/esp-idf/components/mqtt/esp-mqtt/mqtt_client.c:1662
#4  0x40389140 in vPortTaskWrapper (pxCode=<optimized out>, pvParameters=<optimized out>) at /home/axel/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c:213
ELF file SHA256: c9e3b4816634def1

Rebooting...



@AxelLin
Copy link
Contributor Author

AxelLin commented Jul 26, 2023

@euripedesrocha
Can you reproduce the issue?
It's easy to observe the panic if you make the device running overnight with above modified example code.

@euripedesrocha
Copy link
Collaborator

euripedesrocha commented Jul 26, 2023

Hi @AxelLin I'm trying to reproduce. Just to be sure, you are using the esp-mqtt version pointed by IDF, right?

@AxelLin
Copy link
Contributor Author

AxelLin commented Jul 26, 2023

Hi @AxelLin I'm trying to reproduce. Just to be sure, you are using the esp-mqtt version pointed by IDF, right?

Yes, v5.2-dev-1709-g4fc2e5cb95.
I also hit this issue with current master: v5.2-dev-1805-g9a1cc59338.

@AxelLin
Copy link
Contributor Author

AxelLin commented Jul 28, 2023

@euripedesrocha

It's not clear to me about the meaning of unassignment by espressif-bot.
Maybe this is not mqtt specific issue and I just find a way to trigger the issue via mqtt.
Just wondering if you see the symptom now? Or any other information I need to provide?

@euripedesrocha
Copy link
Collaborator

@AxelLin I was able to reproduce the issue, but it's not related to the mqtt client. The issue was moved to the correct team and should have someone assigned soon.

@filzek
Copy link

filzek commented Aug 9, 2023

@euripedesrocha We have face some problens in the Mbed tls handshake in the past versions, it seens that this is realted to it or the lwip area, right?

@AxelLin
Copy link
Contributor Author

AxelLin commented Aug 14, 2023

Hi @Dazza0
How is the status of this issue?
I'd like to know the impact of this issue first since it's not mqtt specific problem.

@AxelLin
Copy link
Contributor Author

AxelLin commented Aug 15, 2023

@euripedesrocha We have face some problens in the Mbed tls handshake in the past versions, it seens that this is realted to it or the lwip area, right?

@filzek
Please create a new issue with your log and your esp-idf version.

@espressif-bot espressif-bot added Status: Done Issue is done internally Resolution: NA Issue resolution is unavailable and removed Status: Opened Issue is new labels Aug 16, 2023
@Dazza0
Copy link
Contributor

Dazza0 commented Aug 16, 2023

@AxelLin We've traced root cause of the issue as a race condition caused by non-thread safe task list access in vTaskRemoveFromUnorderedEventList(). This fix has already been internally merged to master and is currently waiting sync to GitHub.

In the mean time, if you want to give the fix a try, you can try applying the following patch on v5.2-dev-1709-g4fc2e5cb95:

Patch
From 436391aa88a43b546cffc6b6eda8971035c2d7bd Mon Sep 17 00:00:00 2001
From: Darian Leung <darian@espressif.com>
Date: Wed, 2 Aug 2023 12:27:54 +0200
Subject: [PATCH] fix(freertos): taskCAN_BE_SCHEDULED macro parenthesis

This commit adds missing parenthesis around the taskCAN_BE_SCHEDULED macro so
that it can properly used with a negation operator.

fix(freertos): Fix vTaskRemoveFromUnorderedEventList()

This commit fixes and optimizes vTaskRemoveFromUnorderedEventList() in the
following ways:

- Fixed bug in single core builds where the unblocked task would be placed on
xPendingReadyList.
    - If an ISR occurs while accessing xPendingReadyList, and the ISR also
      accesses the xPendingReadyList, xPendingReadyList would be corrupted.
    - In single core builds, this function is only called from event groups with
      the scheduler suspended. Thus the function should have exclusive access to
      pxReadyTasksLists instead of xPendingReadyList.
    - The function's single core logic has now been updated to match upstream
      behavior, by always placing the unblocked task on pxReadyTasksLists.

- Optimized the function for single core builds by removing the
taskCAN_BE_SCHEDULED() check.
    - In single core builds, given that the function is always called with the
      scheduler suspended
    - Thus, the taskCAN_BE_SCHEDULED (and the subsequent routine to place the
      unblocked task on the xPendingReadyList) is not necessary for single core
      builds.
    - The function now matches upstream behavior in single core builds.

Closes https://github.com/espressif/esp-idf/issues/11883

change(freertos): Optimized xTaskRemoveFromEventList()

This commit optimizes xTaskRemoveFromEventList() by removing the
listLIST_IS_EMPTY() check from single core builds. The scenario of the event
list being empty when the function is called can only occur on multi-core
builds.
---
 components/freertos/FreeRTOS-Kernel/tasks.c | 147 +++++++++++---------
 1 file changed, 78 insertions(+), 69 deletions(-)

diff --git a/components/freertos/FreeRTOS-Kernel/tasks.c b/components/freertos/FreeRTOS-Kernel/tasks.c
index 53e519a141..0da65a3a51 100644
--- a/components/freertos/FreeRTOS-Kernel/tasks.c
+++ b/components/freertos/FreeRTOS-Kernel/tasks.c
@@ -281,8 +281,8 @@
  */
 #if ( configNUM_CORES > 1 )
     #define taskCAN_BE_SCHEDULED( pxTCB )                                                                           \
-    ( ( pxTCB->xCoreID != tskNO_AFFINITY ) ) ? ( uxSchedulerSuspended[ pxTCB->xCoreID ] == ( UBaseType_t ) 0U ) :   \
-    ( ( uxSchedulerSuspended[ 0 ] == ( UBaseType_t ) 0U ) || ( uxSchedulerSuspended[ 1 ] == ( UBaseType_t ) 0U ) )
+    ( ( ( pxTCB->xCoreID != tskNO_AFFINITY ) ) ? ( uxSchedulerSuspended[ pxTCB->xCoreID ] == ( UBaseType_t ) 0U ) : \
+    ( ( uxSchedulerSuspended[ 0 ] == ( UBaseType_t ) 0U ) || ( uxSchedulerSuspended[ 1 ] == ( UBaseType_t ) 0U ) ) )
 #else
     #define taskCAN_BE_SCHEDULED( pxTCB )    ( ( uxSchedulerSuspended[ 0 ] == ( UBaseType_t ) 0U ) )
 #endif /* configNUM_CORES > 1 */
@@ -3919,23 +3919,31 @@ BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList )
         }
     #endif /* configNUM_CORES > 1 */
     {
-        /* Before taking the kernel lock, another task/ISR could have already
-         * emptied the pxEventList. So we insert a check here to see if
-         * pxEventList is empty before attempting to remove an item from it. */
-        if( listLIST_IS_EMPTY( pxEventList ) == pdFALSE )
+        /* The event list is sorted in priority order, so the first in the list can
+         * be removed as it is known to be the highest priority.  Remove the TCB from
+         * the delayed list, and add it to the ready list. */
+        #if ( configNUM_CORES > 1 )
+            /* Before taking the kernel lock, another task/ISR could have already
+             * emptied the pxEventList. So we insert a check here to see if
+             * pxEventList is empty before attempting to remove an item from it. */
+            if( listLIST_IS_EMPTY( pxEventList ) == pdTRUE )
+            {
+                /* The pxEventList was emptied before we entered the critical section,
+                * Nothing to do except return pdFALSE. */
+                xReturn = pdFALSE;
+            }
+            else
+        #else /* configNUM_CORES > 1 */
+            /* If an event is for a queue that is locked then this function will never
+            * get called - the lock count on the queue will get modified instead.  This
+            * means exclusive access to the event list is guaranteed here.
+            *
+            * This function assumes that a check has already been made to ensure that
+            * pxEventList is not empty. */
+        #endif /* configNUM_CORES > 1 */
         {
             BaseType_t xCurCoreID = xPortGetCoreID();
 
-            /* The event list is sorted in priority order, so the first in the list can
-             * be removed as it is known to be the highest priority.  Remove the TCB from
-             * the delayed list, and add it to the ready list.
-             *
-             * If an event is for a queue that is locked then this function will never
-             * get called - the lock count on the queue will get modified instead.  This
-             * means exclusive access to the event list is guaranteed here.
-             *
-             * This function assumes that a check has already been made to ensure that
-             * pxEventList is not empty. */
             pxUnblockedTCB = listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too.  Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */
             configASSERT( pxUnblockedTCB );
             ( void ) uxListRemove( &( pxUnblockedTCB->xEventListItem ) );
@@ -4000,12 +4008,6 @@ BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList )
                 xReturn = pdFALSE;
             }
         }
-        else
-        {
-            /* The pxEventList was emptied before we entered the critical section,
-             * Nothing to do except return pdFALSE. */
-            xReturn = pdFALSE;
-        }
     }
     #if ( configNUM_CORES > 1 )
         /* Release the previously taken kernel lock. */
@@ -4064,57 +4066,64 @@ void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem,
     configASSERT( pxUnblockedTCB );
     ( void ) uxListRemove( pxEventListItem );
 
-    /* Add the task to the ready list if a core with compatible affinity
-     * has NOT suspended its scheduler. This occurs when:
-     * - The task is pinned, and the pinned core's scheduler is running
-     * - The task is unpinned, and at least one of the core's scheduler is running */
-    if( taskCAN_BE_SCHEDULED( pxUnblockedTCB ) )
-    {
-        ( void ) uxListRemove( &( pxUnblockedTCB->xStateListItem ) );
-        prvAddTaskToReadyList( pxUnblockedTCB );
+    #if ( configUSE_TICKLESS_IDLE != 0 )
+        {
+            /* If a task is blocked on a kernel object then xNextTaskUnblockTime
+             * might be set to the blocked task's time out time.  If the task is
+             * unblocked for a reason other than a timeout xNextTaskUnblockTime is
+             * normally left unchanged, because it is automatically reset to a new
+             * value when the tick count equals xNextTaskUnblockTime.  However if
+             * tickless idling is used it might be more important to enter sleep mode
+             * at the earliest possible time - so reset xNextTaskUnblockTime here to
+             * ensure it is updated at the earliest possible time. */
+            prvResetNextTaskUnblockTime();
+        }
+    #endif
 
-        #if ( configUSE_TICKLESS_IDLE != 0 )
-            {
-                /* If a task is blocked on a kernel object then xNextTaskUnblockTime
-                 * might be set to the blocked task's time out time.  If the task is
-                 * unblocked for a reason other than a timeout xNextTaskUnblockTime is
-                 * normally left unchanged, because it is automatically reset to a new
-                 * value when the tick count equals xNextTaskUnblockTime.  However if
-                 * tickless idling is used it might be more important to enter sleep mode
-                 * at the earliest possible time - so reset xNextTaskUnblockTime here to
-                 * ensure it is updated at the earliest possible time. */
-                prvResetNextTaskUnblockTime();
-            }
-        #endif
-    }
-    else
-    {
-        /* We arrive here due to one of the following possibilities:
-         * - The task is pinned to core X and core X has suspended its scheduler
-         * - The task is unpinned and both cores have suspend their schedulers
-         * Therefore, we add the task to one of the pending lists:
-         * - If the task is pinned to core X, add it to core X's pending list
-         * - If the task is unpinned, add it to the current core's pending list */
-        BaseType_t xPendingListCore;
-        #if ( configNUM_CORES > 1 )
-            xPendingListCore = ( ( pxUnblockedTCB->xCoreID == tskNO_AFFINITY ) ? xCurCoreID : pxUnblockedTCB->xCoreID );
-        #else
-            xPendingListCore = 0;
-        #endif /* configNUM_CORES > 1 */
-        configASSERT( uxSchedulerSuspended[ xPendingListCore ] != ( UBaseType_t ) 0U );
+    #if ( configNUM_CORES > 1 )
 
-        /* The delayed and ready lists cannot be accessed, so hold this task
-         * pending until the scheduler is resumed. */
-        vListInsertEnd( &( xPendingReadyList[ xPendingListCore ] ), &( pxUnblockedTCB->xEventListItem ) );
-    }
+        /* Add the task to the ready list if a core with compatible affinity
+         * has NOT suspended its scheduler. This occurs when:
+         * - The task is pinned, and the pinned core's scheduler is running
+         * - The task is unpinned, and at least one of the core's scheduler is
+         *   running */
+        if( !taskCAN_BE_SCHEDULED( pxUnblockedTCB ) )
+        {
+            /* We arrive here due to one of the following possibilities:
+             * - The task is pinned to core X and core X has suspended its scheduler
+             * - The task is unpinned and both cores have suspend their schedulers
+             * Therefore, we add the task to one of the pending lists:
+             * - If the task is pinned to core X, add it to core X's pending list
+             * - If the task is unpinned, add it to the current core's pending list */
+            BaseType_t xPendingListCore = ( ( pxUnblockedTCB->xCoreID == tskNO_AFFINITY ) ? xCurCoreID : pxUnblockedTCB->xCoreID );
+            configASSERT( uxSchedulerSuspended[ xPendingListCore ] != ( UBaseType_t ) 0U );
+
+            /* The delayed and ready lists cannot be accessed, so hold this task
+            * pending until the scheduler is resumed. */
+            vListInsertEnd( &( xPendingReadyList[ xPendingListCore ] ), &( pxUnblockedTCB->xEventListItem ) );
+        }
+        else
+    #else /* configNUM_CORES > 1 */
 
-    if( prvCheckForYield( pxUnblockedTCB, xCurCoreID, pdFALSE ) )
+        /* In single core, the caller of this function has already suspended the
+         * scheduler, which means we have exclusive access to the ready list.
+         * We add the unblocked task to the ready list directly. */
+    #endif /* configNUM_CORES > 1 */
     {
-        /* The unblocked task has a priority above that of the calling task, so
-         * a context switch is required.  This function is called with the
-         * scheduler suspended so xYieldPending is set so the context switch
-         * occurs immediately that the scheduler is resumed (unsuspended). */
-        xYieldPending[ xCurCoreID ] = pdTRUE;
+        /* Remove the task from the delayed list and add it to the ready list.  The
+        * scheduler is suspended so interrupts will not be accessing the ready
+        * lists. */
+        ( void ) uxListRemove( &( pxUnblockedTCB->xStateListItem ) );
+        prvAddTaskToReadyList( pxUnblockedTCB );
+
+        if( prvCheckForYield( pxUnblockedTCB, xCurCoreID, pdFALSE ) )
+        {
+            /* The unblocked task has a priority above that of the calling task, so
+            * a context switch is required.  This function is called with the
+            * scheduler suspended so xYieldPending is set so the context switch
+            * occurs immediately that the scheduler is resumed (unsuspended). */
+            xYieldPending[ xCurCoreID ] = pdTRUE;
+        }
     }
 }
 /*-----------------------------------------------------------*/
-- 
2.25.1


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Type: Bug bugs in IDF
Projects
None yet
Development

No branches or pull requests

5 participants