]> granicus.if.org Git - zfs/commitdiff
zfs_arc_num_sublists_per_state should be common to all multilists
authorMatthew Ahrens <mahrens@delphix.com>
Wed, 15 Feb 2017 23:49:33 +0000 (15:49 -0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 15 Feb 2017 23:49:33 +0000 (15:49 -0800)
The global tunable zfs_arc_num_sublists_per_state is used by the ARC and
the dbuf cache, and other users are planned. We should change this
tunable to be common to all multilists.  This tuning may be overridden
on a per-multilist basis.

Reviewed-by: Pavel Zakharov <pavel.zakharov@delphix.com>
Reviewed-by: Dan Kimmel <dan.kimmel@delphix.com>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Matthew Ahrens <mahrens@delphix.com>
Closes #5764

include/sys/arc.h
include/sys/multilist.h
man/man5/zfs-module-parameters.5
module/zfs/arc.c
module/zfs/dbuf.c
module/zfs/multilist.c

index e1422d2e10518c6aebbc3d5b351238bbe546da4c..07a72302df7b19c6b89005e692706cb8f02d0f50 100644 (file)
@@ -70,8 +70,6 @@ extern int zfs_arc_average_blocksize;
 arc_done_func_t arc_bcopy_func;
 arc_done_func_t arc_getbuf_func;
 
-extern int zfs_arc_num_sublists_per_state;
-
 /* generic arc_prune_func_t wrapper for callbacks */
 struct arc_prune {
        arc_prune_func_t        *p_pfunc;
index 98d707dd71efe5f018e91992018b9d69fe49e7fd..9b19d016d971dd187dc8ec2fad85b411723c9dae 100644 (file)
@@ -13,7 +13,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright (c) 2013, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2013, 2017 by Delphix. All rights reserved.
  */
 
 #ifndef        _SYS_MULTILIST_H
@@ -72,7 +72,7 @@ struct multilist {
 };
 
 void multilist_destroy(multilist_t *);
-void multilist_create(multilist_t *, size_t, size_t, unsigned int,
+void multilist_create(multilist_t *, size_t, size_t,
     multilist_sublist_index_func_t *);
 
 void multilist_insert(multilist_t *, void *);
index b1c99cb17cc5e5d4d2598844cafdd2acc4a15e80..ca92af5511fad79d003da09e820781ad91f719a3 100644 (file)
@@ -622,15 +622,16 @@ Default value: \fB0\fR.
 .sp
 .ne 2
 .na
-\fBzfs_arc_num_sublists_per_state\fR (int)
+\fBzfs_multilist_num_sublists\fR (int)
 .ad
 .RS 12n
 To allow more fine-grained locking, each ARC state contains a series
 of lists for both data and meta data objects.  Locking is performed at
 the level of these "sub-lists".  This parameters controls the number of
-sub-lists per ARC state.
+sub-lists per ARC state, and also applies to other uses of the
+multilist data structure.
 .sp
-Default value: \fB1\fR or the number of online CPUs, whichever is greater
+Default value: \fB4\fR or the number of online CPUs, whichever is greater
 .RE
 
 .sp
index 1495b0891fe4f6a400f1c6c1220834ee6d767903..9fac5a6c42cffe21667196a1cf3b51f98e12f01e 100644 (file)
@@ -21,7 +21,7 @@
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
- * Copyright (c) 2011, 2016 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
  * Copyright (c) 2014 by Saso Kiselkov. All rights reserved.
  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  */
@@ -307,13 +307,6 @@ static kcondvar_t  arc_reclaim_waiters_cv;
  */
 int zfs_arc_evict_batch_limit = 10;
 
-/*
- * The number of sublists used for each of the arc state lists. If this
- * is not set to a suitable value by the user, it will be configured to
- * the number of CPUs on the system in arc_init().
- */
-int zfs_arc_num_sublists_per_state = 0;
-
 /* number of seconds before growing cache again */
 static int             arc_grow_retry = 5;
 
@@ -6285,43 +6278,43 @@ arc_state_init(void)
        multilist_create(&arc_mru->arcs_list[ARC_BUFC_METADATA],
            sizeof (arc_buf_hdr_t),
            offsetof(arc_buf_hdr_t, b_l1hdr.b_arc_node),
-           zfs_arc_num_sublists_per_state, arc_state_multilist_index_func);
+           arc_state_multilist_index_func);
        multilist_create(&arc_mru->arcs_list[ARC_BUFC_DATA],
            sizeof (arc_buf_hdr_t),
            offsetof(arc_buf_hdr_t, b_l1hdr.b_arc_node),
-           zfs_arc_num_sublists_per_state, arc_state_multilist_index_func);
+           arc_state_multilist_index_func);
        multilist_create(&arc_mru_ghost->arcs_list[ARC_BUFC_METADATA],
            sizeof (arc_buf_hdr_t),
            offsetof(arc_buf_hdr_t, b_l1hdr.b_arc_node),
-           zfs_arc_num_sublists_per_state, arc_state_multilist_index_func);
+           arc_state_multilist_index_func);
        multilist_create(&arc_mru_ghost->arcs_list[ARC_BUFC_DATA],
            sizeof (arc_buf_hdr_t),
            offsetof(arc_buf_hdr_t, b_l1hdr.b_arc_node),
-           zfs_arc_num_sublists_per_state, arc_state_multilist_index_func);
+           arc_state_multilist_index_func);
        multilist_create(&arc_mfu->arcs_list[ARC_BUFC_METADATA],
            sizeof (arc_buf_hdr_t),
            offsetof(arc_buf_hdr_t, b_l1hdr.b_arc_node),
-           zfs_arc_num_sublists_per_state, arc_state_multilist_index_func);
+           arc_state_multilist_index_func);
        multilist_create(&arc_mfu->arcs_list[ARC_BUFC_DATA],
            sizeof (arc_buf_hdr_t),
            offsetof(arc_buf_hdr_t, b_l1hdr.b_arc_node),
-           zfs_arc_num_sublists_per_state, arc_state_multilist_index_func);
+           arc_state_multilist_index_func);
        multilist_create(&arc_mfu_ghost->arcs_list[ARC_BUFC_METADATA],
            sizeof (arc_buf_hdr_t),
            offsetof(arc_buf_hdr_t, b_l1hdr.b_arc_node),
-           zfs_arc_num_sublists_per_state, arc_state_multilist_index_func);
+           arc_state_multilist_index_func);
        multilist_create(&arc_mfu_ghost->arcs_list[ARC_BUFC_DATA],
            sizeof (arc_buf_hdr_t),
            offsetof(arc_buf_hdr_t, b_l1hdr.b_arc_node),
-           zfs_arc_num_sublists_per_state, arc_state_multilist_index_func);
+           arc_state_multilist_index_func);
        multilist_create(&arc_l2c_only->arcs_list[ARC_BUFC_METADATA],
            sizeof (arc_buf_hdr_t),
            offsetof(arc_buf_hdr_t, b_l1hdr.b_arc_node),
-           zfs_arc_num_sublists_per_state, arc_state_multilist_index_func);
+           arc_state_multilist_index_func);
        multilist_create(&arc_l2c_only->arcs_list[ARC_BUFC_DATA],
            sizeof (arc_buf_hdr_t),
            offsetof(arc_buf_hdr_t, b_l1hdr.b_arc_node),
-           zfs_arc_num_sublists_per_state, arc_state_multilist_index_func);
+           arc_state_multilist_index_func);
 
        refcount_create(&arc_anon->arcs_esize[ARC_BUFC_METADATA]);
        refcount_create(&arc_anon->arcs_esize[ARC_BUFC_DATA]);
