From 98865b7e6ac87ac31f813d7596a9d81f78ab2ee2 Mon Sep 17 00:00:00 2001 From: Nitin Singla Date: Mon, 1 Dec 2025 14:04:23 +0000 Subject: [PATCH 1/2] Flush early in of smaller writes. - If kernel cache disable application send smaller writes, try to flush early. --- turbonfs/inc/file_cache.h | 21 +++++++++++++++++++++ turbonfs/src/file_cache.cpp | 6 ++++++ 2 files changed, 27 insertions(+) diff --git a/turbonfs/inc/file_cache.h b/turbonfs/inc/file_cache.h index 12debd1f8..7d14c15a7 100644 --- a/turbonfs/inc/file_cache.h +++ b/turbonfs/inc/file_cache.h @@ -1603,6 +1603,25 @@ class bytes_chunk_cache const bool local_pressure = (bytes_dirty + bytes_commit_pending) > max_dirty_allowed_per_file; + /* + * In case of smaller writes, number of dirty membufs will be more + * than the dirty bytes. So we also check if number of dirty membufs + * exceed a threshold, which is derived from max dirty extent bytes. + * This will help in keep our byte cache map size under control. + * + * Note: Block size below 64KB consider as smaller writes for those, + * if we have more than 16 x (max_dirty_extent_bytes()/1MB) membufs + * dirty, we consider that as local pressure. + * f.e. max_dirty_extent_bytes() = 1GB cause 16K dirty membufs to + * trigger inline write. + */ + if (!local_pressure) { + static const uint64_t max_dirty_membufs_allowed_per_file = + (max_dirty_extent_bytes() * 16)/(1024 * 1024ULL); + local_pressure = num_dirty_membufs > + max_dirty_membufs_allowed_per_file; + } + /* * TODO: Add counter/stats for counting how many times we forced * inline write due to local and how many times due to global @@ -1772,6 +1791,7 @@ class bytes_chunk_cache std::atomic bytes_allocated = 0; std::atomic bytes_cached = 0; std::atomic bytes_dirty = 0; + std::atomic num_dirty_membufs = 0; std::atomic bytes_flushing = 0; std::atomic bytes_commit_pending = 0; std::atomic bytes_uptodate = 0; @@ -1791,6 +1811,7 @@ class bytes_chunk_cache static std::atomic bytes_allocated_g; static std::atomic bytes_cached_g; static std::atomic bytes_dirty_g; + static std::atomic num_dirty_membufs_g; static std::atomic bytes_flushing_g; static std::atomic bytes_commit_pending_g; static std::atomic bytes_uptodate_g; diff --git a/turbonfs/src/file_cache.cpp b/turbonfs/src/file_cache.cpp index e14d59593..b2f7ef5e1 100644 --- a/turbonfs/src/file_cache.cpp +++ b/turbonfs/src/file_cache.cpp @@ -795,6 +795,8 @@ void membuf::set_dirty() bcc->bytes_dirty_g += length; bcc->bytes_dirty += length; + bcc->num_dirty_membufs++; + bcc->num_dirty_membufs_g++; assert(bcc->bytes_dirty <= AZNFSC_MAX_FILE_SIZE); @@ -819,6 +821,10 @@ void membuf::clear_dirty() assert(bcc->bytes_dirty >= length); assert(bcc->bytes_dirty_g >= length); + assert(bcc->num_dirty_membufs > 0); + assert(bcc->num_dirty_membufs_g > 0); + bcc->num_dirty_membufs--; + bcc->num_dirty_membufs_g--; bcc->bytes_dirty -= length; bcc->bytes_dirty_g -= length; From 978abbf98d8b87d2a85be0735d2848405172f1c2 Mon Sep 17 00:00:00 2001 From: Nitin Singla Date: Mon, 1 Dec 2025 14:14:51 +0000 Subject: [PATCH 2/2] Build fix --- turbonfs/inc/file_cache.h | 2 +- turbonfs/src/file_cache.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/turbonfs/inc/file_cache.h b/turbonfs/inc/file_cache.h index 7d14c15a7..7a7c1c9e9 100644 --- a/turbonfs/inc/file_cache.h +++ b/turbonfs/inc/file_cache.h @@ -1600,7 +1600,7 @@ class bytes_chunk_cache */ static const uint64_t max_dirty_allowed_per_file = max_dirty_extent_bytes() * 4; - const bool local_pressure = + bool local_pressure = (bytes_dirty + bytes_commit_pending) > max_dirty_allowed_per_file; /* diff --git a/turbonfs/src/file_cache.cpp b/turbonfs/src/file_cache.cpp index b2f7ef5e1..a25d6c753 100644 --- a/turbonfs/src/file_cache.cpp +++ b/turbonfs/src/file_cache.cpp @@ -29,7 +29,6 @@ namespace aznfsc { /* static */ std::atomic bytes_chunk_cache::num_caches = 0; - /* static */ std::atomic bytes_chunk_cache::num_chunks_g = 0; /* static */ std::atomic bytes_chunk_cache::num_get_g = 0; /* static */ std::atomic bytes_chunk_cache::bytes_get_g = 0; @@ -40,6 +39,7 @@ namespace aznfsc { /* static */ std::atomic bytes_chunk_cache::bytes_allocated_g = 0; /* static */ std::atomic bytes_chunk_cache::bytes_cached_g = 0; /* static */ std::atomic bytes_chunk_cache::bytes_dirty_g = 0; +/* static */ std::atomic bytes_chunk_cache::num_dirty_membufs_g = 0; /* static */ std::atomic bytes_chunk_cache::bytes_flushing_g = 0; /* static */ std::atomic bytes_chunk_cache::bytes_commit_pending_g = 0; /* static */ std::atomic bytes_chunk_cache::bytes_uptodate_g = 0;