Page 2 of 2

Re: [SOLVED] ESP_ERR_NVS_NOT_FOUND from nvs_get_blob() due to nvs_commit() race condition

Posted: Thu Jun 04, 2020 10:25 am
by jakob
Oh, I'm looking at the code just now, sorry.
Actually there shouldn't be a race condition like this.

Code: Select all

nvs_set_blob()
should finish everything before returning. NVS is supposed to be thread safe.

Re: [SOLVED] ESP_ERR_NVS_NOT_FOUND from nvs_get_blob() due to nvs_commit() race condition

Posted: Fri Jun 05, 2020 12:16 am
by Charger
Yes, we're using FreeRTOS. But the commit and then changing the variable happen in the same thread, so I thought the nvs_commit() at least would be synchronous and act as a write barrier.

However, there is the following comment for spi_flash_write_inner(), which nvs_set_blob() eventually calls:

Code: Select all

/* Wrapper around esp_rom_spiflash_write() that verifies data as written if CONFIG_SPI_FLASH_VERIFY_WRITE is set.

   If CONFIG_SPI_FLASH_VERIFY_WRITE is not set, this is esp_rom_spiflash_write().
*/
We do not have CONFIG_SPI_FLASH_VERIFY_WRITE set. And I guess the SPI write itself is set up using DMA. That could allow the NVS operations to return before the flash write has completed (in fact, many cycles before, if the blob is large). If so, I agree the documentation would benefit from explaining this.

Re: [SOLVED] ESP_ERR_NVS_NOT_FOUND from nvs_get_blob() due to nvs_commit() race condition

Posted: Thu Dec 10, 2020 2:37 pm
by km-ids
Hi,

Was the result of the above post (Thu Jun 04, 2020 8:30 am) indicating that the nvs commit and close may return before the data is actually written?
which can lead to changes of the source data following the commit & close may get captured by the write operation?

Thanks

Re: [SOLVED] ESP_ERR_NVS_NOT_FOUND from nvs_get_blob() due to nvs_commit() race condition

Posted: Thu Dec 10, 2020 3:14 pm
by km-ids
And,

If so, is the solution for this having the build flag CONFIG_SPI_FLASH_VERIFY_WRITE set?

Re: [SOLVED] ESP_ERR_NVS_NOT_FOUND from nvs_get_blob() due to nvs_commit() race condition

Posted: Fri Dec 11, 2020 2:21 am
by Charger
Yes, the nvs_close() returned before all the data were even read from RAM (read for writing to flash ... they had already been read before for calculating the checksum).

I didn't try setting CONFIG_SPI_FLASH_VERIFY_WRITE. What I did instead was break up the blob (which was a hangover from a previous implementation) into native key:value pairs. But in theory, if you are writing large strings/blobs, CONFIG_SPI_FLASH_VERIFY_WRITE will fix this problem.

Re: [SOLVED] ESP_ERR_NVS_NOT_FOUND from nvs_get_blob() due to nvs_commit() race condition

Posted: Fri Feb 09, 2024 1:13 am
by taherrera
Hello,

I think I am having this same issue. ESP_ERR_NVS_NOT_FOUND was happening to me because I was calling esp_reset() just after a write to the nvs. I am writing 1064 bytes using nvs_set_blob in a 0x14000 size unencrypted nvs partition with a single blob_key.

I tried using CONFIG_SPI_FLASH_VERIFY_WRITE but this did not help. What I basically did was add a vTaskDelay of 5 seconds and it seemed to resolve the problem, however, since I do not want this to happen ever, I used a 10 second delay before calling esp_reset().

Is there a better way than a delay that some one could hint?

I am using release 4.4

Hopes it helps somebody.

Re: [SOLVED] ESP_ERR_NVS_NOT_FOUND from nvs_get_blob() due to nvs_commit() race condition

Posted: Fri Feb 09, 2024 2:25 am
by Sprite
Do you call nvs_commit and/or nvs_close after writing the value?

Re: [SOLVED] ESP_ERR_NVS_NOT_FOUND from nvs_get_blob() due to nvs_commit() race condition

Posted: Thu Jul 11, 2024 10:09 pm
by taherrera
I save in the NVS by doing:

esp_err_t err = nvs_set_blob(Storage, save_key, tosave, save_size);
and immediately after:
err = nvs_commit(Storage);

But I dont call nvs_close

Re: [SOLVED] ESP_ERR_NVS_NOT_FOUND from nvs_get_blob() due to nvs_commit() race condition

Posted: Thu Jul 11, 2024 10:28 pm
by taherrera
This is the function I use to store:

Code: Select all

int storage_write(uint8_t * tosave, size_t save_size){
  nvs_handle_t NvsHandle;
  const char * save_key = "AGT";

  console_printf("[I] storage.c storage_write: Saving \"%s\"\n", save_key);

  esp_err_t err = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &NvsHandle);
  if (err != ESP_OK) {
    console_printf("[E] storage.c storage_write: Error opening: (%s)\n", esp_err_to_name(err));
    nvs_close(NvsHandle);
    return err;
  }

  err = nvs_set_blob(NvsHandle, save_key, tosave, save_size);
  if (err != ESP_OK) {
    console_printf("[E] storage.c storage_write: Error writing: %s\n", esp_err_to_name(err));
    nvs_close(NvsHandle);
    return err;
  }

  err = nvs_commit(NvsHandle);
  if (err != ESP_OK) {
    console_printf("[E] storage.c storage_write: Error commit: %s\n", esp_err_to_name(err));
    nvs_close(NvsHandle);
    return err;
  }

  //vTaskDelay(10000/ portTICK_PERIOD_MS); // for big blobs, this is necesary..

  nvs_close(NvsHandle);
  return 0;
}
However if I do esp_restart() after running this function I get ESP_ERR_NVS_NOT_FOUND . If I wait say, 10 seconds or so before restarting, I dont get the issue.

Re: [SOLVED] ESP_ERR_NVS_NOT_FOUND from nvs_get_blob() due to nvs_commit() race condition

Posted: Tue Dec 03, 2024 1:22 pm
by ESP_rrtandler
Hi taherrera,

I tried to replicate the immediate reset after a blob write on the current master branch using the ESP32 WROOM module with 4MB flash, but the 'not found' error didn't occur in this case. Could you please provide details on the hardware you were using?