Skip to content

Commit

Permalink
Limit dbuf cache sizes based only on ARC target size by default
Browse files Browse the repository at this point in the history
Fixes openzfs#10563

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.

Signed-off-by: Ryan Moeller <[email protected]>
  • Loading branch information
Ryan Moeller authored and Ryan Moeller committed Jul 23, 2020
1 parent 77ba69b commit 8ac0ed4
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 34 deletions.
1 change: 1 addition & 0 deletions include/sys/arc_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <sys/zio_crypt.h>
#include <sys/zthr.h>
#include <sys/aggsum.h>
#include <sys/multilist.h>

#ifdef __cplusplus
extern "C" {
Expand Down
22 changes: 10 additions & 12 deletions man/man5/zfs-module-parameters.5
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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_cache_shift\fR (1/16) 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
Expand Down
39 changes: 17 additions & 22 deletions module/zfs/dbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include <sys/zfs_context.h>
#include <sys/arc.h>
#include <sys/arc_impl.h>
#include <sys/dmu.h>
#include <sys/dmu_send.h>
#include <sys/dmu_impl.h>
Expand Down Expand Up @@ -241,12 +242,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
Expand Down Expand Up @@ -466,7 +471,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);
}
Expand Down Expand Up @@ -647,8 +652,15 @@ dbuf_cache_multilist_index_func(multilist_t *ml, void *obj)
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));
}

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
Expand Down Expand Up @@ -878,23 +890,6 @@ dbuf_init(void)

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.
Expand Down

0 comments on commit 8ac0ed4

Please sign in to comment.