@@ -6452,9 +6445,6 @@ arc_init(void)
        /* Apply user specified tunings */
        arc_tuning_update();
 
-       if (zfs_arc_num_sublists_per_state < 1)
-               zfs_arc_num_sublists_per_state = MAX(boot_ncpus, 1);
-
        /* if kmem_flags are set, lets try to use less memory */
        if (kmem_debugging())
                arc_c = arc_c / 2;
@@ -7745,10 +7735,6 @@ MODULE_PARM_DESC(zfs_compressed_arc_enabled, "Disable compressed arc buffers");
 module_param(zfs_arc_min_prefetch_lifespan, int, 0644);
 MODULE_PARM_DESC(zfs_arc_min_prefetch_lifespan, "Min life of prefetch block");
 
-module_param(zfs_arc_num_sublists_per_state, int, 0644);
-MODULE_PARM_DESC(zfs_arc_num_sublists_per_state,
-       "Number of sublists used in each of the ARC state lists");
-
 module_param(l2arc_write_max, ulong, 0644);
 MODULE_PARM_DESC(l2arc_write_max, "Max write bytes per interval");
 
index 173e1dbb8ea3c0c13cf42d02cd08264bf78ffa96..096f74a000deb1bb30c1b78bceb67e07b5b82c19 100644 (file)
@@ -673,7 +673,6 @@ retry:
 
        multilist_create(&dbuf_cache, sizeof (dmu_buf_impl_t),
            offsetof(dmu_buf_impl_t, db_cache_link),
-           zfs_arc_num_sublists_per_state,
            dbuf_cache_multilist_index_func);
        refcount_create(&dbuf_cache_size);
 
