zms: optimize write function by skipping unnecessary reads

when performing a write ZMS checks if the data exists in the storage to
avoid double writing the same data and save some memory cycle life time.
However this downgrades the write performance.
Enable this feature only when CONFIG_ZMS_NO_DOUBLE_WRITE is enabled.

Signed-off-by: Riadh Ghaddab <rghaddab@baylibre.com>
This commit is contained in:
Riadh Ghaddab 2024-12-05 13:29:17 +01:00 committed by Benjamin Cabé
parent 4b086612cc
commit e0f0256538
3 changed files with 18 additions and 6 deletions

View file

@ -50,6 +50,15 @@ config ZMS_CUSTOM_BLOCK_SIZE
help
Changes the internal buffer size of ZMS
config ZMS_NO_DOUBLE_WRITE
bool "Avoid writing the same data again in the storage"
help
For some memory technologies, write cycles for memory cells are limited and any
unncessary writes should be avoided.
Enable this config to avoid rewriting data in the storage if it already exists.
This option will reduce write performance as it will need to do a research of the
data in the whole storage before any write.
module = ZMS
module-str = zms
source "subsys/logging/Kconfig.template.log_config"

View file

@ -1392,12 +1392,10 @@ ssize_t zms_write(struct zms_fs *fs, uint32_t id, const void *data, size_t len)
{
int rc;
size_t data_size;
struct zms_ate wlk_ate;
uint64_t wlk_addr;
uint64_t rd_addr;
uint32_t gc_count;
uint32_t required_space = 0U; /* no space, appropriate for delete ate */
int prev_found = 0;
if (!fs->ready) {
LOG_ERR("zms not initialized");
@ -1428,15 +1426,14 @@ ssize_t zms_write(struct zms_fs *fs, uint32_t id, const void *data, size_t len)
#endif
rd_addr = wlk_addr;
#ifdef CONFIG_ZMS_NO_DOUBLE_WRITE
/* Search for a previous valid ATE with the same ID */
prev_found = zms_find_ate_with_id(fs, id, wlk_addr, fs->ate_wra, &wlk_ate, &rd_addr);
struct zms_ate wlk_ate;
int prev_found = zms_find_ate_with_id(fs, id, wlk_addr, fs->ate_wra, &wlk_ate, &rd_addr);
if (prev_found < 0) {
return prev_found;
}
#ifdef CONFIG_ZMS_LOOKUP_CACHE
no_cached_entry:
#endif
if (prev_found) {
/* previous entry found */
if (len > ZMS_DATA_IN_ATE_SIZE) {
@ -1473,7 +1470,11 @@ no_cached_entry:
return 0;
}
}
#endif
#ifdef CONFIG_ZMS_LOOKUP_CACHE
no_cached_entry:
#endif
/* calculate required space if the entry contains data */
if (data_size) {
/* Leave space for delete ate */

View file

@ -545,6 +545,7 @@ ZTEST_F(zms, test_delete)
ate_wra = fixture->fs.ate_wra;
data_wra = fixture->fs.data_wra;
#ifdef CONFIG_ZMS_NO_DOUBLE_WRITE
/* delete already deleted entry */
err = zms_delete(&fixture->fs, 1);
zassert_true(err == 0, "zms_delete call failure: %d", err);
@ -558,6 +559,7 @@ ZTEST_F(zms, test_delete)
zassert_true(ate_wra == fixture->fs.ate_wra && data_wra == fixture->fs.data_wra,
"delete nonexistent entry should not make"
" any footprint in the storage");
#endif
}
/*