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:
parent
4b086612cc
commit
e0f0256538
3 changed files with 18 additions and 6 deletions
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue