sleep: fix deadlock in esp_timer_impl_advance after light sleep

When light sleep is started, the other CPU gets halted using DPORT
stall mechanism. This can happen while it is inside an esp_timer
critical section, which may lead to a deadlock. This change adds
functions to take and release esp_timer lock before entering
DPORT critical section, preventing the deadlock.
This commit is contained in:
Ivan Grokhotkov
2018-05-04 12:50:39 +08:00
parent 296b280801
commit 8c307a5720
4 changed files with 60 additions and 0 deletions

View File

@@ -279,6 +279,11 @@ esp_err_t esp_light_sleep_start()
{
static portMUX_TYPE light_sleep_lock = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL(&light_sleep_lock);
/* We will be calling esp_timer_impl_advance inside DPORT access critical
* section. Make sure the code on the other CPU is not holding esp_timer
* lock, otherwise there will be deadlock.
*/
esp_timer_impl_lock();
s_config.rtc_ticks_at_sleep_start = rtc_time_get();
uint64_t frc_time_at_start = esp_timer_get_time();
DPORT_STALL_OTHER_CPU_START();
@@ -332,6 +337,7 @@ esp_err_t esp_light_sleep_start()
}
esp_set_time_from_rtc();
esp_timer_impl_unlock();
DPORT_STALL_OTHER_CPU_END();
rtc_wdt_disable();
portEXIT_CRITICAL(&light_sleep_lock);