mirror of
https://github.com/espressif/esp-idf.git
synced 2025-09-23 01:05:14 +00:00
spi_flash: fix race condition in s_flash_op_complete access
Flash operation complete flag was cleared by the core initiating flash operation. If the other core was running an ISR, then IPC task could be late to enter the loop to check s_flash_op_complete by the time next flash operation started. If the flag is cleared on the CPU waiting on this flag, then the race condition can not happen.
This commit is contained in:
@@ -69,9 +69,12 @@ void IRAM_ATTR spi_flash_op_block_func(void* arg)
|
||||
uint32_t cpuid = (uint32_t) arg;
|
||||
// Disable cache so that flash operation can start
|
||||
spi_flash_disable_cache(cpuid, &s_flash_op_cache_state[cpuid]);
|
||||
// s_flash_op_complete flag is cleared on *this* CPU, otherwise the other
|
||||
// CPU may reset the flag back to false before IPC task has a chance to check it
|
||||
// (if it is preempted by an ISR taking non-trivial amount of time)
|
||||
s_flash_op_complete = false;
|
||||
s_flash_op_can_start = true;
|
||||
while (!s_flash_op_complete) {
|
||||
// until we have a way to use interrupts for inter-CPU communication,
|
||||
// busy loop here and wait for the other CPU to finish flash operation
|
||||
}
|
||||
// Flash operation is complete, re-enable cache
|
||||
@@ -105,7 +108,6 @@ void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu()
|
||||
// Signal to the spi_flash_op_block_task on the other CPU that we need it to
|
||||
// disable cache there and block other tasks from executing.
|
||||
s_flash_op_can_start = false;
|
||||
s_flash_op_complete = false;
|
||||
esp_err_t ret = esp_ipc_call(other_cpuid, &spi_flash_op_block_func, (void*) other_cpuid);
|
||||
assert(ret == ESP_OK);
|
||||
while (!s_flash_op_can_start) {
|
||||
|
Reference in New Issue
Block a user