summaryrefslogtreecommitdiffstats
path: root/module/zfs
diff options
context:
space:
mode:
authorchrisrd <[email protected]>2017-09-30 08:49:19 +1000
committerBrian Behlendorf <[email protected]>2017-09-29 15:49:19 -0700
commite71cade67d48495db46fb6eed29b88b895bcb2d8 (patch)
tree27868fb2da175673cddc274967dcecd82f47f1de /module/zfs
parentb59b22972db5913000ca157c24a254182df8d957 (diff)
Scale the dbuf cache with arc_c
Commit d3c2ae1 introduced a dbuf cache with a default size of the minimum of 100M or 1/32 maximum ARC size. (These figures may be adjusted using dbuf_cache_max_bytes and dbuf_cache_max_shift.) The dbuf cache is counted as metadata for the purposes of ARC size calculations. On a 1GB box the ARC maximum size defaults to c_max 493M which gives a dbuf cache default minimum size of 15.4M, and the ARC metadata defaults to minimum 16M. I.e. the dbuf cache is an significant proportion of the minimum metadata size. With other overheads involved this actually means the ARC metadata doesn't get down to the minimum. This patch dynamically scales the dbuf cache to the target ARC size instead of statically scaling it to the maximum ARC size. (The scale is still set by dbuf_cache_max_shift and the maximum size is still fixed by dbuf_cache_max_bytes.) Using the target ARC size rather than the current ARC size is done to help the ARC reach the target rather than simply focusing on the current size. Reviewed-by: Chunwei Chen <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: George Melikov <[email protected]> Signed-off-by: Chris Dunlop <[email protected]> Issue #6506 Closes #6561
Diffstat (limited to 'module/zfs')
-rw-r--r--module/zfs/arc.c4
-rw-r--r--module/zfs/dbuf.c23
2 files changed, 19 insertions, 8 deletions
diff --git a/module/zfs/arc.c b/module/zfs/arc.c
index ed093fac1..3230a3d2e 100644
--- a/module/zfs/arc.c
+++ b/module/zfs/arc.c
@@ -7320,9 +7320,9 @@ arc_state_fini(void)
}
uint64_t
-arc_max_bytes(void)
+arc_target_bytes(void)
{
- return (arc_c_max);
+ return (arc_c);
}
void
diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c
index fb490ceda..1ea4c757e 100644
--- a/module/zfs/dbuf.c
+++ b/module/zfs/dbuf.c
@@ -463,24 +463,35 @@ dbuf_cache_multilist_index_func(multilist_t *ml, void *obj)
multilist_get_num_sublists(ml));
}
+static inline unsigned long
+dbuf_cache_target_bytes(void)
+{
+ return MIN(dbuf_cache_max_bytes,
+ arc_target_bytes() >> dbuf_cache_max_shift);
+}
+
static inline boolean_t
dbuf_cache_above_hiwater(void)
{
+ uint64_t dbuf_cache_target = dbuf_cache_target_bytes();
+
uint64_t dbuf_cache_hiwater_bytes =
- (dbuf_cache_max_bytes * dbuf_cache_hiwater_pct) / 100;
+ (dbuf_cache_target * dbuf_cache_hiwater_pct) / 100;
return (refcount_count(&dbuf_cache_size) >
- dbuf_cache_max_bytes + dbuf_cache_hiwater_bytes);
+ dbuf_cache_target + dbuf_cache_hiwater_bytes);
}
static inline boolean_t
dbuf_cache_above_lowater(void)
{
+ uint64_t dbuf_cache_target = dbuf_cache_target_bytes();
+
uint64_t dbuf_cache_lowater_bytes =
- (dbuf_cache_max_bytes * dbuf_cache_lowater_pct) / 100;
+ (dbuf_cache_target * dbuf_cache_lowater_pct) / 100;
return (refcount_count(&dbuf_cache_size) >
- dbuf_cache_max_bytes - dbuf_cache_lowater_bytes);
+ dbuf_cache_target - dbuf_cache_lowater_bytes);
}
/*
@@ -600,7 +611,7 @@ dbuf_evict_notify(void)
* because it's OK to occasionally make the wrong decision here,
* and grabbing the lock results in massive lock contention.
*/
- if (refcount_count(&dbuf_cache_size) > dbuf_cache_max_bytes) {
+ if (refcount_count(&dbuf_cache_size) > dbuf_cache_target_bytes()) {
if (dbuf_cache_above_hiwater())
dbuf_evict_one();
cv_signal(&dbuf_evict_cv);
@@ -657,7 +668,7 @@ retry:
* dbuf cache to 1/32nd (default) of the size of the ARC.
*/
dbuf_cache_max_bytes = MIN(dbuf_cache_max_bytes,
- arc_max_bytes() >> dbuf_cache_max_shift);
+ arc_target_bytes() >> dbuf_cache_max_shift);
/*
* All entries are queued via taskq_dispatch_ent(), so min/maxalloc