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 <hutter2@llnl.gov>
Reviewed-by: Ameer Hamza <ahamza@ixsystems.com>
Signed-off-by:	Alexander Motin <mav@FreeBSD.org>
Sponsored by:	iXsystems, Inc.
Closes #17314
This commit is contained in:
Alexander Motin 2025-05-14 10:34:14 -04:00 committed by GitHub
parent 0aa83dce99
commit 89a8a91582
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 22 additions and 0 deletions

View File

@ -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);

View File

@ -297,6 +297,7 @@
#include <sys/dsl_pool.h>
#include <sys/multilist.h>
#include <sys/abd.h>
#include <sys/dbuf.h>
#include <sys/zil.h>
#include <sys/fm/fs/zfs.h>
#include <sys/callb.h>
@ -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.

View File

@ -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)
{