From 8348fac30c51564bf0c102aab35a54ca2dca50b4 Mon Sep 17 00:00:00 2001 From: Ryan Moeller Date: Fri, 24 Jul 2020 23:38:48 -0400 Subject: [PATCH] Limit dbuf cache sizes based only on ARC target size by default Set the initial max sizes to ULONG_MAX to allow the caches to grow with the ARC. Recalculate the metadata cache size on demand so it can adapt, too. Update descriptions in zfs-module-parameters(5). Reviewed-by: Alexander Motin Reviewed-by: Brian Behlendorf Reviewed-by: Matt Ahrens Signed-off-by: Ryan Moeller Closes #10563 Closes #10610 --- man/man5/zfs-module-parameters.5 | 22 +++++++-------- module/zfs/dbuf.c | 46 +++++++++++++++++--------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/man/man5/zfs-module-parameters.5 b/man/man5/zfs-module-parameters.5 index 3fbd3c67f8..c2abd9d805 100644 --- a/man/man5/zfs-module-parameters.5 +++ b/man/man5/zfs-module-parameters.5 @@ -32,13 +32,12 @@ Description of the different parameters to the ZFS module. \fBdbuf_cache_max_bytes\fR (ulong) .ad .RS 12n -Maximum size in bytes of the dbuf cache. When \fB0\fR this value will default -to \fB1/2^dbuf_cache_shift\fR (1/32) of the target ARC size, otherwise the -provided value in bytes will be used. The behavior of the dbuf cache and its -associated settings can be observed via the \fB/proc/spl/kstat/zfs/dbufstats\fR -kstat. +Maximum size in bytes of the dbuf cache. The target size is determined by the +MIN versus \fB1/2^dbuf_cache_shift\fR (1/32) of the target ARC size. The +behavior of the dbuf cache and its associated settings can be observed via the +\fB/proc/spl/kstat/zfs/dbufstats\fR kstat. .sp -Default value: \fB0\fR. +Default value: \fBULONG_MAX\fR. .RE .sp @@ -47,13 +46,12 @@ Default value: \fB0\fR. \fBdbuf_metadata_cache_max_bytes\fR (ulong) .ad .RS 12n -Maximum size in bytes of the metadata dbuf cache. When \fB0\fR this value will -default to \fB1/2^dbuf_cache_shift\fR (1/16) of the target ARC size, otherwise -the provided value in bytes will be used. The behavior of the metadata dbuf -cache and its associated settings can be observed via the -\fB/proc/spl/kstat/zfs/dbufstats\fR kstat. +Maximum size in bytes of the metadata dbuf cache. The target size is +determined by the MIN versus \fB1/2^dbuf_metadata_cache_shift\fR (1/64) of the +target ARC size. The behavior of the metadata dbuf cache and its associated +settings can be observed via the \fB/proc/spl/kstat/zfs/dbufstats\fR kstat. .sp -Default value: \fB0\fR. +Default value: \fBULONG_MAX\fR. .RE .sp diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c index 207d594396..aa44cc31e1 100644 --- a/module/zfs/dbuf.c +++ b/module/zfs/dbuf.c @@ -207,12 +207,16 @@ typedef struct dbuf_cache { dbuf_cache_t dbuf_caches[DB_CACHE_MAX]; /* Size limits for the caches */ -unsigned long dbuf_cache_max_bytes = 0; -unsigned long dbuf_metadata_cache_max_bytes = 0; +unsigned long dbuf_cache_max_bytes = ULONG_MAX; +unsigned long dbuf_metadata_cache_max_bytes = ULONG_MAX; + /* Set the default sizes of the caches to log2 fraction of arc size */ int dbuf_cache_shift = 5; int dbuf_metadata_cache_shift = 6; +static unsigned long dbuf_cache_target_bytes(void); +static unsigned long dbuf_metadata_cache_target_bytes(void); + /* * The LRU dbuf cache uses a three-stage eviction policy: * - A low water marker designates when the dbuf eviction thread @@ -432,7 +436,7 @@ dbuf_include_in_metadata_cache(dmu_buf_impl_t *db) */ if (zfs_refcount_count( &dbuf_caches[DB_DBUF_METADATA_CACHE].size) > - dbuf_metadata_cache_max_bytes) { + dbuf_metadata_cache_target_bytes()) { DBUF_STAT_BUMP(metadata_cache_overflow); return (B_FALSE); } @@ -610,11 +614,26 @@ dbuf_cache_multilist_index_func(multilist_t *ml, void *obj) multilist_get_num_sublists(ml)); } +/* + * The target size of the dbuf cache can grow with the ARC target, + * unless limited by the tunable dbuf_cache_max_bytes. + */ static inline unsigned long dbuf_cache_target_bytes(void) { - return MIN(dbuf_cache_max_bytes, - arc_target_bytes() >> dbuf_cache_shift); + return (MIN(dbuf_cache_max_bytes, + arc_target_bytes() >> dbuf_cache_shift)); +} + +/* + * The target size of the dbuf metadata cache can grow with the ARC target, + * unless limited by the tunable dbuf_metadata_cache_max_bytes. + */ +static inline unsigned long +dbuf_metadata_cache_target_bytes(void) +{ + return (MIN(dbuf_metadata_cache_max_bytes, + arc_target_bytes() >> dbuf_metadata_cache_shift)); } static inline uint64_t @@ -805,23 +824,6 @@ retry: dbuf_stats_init(h); - /* - * Setup the parameters for the dbuf caches. We set the sizes of the - * dbuf cache and the metadata cache to 1/32nd and 1/16th (default) - * of the target size of the ARC. If the values has been specified as - * a module option and they're not greater than the target size of the - * ARC, then we honor that value. - */ - if (dbuf_cache_max_bytes == 0 || - dbuf_cache_max_bytes >= arc_target_bytes()) { - dbuf_cache_max_bytes = arc_target_bytes() >> dbuf_cache_shift; - } - if (dbuf_metadata_cache_max_bytes == 0 || - dbuf_metadata_cache_max_bytes >= arc_target_bytes()) { - dbuf_metadata_cache_max_bytes = - arc_target_bytes() >> dbuf_metadata_cache_shift; - } - /* * All entries are queued via taskq_dispatch_ent(), so min/maxalloc * configuration is not required.