From 88bc3335599bc4d4655cde38b4965099ec28ce00 Mon Sep 17 00:00:00 2001 From: WeiXiong Liao Date: Fri, 21 Feb 2020 16:22:52 +0800 Subject: [PATCH] Support no validation to improve write performance It can improve write performance if no validation, but drivers must ensure data integrity. I test lfs on spinand with NFTL. The spinand has 128M capacity with 2K page size and 128K block size. The actually page size changes to 4K on my using NFTL. And lfs is configured as follows: .read_size = 4096 .write_szie = 4096 .block_szie = 4096 .block_count = 25680 .block_cycles = -1 .lookahead_size = 256 The performance on raw device without littlefs: read average speed: 14361.85 KB/s write average speed: 2994.74 KB/s The performance on lfs with validation as follow: read average speed: 12094.49 KB/s write average speed: 2074.97 KB/s The performance on lfs without validation as follow: read average speed: 12427.18 KB/s write average speed: 2674.33 KB/s It really improves 600 KB/s to write if disable validation. To me, the NFTL has ensure data integrity, there is no need to validate again on lfs. It is also helpfull to flash like MMC. --- lfs.c | 6 +++--- lfs.h | 9 ++++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/lfs.c b/lfs.c index 4553a6ed..ca8f3f0a 100644 --- a/lfs.c +++ b/lfs.c @@ -133,7 +133,7 @@ static int lfs_bd_flush(lfs_t *lfs, return err; } - if (validate) { + if (lfs->cfg->validate >= 0 && validate) { // check data on disk lfs_cache_drop(lfs, rcache); int res = lfs_bd_cmp(lfs, @@ -3593,14 +3593,14 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { ".lookahead_size=%"PRIu32", .read_buffer=%p, " ".prog_buffer=%p, .lookahead_buffer=%p, " ".name_max=%"PRIu32", .file_max=%"PRIu32", " - ".attr_max=%"PRIu32"})", + ".attr_max=%"PRIu32", .validate=%"PRIu32"})", (void*)lfs, (void*)cfg, cfg->context, (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog, (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count, cfg->block_cycles, cfg->cache_size, cfg->lookahead_size, cfg->read_buffer, cfg->prog_buffer, cfg->lookahead_buffer, - cfg->name_max, cfg->file_max, cfg->attr_max); + cfg->name_max, cfg->file_max, cfg->attr_max, cfg->validate); int err = lfs_init(lfs, cfg); if (err) { LFS_TRACE("lfs_mount -> %d", err); diff --git a/lfs.h b/lfs.h index 04054e91..8e31138f 100644 --- a/lfs.h +++ b/lfs.h @@ -32,7 +32,6 @@ extern "C" #define LFS_DISK_VERSION_MAJOR (0xffff & (LFS_DISK_VERSION >> 16)) #define LFS_DISK_VERSION_MINOR (0xffff & (LFS_DISK_VERSION >> 0)) - /// Definitions /// // Type definitions @@ -240,6 +239,14 @@ struct lfs_config { // larger attributes size but must be <= LFS_ATTR_MAX. Defaults to // LFS_ATTR_MAX when zero. lfs_size_t attr_max; + + // Whether read and validate after writing. The positive number means + // enable while the negative number means disable. The zero means + // enable for compatible. It can imporve write performance if no + // validation, but drivers must ensure data integrity. + int validate; +#define LFS_ENABLE_VALIDATE 1 +#define LFS_DISABLE_VALIDATE -1 }; // File info structure