Merge branch 'fix/fix_deepsleep_deadlock_if_threadsafe_claim_is_not_enabled_v6.1' into 'release/v6.1'

fix(esp_hw_support): fix deepsleep deadlock if threadsafe claim is not enabled (v6.1)

See merge request espressif/esp-idf!51197
This commit is contained in:
Jiang Jiang Jian
2026-09-20 14:11:36 +08:00
+15 -13
View File
@@ -1259,15 +1259,6 @@ static esp_err_t FORCE_IRAM_ATTR deep_sleep_start(bool allow_sleep_rejection)
esp_sync_timekeeping_timers(); esp_sync_timekeeping_timers();
// Must acquire all spinlocks which may be acquired during sleep process before stalling other core,
// otherwise deadlock may occur.
esp_os_enter_critical(&s_config.lock);
#if !CONFIG_FREERTOS_UNICORE
extern portMUX_TYPE rtc_spinlock;
esp_os_enter_critical_safe(&rtc_spinlock); // Maybe acquired from temp_sensor_get_raw_value by phy_close_rf callback
esp_clk_private_lock(); // Maybe acquired from esp_clk_slowclk_cal_set
#endif
#if CONFIG_ESP_INT_WDT && CONFIG_ESP32_ECO3_CACHE_LOCK_FIX #if CONFIG_ESP_INT_WDT && CONFIG_ESP32_ECO3_CACHE_LOCK_FIX
// The other core will be stalled by high-priority interrupt and spins on variables in internal RAM, // The other core will be stalled by high-priority interrupt and spins on variables in internal RAM,
// which naturally avoids cache livelock, so the 20ms livelock workaround timeout is not needed. // which naturally avoids cache livelock, so the 20ms livelock workaround timeout is not needed.
@@ -1275,10 +1266,25 @@ static esp_err_t FORCE_IRAM_ATTR deep_sleep_start(bool allow_sleep_rejection)
// esp_int_wdt_livelock_workaround, which may cause deadlock. // esp_int_wdt_livelock_workaround, which may cause deadlock.
esp_int_wdt_livelock_workaround(false); esp_int_wdt_livelock_workaround(false);
#endif #endif
/* Disable interrupts and stall another core in case another task writes /* Disable interrupts and stall another core in case another task writes
* to RTC memory while we calculate RTC memory CRC. * to RTC memory while we calculate RTC memory CRC.
*/ */
esp_os_enter_critical(&s_config.lock);
#if CONFIG_FREERTOS_PORT_THREAD_SAFE_CLAIM
esp_ipc_isr_stall_other_cpu(); esp_ipc_isr_stall_other_cpu();
#else
/* Retry with the lock held on success. Drop the lock on failure so the other
* CPU can leave its critical section (and to avoid deadlock on s_config.lock).
*/
while (esp_ipc_isr_stall_other_cpu_safe() != ESP_OK) {
esp_os_exit_critical(&s_config.lock);
esp_rom_delay_us(portTICK_PERIOD_MS * 1000 / 10);
esp_os_enter_critical(&s_config.lock);
}
#endif
esp_ipc_isr_stall_pause(); esp_ipc_isr_stall_pause();
// record current RTC time // record current RTC time
@@ -1368,10 +1374,6 @@ static esp_err_t FORCE_IRAM_ATTR deep_sleep_start(bool allow_sleep_rejection)
#if CONFIG_ESP_INT_WDT && CONFIG_ESP32_ECO3_CACHE_LOCK_FIX #if CONFIG_ESP_INT_WDT && CONFIG_ESP32_ECO3_CACHE_LOCK_FIX
// Configure WDT to use livelock workaround timeout after releasing other CPU // Configure WDT to use livelock workaround timeout after releasing other CPU
esp_int_wdt_livelock_workaround(true); esp_int_wdt_livelock_workaround(true);
#endif
#if !CONFIG_FREERTOS_UNICORE
esp_clk_private_unlock();
esp_os_exit_critical_safe(&rtc_spinlock);
#endif #endif
esp_os_exit_critical(&s_config.lock); esp_os_exit_critical(&s_config.lock);