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

ESP_jakob
Posts: 49
Joined: Mon Jun 01, 2020 6:28 am

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

Postby ESP_jakob » Thu Jun 04, 2020 10:25 am

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.

Charger
Posts: 8
Joined: Mon Jun 01, 2020 12:25 am
Location: Australia

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

Postby Charger » Fri Jun 05, 2020 12:16 am

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.

km-ids
Posts: 4
Joined: Thu May 16, 2019 1:40 pm

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

Postby km-ids » Thu Dec 10, 2020 2:37 pm

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

km-ids
Posts: 4
Joined: Thu May 16, 2019 1:40 pm

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

Postby km-ids » Thu Dec 10, 2020 3:14 pm

And,

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

Charger
Posts: 8
Joined: Mon Jun 01, 2020 12:25 am
Location: Australia

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

Postby Charger » Fri Dec 11, 2020 2:21 am

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.

taherrera
Posts: 4
Joined: Fri Feb 09, 2024 12:52 am

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

Postby taherrera » Fri Feb 09, 2024 1:13 am

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.

ESP_Sprite
Posts: 9772
Joined: Thu Nov 26, 2015 4:08 am

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

Postby ESP_Sprite » Fri Feb 09, 2024 2:25 am

Do you call nvs_commit and/or nvs_close after writing the value?

taherrera
Posts: 4
Joined: Fri Feb 09, 2024 12:52 am

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

Postby taherrera » Thu Jul 11, 2024 10:09 pm

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

taherrera
Posts: 4
Joined: Fri Feb 09, 2024 12:52 am

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

Postby taherrera » Thu Jul 11, 2024 10:28 pm

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.

Who is online

Users browsing this forum: No registered users and 82 guests