esp_system: Fix a race-condition in esp_ipc_isr (in QEMU env)

The race condition is very unlikely on real hardware but can be observed with
qemu under heavy load.
Also add missing `memw` instructions which are generated by the C compiler but
absent in the assembly code.

Signed-off-by: Paul Guyot <pguyot@kallisys.net>
Signed-off-by: KonstantinKondrashov <konstantin@espressif.com>

Merges https://github.com/espressif/esp-idf/pull/11447
Closes https://github.com/espressif/esp-idf/issues/11433
This commit is contained in:
Paul Guyot 2023-05-19 19:01:41 +02:00 committed by BOT
parent 4bc762621d
commit ee7554c1c4
3 changed files with 5 additions and 0 deletions

View File

@ -142,6 +142,8 @@ void IRAM_ATTR esp_ipc_isr_release_other_cpu(void)
const uint32_t cpu_id = xPortGetCoreID(); const uint32_t cpu_id = xPortGetCoreID();
if (--s_count_of_nested_calls[cpu_id] == 0) { if (--s_count_of_nested_calls[cpu_id] == 0) {
esp_ipc_isr_finish_cmd = 1; esp_ipc_isr_finish_cmd = 1;
// Make sure end flag is cleared and esp_ipc_isr_waiting_for_finish_cmd is done.
while (!esp_ipc_isr_end_fl) {};
IPC_ISR_EXIT_CRITICAL(); IPC_ISR_EXIT_CRITICAL();
#if CONFIG_FREERTOS_SMP #if CONFIG_FREERTOS_SMP
portRESTORE_INTERRUPTS(s_stored_interrupt_level); portRESTORE_INTERRUPTS(s_stored_interrupt_level);

View File

@ -96,6 +96,7 @@ esp_ipc_isr_handler:
/* set the start flag */ /* set the start flag */
movi a0, esp_ipc_isr_start_fl movi a0, esp_ipc_isr_start_fl
memw
s32i a0, a0, 0 s32i a0, a0, 0
/* Call the esp_ipc_function(void* arg) */ /* Call the esp_ipc_function(void* arg) */
@ -113,6 +114,7 @@ esp_ipc_isr_handler:
/* set the end flag */ /* set the end flag */
movi a0, esp_ipc_isr_end_fl movi a0, esp_ipc_isr_end_fl
memw
s32i a0, a0, 0 s32i a0, a0, 0
/* restore a0 */ /* restore a0 */

View File

@ -23,6 +23,7 @@
esp_ipc_isr_waiting_for_finish_cmd: esp_ipc_isr_waiting_for_finish_cmd:
/* waiting for the finish command */ /* waiting for the finish command */
.check_finish_cmd: .check_finish_cmd:
memw
l32i a3, a2, 0 l32i a3, a2, 0
beqz a3, .check_finish_cmd beqz a3, .check_finish_cmd
ret ret