From e0f0256538b1b7c2544d4479d3f68722e41ccb1a Mon Sep 17 00:00:00 2001 From: Riadh Ghaddab Date: Thu, 5 Dec 2024 13:29:17 +0100 Subject: [PATCH] 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 --- subsys/fs/zms/Kconfig | 9 +++++++++ subsys/fs/zms/zms.c | 13 +++++++------ tests/subsys/fs/zms/src/main.c | 2 ++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/subsys/fs/zms/Kconfig b/subsys/fs/zms/Kconfig index dd3c5a184e1..781da81bf0a 100644 --- a/subsys/fs/zms/Kconfig +++ b/subsys/fs/zms/Kconfig @@ -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" diff --git a/subsys/fs/zms/zms.c b/subsys/fs/zms/zms.c index e00506dec4b..0e5ca1e5f3b 100644 --- a/subsys/fs/zms/zms.c +++ b/subsys/fs/zms/zms.c @@ -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 */ diff --git a/tests/subsys/fs/zms/src/main.c b/tests/subsys/fs/zms/src/main.c index bd4e21dd745..500ad758d68 100644 --- a/tests/subsys/fs/zms/src/main.c +++ b/tests/subsys/fs/zms/src/main.c @@ -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 } /*