From 89a8a91582fac11c5a433e18e4d4889ec81ff3d0 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 14 May 2025 10:34:14 -0400 Subject: [PATCH] ARC: Notify dbuf cache about target size reduction ARC target size might drop significantly under memory pressure, especially if current ARC size was much smaller than the target. Since dbuf cache size is a fraction of the target ARC size, it might need eviction too. Aside of memory from the dbuf eviction itself, it might help ARC by making more buffers evictable. Reviewed-by: Tony Hutter Reviewed-by: Ameer Hamza Signed-off-by: Alexander Motin Sponsored by: iXsystems, Inc. Closes #17314 --- include/sys/dbuf.h | 1 + module/zfs/arc.c | 8 ++++++++ module/zfs/dbuf.c | 13 +++++++++++++ 3 files changed, 22 insertions(+) diff --git a/include/sys/dbuf.h b/include/sys/dbuf.h index d3d47f7ba..756459b2f 100644 --- a/include/sys/dbuf.h +++ b/include/sys/dbuf.h @@ -435,6 +435,7 @@ int dbuf_dnode_findbp(dnode_t *dn, uint64_t level, uint64_t blkid, void dbuf_init(void); void dbuf_fini(void); +void dbuf_cache_reduce_target_size(void); boolean_t dbuf_is_metadata(dmu_buf_impl_t *db); diff --git a/module/zfs/arc.c b/module/zfs/arc.c index ddb5b2686..c4c6e37c5 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -297,6 +297,7 @@ #include #include #include +#include #include #include #include @@ -4555,6 +4556,13 @@ arc_reduce_target_size(uint64_t to_free) to_free = 0; } + /* + * Since dbuf cache size is a fraction of target ARC size, we should + * notify dbuf about the reduction, which might be significant, + * especially if current ARC size was much smaller than the target. + */ + dbuf_cache_reduce_target_size(); + /* * Whether or not we reduced the target size, request eviction if the * current size is over it now, since caller obviously wants some RAM. diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c index 81952af41..f94cfd726 100644 --- a/module/zfs/dbuf.c +++ b/module/zfs/dbuf.c @@ -872,6 +872,19 @@ dbuf_evict_notify(uint64_t size) } } +/* + * Since dbuf cache size is a fraction of target ARC size, ARC calls this when + * its target size is reduced due to memory pressure. + */ +void +dbuf_cache_reduce_target_size(void) +{ + uint64_t size = zfs_refcount_count(&dbuf_caches[DB_DBUF_CACHE].size); + + if (size > dbuf_cache_target_bytes()) + cv_signal(&dbuf_evict_cv); +} + static int dbuf_kstat_update(kstat_t *ksp, int rw) {