@@ -470,22 +470,23 @@ static int zfs_arc_prune_task_threads = 1;
470
470
static taskq_t * arc_flush_taskq ;
471
471
472
472
/*
473
- * Controls the number of ARC eviction threads.
473
+ * Controls the number of ARC eviction threads to dispatch sublists to.
474
+ *
474
475
* Possible values:
475
476
* 0 (auto) compute the number of threads using a logarithmic formula.
476
477
* 1 (disabled) one thread - parallel eviction is disabled.
477
- * 2+ (manual) set the number manually, limited by zfs_arc_evict_threads_max.
478
+ * 2+ (manual) set the number manually.
479
+ *
480
+ * See arc_evict_thread_init() for how "auto" is computed.
478
481
*/
479
482
static uint_t zfs_arc_evict_threads = 0 ;
480
483
481
484
/*
482
- * The number of allocated ARC eviction threads. This limits the maximum value
483
- * of zfs_arc_evict_threads.
484
- * The number is set up at module load time and depends on the initial value of
485
- * zfs_arc_evict_threads. If zfs_arc_evict_threads is set to auto, a logarithmic
486
- * function is used to compute this value. Otherwise, it is set to max_ncpus.
485
+ * The max number of ARC eviction threads to use. All provided or computed
486
+ * values for zfs_arc_evict_threads will be clamped to this. If not set at
487
+ * module load time, will be computed. See arc_evict_thread_init().
487
488
*/
488
- static uint_t zfs_arc_evict_threads_max ;
489
+ static uint_t zfs_arc_evict_threads_max = 0 ;
489
490
490
491
/* The 7 states: */
491
492
arc_state_t ARC_anon ;
@@ -4086,6 +4087,102 @@ arc_evict_task(void *arg)
4086
4087
eva -> eva_marker , eva -> eva_spa , eva -> eva_bytes );
4087
4088
}
4088
4089
4090
+ static uint_t arc_evict_threads = 0 ;
4091
+ static uint_t arc_evict_threads_auto = 0 ;
4092
+
4093
+ static void
4094
+ arc_evict_thread_recalc (void )
4095
+ {
4096
+ /* Reload from tuneable */
4097
+ uint_t want_threads = zfs_arc_evict_threads ;
4098
+ if (want_threads == 0 )
4099
+ want_threads = arc_evict_threads_auto ;
4100
+
4101
+ /* Clamp to configured maximum */
4102
+ if (want_threads > zfs_arc_evict_threads_max )
4103
+ want_threads = zfs_arc_evict_threads_max ;
4104
+
4105
+ if (want_threads > 1 && arc_evict_taskq == NULL )
4106
+ /*
4107
+ * First time the thread count goes over 1, ensure the taskq
4108
+ * is created. By default, this will happen in the call from
4109
+ * arc_init() on any system with 6+ CPUs. This is here to
4110
+ * support a system that started out with 1 thread (either
4111
+ * explicitly configured or because the system has <6 CPUs),
4112
+ * which was then raised. This should be a rare case, and we
4113
+ * do this to avoid precreating a taskq that we won't ever use.
4114
+ */
4115
+ arc_evict_taskq = taskq_create ("arc_evict" ,
4116
+ zfs_arc_evict_threads_max , defclsyspri , 0 , INT_MAX ,
4117
+ TASKQ_PREPOPULATE );
4118
+
4119
+ atomic_store_32 (& arc_evict_threads , want_threads );
4120
+ }
4121
+
4122
+ static void
4123
+ arc_evict_thread_init (void )
4124
+ {
4125
+ /*
4126
+ * Compute number of threads we want to use for eviction.
4127
+ *
4128
+ * Normally, it's log2(ncpus) + ncpus/32, which gets us to the
4129
+ * default max of 16 threads at ~256 CPUs.
4130
+ *
4131
+ * However, this formula goes to two threads at 4 CPUs, which
4132
+ * is still rather to low to be really useful, so we just go
4133
+ * with 1 thread at fewer than 6 cores.
4134
+ */
4135
+ if (max_ncpus < 6 )
4136
+ arc_evict_threads_auto = 1 ;
4137
+ else
4138
+ arc_evict_threads_auto =
4139
+ (highbit64 (max_ncpus ) - 1 ) + max_ncpus / 32 ;
4140
+
4141
+ /*
4142
+ * If not set, compute an appropriate max possible threads.
4143
+ */
4144
+ if (zfs_arc_evict_threads_max == 0 ) {
4145
+ /*
4146
+ * If they want the computed number of threads, then then
4147
+ * set the max such that the computer value falls in the
4148
+ * range of 4 to 16 threads.
4149
+ *
4150
+ * 4 threads in the minimum, because this allows machines
4151
+ * with <16 CPUs to still have room to raise
4152
+ * zfs_arc_evict_threads at runtime, giving operators of
4153
+ * smaller machines some room to move.
4154
+ *
4155
+ * Above that, we set it to the computed value, so it can
4156
+ * only be reduced at runtime.
4157
+ *
4158
+ * 16 is the hard upper limit for a computed maximum,
4159
+ * regardless of the number of CPUs. This is the computed value
4160
+ * for 256-287 cores, at which point you almost certainly
4161
+ * should be setting these tuneables yourself.
4162
+ *
4163
+ * If they have supplied a wanted number of threads, but
4164
+ * have not explicitly set a maximum, follow the same rules,
4165
+ * but if they go over 16, set the max there, so they don't
4166
+ * have to set a separate tuneable just to get their choice
4167
+ * through.
4168
+ */
4169
+ if (zfs_arc_evict_threads > 16 )
4170
+ zfs_arc_evict_threads_max = zfs_arc_evict_threads ;
4171
+ else {
4172
+ uint_t nthreads = zfs_arc_evict_threads ?
4173
+ zfs_arc_evict_threads : arc_evict_threads_auto ;
4174
+
4175
+ zfs_arc_evict_threads_max = MAX (MIN (nthreads , 16 ), 4 );
4176
+ }
4177
+ }
4178
+
4179
+ /* Clamp computed number of threads to maximum */
4180
+ if (arc_evict_threads_auto > zfs_arc_evict_threads_max )
4181
+ arc_evict_threads_auto = zfs_arc_evict_threads_max ;
4182
+
4183
+ arc_evict_thread_recalc ();
4184
+ }
4185
+
4089
4186
/*
4090
4187
* The minimum number of bytes we can evict at once is a block size.
4091
4188
* So, SPA_MAXBLOCKSIZE is a reasonable minimal value per an eviction task.
@@ -4118,19 +4215,7 @@ arc_evict_state(arc_state_t *state, arc_buf_contents_t type, uint64_t spa,
4118
4215
4119
4216
num_sublists = multilist_get_num_sublists (ml );
4120
4217
4121
- /* Compute how many sublists we can evict in parallel */
4122
- uint_t nthreads = 1 ;
4123
- if (arc_evict_taskq ) {
4124
- /* One sublist per thread */
4125
- nthreads = num_sublists ;
4126
-
4127
- /* Operator has set an ideal number of threads, honour it */
4128
- if (zfs_arc_evict_threads > 0 )
4129
- nthreads = MIN (nthreads , zfs_arc_evict_threads );
4130
-
4131
- /* Never more than the max threads */
4132
- nthreads = MIN (nthreads , zfs_arc_evict_threads_max );
4133
- }
4218
+ uint_t nthreads = atomic_load_32 (& arc_evict_threads );
4134
4219
4135
4220
boolean_t use_evcttq = nthreads > 1 ;
4136
4221
@@ -4815,6 +4900,12 @@ arc_evict_cb(void *arg, zthr_t *zthr)
4815
4900
{
4816
4901
(void ) arg ;
4817
4902
4903
+ /*
4904
+ * Recompute how many sublists we can evict in parallel, as it may
4905
+ * have been changed by the operator since the last eviction call.
4906
+ */
4907
+ arc_evict_thread_recalc ();
4908
+
4818
4909
uint64_t evicted = 0 ;
4819
4910
fstrans_cookie_t cookie = spl_fstrans_mark ();
4820
4911
@@ -8011,34 +8102,7 @@ arc_init(void)
8011
8102
arc_prune_taskq = taskq_create ("arc_prune" , zfs_arc_prune_task_threads ,
8012
8103
defclsyspri , 100 , INT_MAX , TASKQ_PREPOPULATE | TASKQ_DYNAMIC );
8013
8104
8014
- if (max_ncpus > 1 ) {
8015
- if (zfs_arc_evict_threads == 0 ) {
8016
- /*
8017
- * Limit the maximum number of threads by 16.
8018
- * We reach the limit when max_ncpu == 256.
8019
- */
8020
- uint_t nthreads = MIN ((highbit64 (max_ncpus ) - 1 ) +
8021
- max_ncpus / 32 , 16 );
8022
-
8023
- /*
8024
- * If there's less then four cores in the system,
8025
- * disable parallel eviction entirely. This is somewhat
8026
- * arbitrary but at least, this is quite a small
8027
- * computer that should probably use those cores for
8028
- * something else.
8029
- */
8030
- zfs_arc_evict_threads_max = max_ncpus < 4 ? 1 :
8031
- nthreads ;
8032
- } else {
8033
- zfs_arc_evict_threads_max = max_ncpus / 2 ;
8034
- }
8035
-
8036
- if (zfs_arc_evict_threads_max > 1 ) {
8037
- arc_evict_taskq = taskq_create ("arc_evict" ,
8038
- zfs_arc_evict_threads_max ,
8039
- defclsyspri , 0 , INT_MAX , TASKQ_PREPOPULATE );
8040
- }
8041
- }
8105
+ arc_evict_thread_init ();
8042
8106
8043
8107
list_create (& arc_async_flush_list , sizeof (arc_async_flush_t ),
8044
8108
offsetof(arc_async_flush_t , af_node ));
@@ -11275,7 +11339,7 @@ ZFS_MODULE_PARAM(zfs_arc, zfs_arc_, prune_task_threads, INT, ZMOD_RW,
11275
11339
"Number of arc_prune threads" );
11276
11340
11277
11341
ZFS_MODULE_PARAM (zfs_arc , zfs_arc_ , evict_threads , UINT , ZMOD_RW ,
11278
- "Controls the number of ARC eviction threads " );
11342
+ "Number of threads to use for ARC eviction. " );
11279
11343
11280
11344
ZFS_MODULE_PARAM (zfs_arc , zfs_arc_ , evict_threads_max , UINT , ZMOD_RD ,
11281
- "The number of allocated ARC eviction threads " );
11345
+ "The max number of threads that can be used for ARC eviction" );
0 commit comments