cpu/esp32: fix of a serious memory leak when using esp_wifi on ESP32-S3#21974
Merged
benpicco merged 3 commits intoRIOT-OS:masterfrom Jan 12, 2026
Merged
Conversation
Instead of using the ESP CPU family to conditionally define the number of processors used by FreeRTOS, SOC_CPU_NUM_CORES can be used directly, if it exists. Otherwise it is set to 1. Macros `xPortGetCoreID` and `xPortGetCoreID` are the same for all ESP CPU families.
RIOT generally uses only one CPU, and the second CPU, if there is one, is stalled by default. Defining portNUM_PROCESSORS here as 2 can cause problems. For example, the SYSTIMER counting units are stopped when the second CPU is disabled, which in turn leads to a memory leak because SYSTIMER is used for the esp_timer implementation to delete timers in thread context. Therefore, we define portNUM_PROCESSORS always as 1 even for ESP32x SOCs with 2 CPUs.
AnnsAnns
reviewed
Jan 9, 2026
Member
AnnsAnns
left a comment
There was a problem hiding this comment.
I looked into this and the documentation around the ESP for this and it does seem like a good way to tackle this considering that RIOT OS is currently purely single core. However, I currently don't have access to any hardware to test this so I don't want to be the one to approve this 😔 Ty for the fix though!
benpicco
approved these changes
Jan 12, 2026
Contributor
benpicco
left a comment
There was a problem hiding this comment.
Thank you for figuring this out!
e857713 to
680abd6
Compare
Contributor
Author
|
@benpicco Thanks. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Contribution description
This PR fixes a serious memory leak on ESP32-S3 and ESP32-S2.
When investigating the problem described in issue #21923, I realized coincidentally that
esp_wificauses a serious memory leak on ESP32-S3 and ESP32-S2 that is related to theSYSTIMERperipheral.Background
The implementation of the ESP-IDF module
esp_wifiuses the ESP-IDF moduleesp_timerto track the PLL of the WiFi modem when the PHY layer is briefly enabled and disabled again at regular intervals. To do this, it starts a timer when the PHY layer is enabled and stops the timer when the PHY layer is disabled again.To prevent the corresponding timer object from being deleted when the timer is stopped in ISR context, the timer object is not deleted directly when the timer is stopped, but is added to a list of timer objects to be deleted. The timer objects in this list should then be deleted by the
esp_wifitask in the thread context. To be executed periodically,esp_wifitask uses theSYSTIMERperipheral on ESP32x SoCs with the exception of ESP32.On multi-core SoCs however, this
SYSTIMERperipheral is stalled if one of the CPUs is stalled. Since RIOT generally uses only one CPU, theSYSTIMERperipheral doesn't work in RIOT. As a result, theesp_wifitask never executed and the timer objects are never deleted. This causes a serious memory leak on ESP32-S3 because the list of timer objects to be deleted grows rapidly within a couple of seconds.Defining
portNUM_PROCESSORSalways as 1 (which reflects the reality) solves this problem because stalling theSYSTIMERperipheral when the second CPU is stalled isn't enabled in this case.As a side effect it also solves the same memory leak on ESP32-S2 even though it is a single-core SoC.
All other ESP32x SoC didn't have this problem.
Testing procedure
Compile and flash the networking example with
heapcommand for ESP32-S3 and ESP32-S2:Without PR, the allocated memory increases by several hundred bytes every second.
With PR, the allocated memory should stabilize after a few seconds and only increase or decrease slightly.
Issues/PRs references