index e02a4bae33830cb591632df7dbf4c652ce2c9475..fa927b43baf44fbc47ed74df12679bcee44adbb9 100644 (file)
@@ -13,7 +13,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright (c) 2013, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2013, 2017 by Delphix. All rights reserved.
  */
 
 #include <sys/zfs_context.h>
 /* needed for spa_get_random() */
 #include <sys/spa.h>
 
+/*
+ * This overrides the number of sublists in each multilist_t, which defaults
+ * to the number of CPUs in the system (see multilist_create()).
+ */
+int zfs_multilist_num_sublists = 0;
+
 /*
  * Given the object contained on the list, return a pointer to the
  * object's multilist_node_t structure it contains.
@@ -62,9 +68,9 @@ multilist_d2l(multilist_t *ml, void *obj)
  *     requirement, but a general rule of thumb in order to garner the
  *     best multi-threaded performance out of the data structure.
  */
-void
-multilist_create(multilist_t *ml, size_t size, size_t offset, unsigned int num,
-    multilist_sublist_index_func_t *index_func)
+static void
+multilist_create_impl(multilist_t *ml, size_t size, size_t offset,
+    unsigned int num, multilist_sublist_index_func_t *index_func)
 {
        int i;
 
@@ -90,6 +96,26 @@ multilist_create(multilist_t *ml, size_t size, size_t offset, unsigned int num,
        }
 }
 
+/*
+ * Initialize a new sublist, using the default number of sublists
+ * (the number of CPUs, or at least 4, or the tunable
+ * zfs_multilist_num_sublists).
+ */
+void
+multilist_create(multilist_t *ml, size_t size, size_t offset,
+    multilist_sublist_index_func_t *index_func)
+{
+       int num_sublists;
+
+       if (zfs_multilist_num_sublists > 0) {
+               num_sublists = zfs_multilist_num_sublists;
+       } else {
+               num_sublists = MAX(boot_ncpus, 4);
+       }
+
+       multilist_create_impl(ml, size, offset, num_sublists, index_func);
+}
+
 /*
  * Destroy the given multilist object, and free up any memory it holds.
  */
@@ -373,3 +399,14 @@ multilist_link_active(multilist_node_t *link)
 {
        return (list_link_active(link));
 }
+
+#if defined(_KERNEL) && defined(HAVE_SPL)
+
+/* BEGIN CSTYLED */
+
+module_param(zfs_multilist_num_sublists, int, 0644);
+MODULE_PARM_DESC(zfs_multilist_num_sublists,
+       "Number of sublists used in each multilist");
+
+/* END CSTYLED */
+#endif