]> granicus.if.org Git - zfs/commitdiff
OpenZFS 9188 - increase size of dbuf cache to reduce indirect block decompression
authorBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 13 Mar 2018 17:52:48 +0000 (10:52 -0700)
committerGitHub <noreply@github.com>
Tue, 13 Mar 2018 17:52:48 +0000 (10:52 -0700)
With compressed ARC (bug 6950) we use up to 25% of our CPU to decompress
indirect blocks, under a workload of random cached reads. To reduce this
decompression cost, we would like to increase the size of the dbuf cache so
that more indirect blocks can be stored uncompressed.

If we are caching entire large files of recordsize=8K, the indirect blocks
use 1/64th as much memory as the data blocks (assuming they have the same
compression ratio). We suggest making the dbuf cache be 1/32nd of all memory,
so that in this scenario we should be able to keep all the indirect blocks
decompressed in the dbuf cache. (We want it to be more than the 1/64th that
the indirect blocks would use because we need to cache other stuff in the dbuf
cache as well.)

In real world workloads, this won't help as dramatically as the example above,
but we think it's still worth it because the risk of decreasing performance is
low. The potential negative performance impact is that we will be slightly
reducing the size of the ARC (by ~3%).

Porting Notes:
* Added modules options to zfs-module-parameters.5 man page.
* Preserved scaling based on target ARC size rather than max ARC size.

Authored by: George Wilson <george.wilson@delphix.com>
Reviewed by: Dan Kimmel <dan.kimmel@delphix.com>
Reviewed by: Prashanth Sreenivasa <pks@delphix.com>
Reviewed by: Paul Dagnelie <pcd@delphix.com>
Reviewed-by: Richard Elling <Richard.Elling@RichardElling.com>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
Ported-by: Brian Behlendorf <behlendorf1@llnl.gov>
OpenZFS-issue: https://www.illumos.org/issues/9188
OpenZFS-commit: https://github.com/openzfs/openzfs/pull/564
Upstream bug: DLPX-46942
Closes #7273

man/man5/zfs-module-parameters.5
module/zfs/dbuf.c

index 8515bf087435e66d2281770dbc2ce1e6e98a304a..f7db35b19e943a4eab9fcf50f28837e3e08b3a30 100644 (file)
@@ -25,6 +25,57 @@ Description of the different parameters to the ZFS module.
 .sp
 .LP
 
+.sp
+.ne 2
+.na
+\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.
+.sp
+Default value: \fB0\fR.
+.RE
+
+.sp
+.ne 2
+.na
+\fBdbuf_cache_hiwater_pct\fR (uint)
+.ad
+.RS 12n
+The percentage over \fBdbuf_cache_max_bytes\fR when dbufs must be evicted
+directly.
+.sp
+Default value: \fB10\fR%.
+.RE
+
+.sp
+.ne 2
+.na
+\fBdbuf_cache_lowater_pct\fR (uint)
+.ad
+.RS 12n
+The percentage below \fBdbuf_cache_max_bytes\fR when the evict thread stops
+evicting dbufs.
+.sp
+Default value: \fB10\fR%.
+.RE
+
+.sp
+.ne 2
+.na
+\fBdbuf_cache_shift\fR (int)
+.ad
+.RS 12n
+Set the size of the dbuf cache, \fBdbuf_cache_max_bytes\fR, to a log2 fraction
+of the target arc size.
+.sp
+Default value: \fB5\fR.
+.RE
+
 .sp
 .ne 2
 .na
index 51cb0c982f4991e2a852abc1e1c02d8c2eadd9fb..7e3f0a71329c9e7297aad48dd09f22c436ce0d20 100644 (file)
@@ -186,10 +186,10 @@ static boolean_t dbuf_evict_thread_exit;
  */
 static multilist_t *dbuf_cache;
 static refcount_t dbuf_cache_size;
-unsigned long  dbuf_cache_max_bytes = 100 * 1024 * 1024;
+unsigned long dbuf_cache_max_bytes = 0;
 
-/* Cap the size of the dbuf cache to log2 fraction of arc size. */
-int dbuf_cache_max_shift = 5;
+/* Set the default size of the dbuf cache to log2 fraction of arc size. */
+int dbuf_cache_shift = 5;
 
 /*
  * The dbuf cache uses a three-stage eviction policy:
@@ -561,7 +561,7 @@ static inline unsigned long
 dbuf_cache_target_bytes(void)
 {
        return MIN(dbuf_cache_max_bytes,
-           arc_target_bytes() >> dbuf_cache_max_shift);
+           arc_target_bytes() >> dbuf_cache_shift);
 }
 
 static inline uint64_t
@@ -787,11 +787,15 @@ retry:
        dbuf_stats_init(h);
 
        /*
-        * Setup the parameters for the dbuf cache. We cap the size of the
-        * dbuf cache to 1/32nd (default) of the size of the ARC.
+        * Setup the parameters for the dbuf cache. We set the size of the
+        * dbuf cache to 1/32nd (default) of the target size of the ARC. If
+        * the value has been specified as a module option and it's not
+        * greater than the target size of the ARC, then we honor that value.
         */
-       dbuf_cache_max_bytes = MIN(dbuf_cache_max_bytes,
-           arc_target_bytes() >> dbuf_cache_max_shift);
+       if (dbuf_cache_max_bytes == 0 ||
+           dbuf_cache_max_bytes >= arc_target_bytes()) {
+               dbuf_cache_max_bytes = arc_target_bytes() >> dbuf_cache_shift;
+       }
 
        /*
         * All entries are queued via taskq_dispatch_ent(), so min/maxalloc
@@ -4216,8 +4220,8 @@ MODULE_PARM_DESC(dbuf_cache_lowater_pct,
        "Percentage below dbuf_cache_max_bytes when the evict thread stops "
        "evicting dbufs.");
 
-module_param(dbuf_cache_max_shift, int, 0644);
-MODULE_PARM_DESC(dbuf_cache_max_shift,
-       "Cap the size of the dbuf cache to a log2 fraction of arc size.");
+module_param(dbuf_cache_shift, int, 0644);
+MODULE_PARM_DESC(dbuf_cache_shift,
+       "Set the size of the dbuf cache to a log2 fraction of arc size.");
 /* END CSTYLED */
 #endif