diff --git a/include/sys/sysmacros.h b/include/sys/sysmacros.h index 4838ab3be3..9f16ac70fd 100644 --- a/include/sys/sysmacros.h +++ b/include/sys/sysmacros.h @@ -95,6 +95,7 @@ */ #define minclsyspri (MAX_RT_PRIO) #define maxclsyspri (MAX_PRIO-1) +#define defclsyspri (DEFAULT_PRIO) #ifndef NICE_TO_PRIO #define NICE_TO_PRIO(nice) (MAX_RT_PRIO + (nice) + 20) diff --git a/include/sys/taskq.h b/include/sys/taskq.h index a43a86da65..5c29e8f0eb 100644 --- a/include/sys/taskq.h +++ b/include/sys/taskq.h @@ -129,7 +129,7 @@ extern int taskq_member(taskq_t *, void *); #define taskq_create_proc(name, nthreads, pri, min, max, proc, flags) \ taskq_create(name, nthreads, pri, min, max, flags) #define taskq_create_sysdc(name, nthreads, min, max, proc, dc, flags) \ - taskq_create(name, nthreads, maxclsyspri, min, max, flags) + taskq_create(name, nthreads, defclsyspri, min, max, flags) int spl_taskq_init(void); void spl_taskq_fini(void); diff --git a/man/man5/spl-module-parameters.5 b/man/man5/spl-module-parameters.5 index fc38605b25..acdd5b658f 100644 --- a/man/man5/spl-module-parameters.5 +++ b/man/man5/spl-module-parameters.5 @@ -266,6 +266,21 @@ aid performance analysis or troubleshooting. Default value: \fB1\fR .RE +.sp +.ne 2 +.na +\fBspl_taskq_thread_priority\fR (int) +.ad +.RS 12n +Allow newly created taskq threads to set a non-default scheduler priority. +When enabled the priority specified when a taskq is created will be applied +to all threads created by that taskq. When disabled all threads will use +the default Linux kernel thread priority. By default, this behavior is +enabled. +.sp +Default value: \fB1\fR +.RE + .sp .ne 2 .na diff --git a/module/spl/spl-kmem-cache.c b/module/spl/spl-kmem-cache.c index 86c26ff054..112d0f8768 100644 --- a/module/spl/spl-kmem-cache.c +++ b/module/spl/spl-kmem-cache.c @@ -1725,7 +1725,7 @@ spl_kmem_cache_init(void) init_rwsem(&spl_kmem_cache_sem); INIT_LIST_HEAD(&spl_kmem_cache_list); spl_kmem_cache_taskq = taskq_create("spl_kmem_cache", - spl_kmem_cache_kmem_threads, maxclsyspri, + spl_kmem_cache_kmem_threads, defclsyspri, spl_kmem_cache_kmem_threads * 8, INT_MAX, TASKQ_PREPOPULATE | TASKQ_DYNAMIC); spl_register_shrinker(&spl_kmem_cache_shrinker); diff --git a/module/spl/spl-taskq.c b/module/spl/spl-taskq.c index 44799de1d1..b4282333e7 100644 --- a/module/spl/spl-taskq.c +++ b/module/spl/spl-taskq.c @@ -36,6 +36,11 @@ int spl_taskq_thread_dynamic = 1; module_param(spl_taskq_thread_dynamic, int, 0644); MODULE_PARM_DESC(spl_taskq_thread_dynamic, "Allow dynamic taskq threads"); +int spl_taskq_thread_priority = 1; +module_param(spl_taskq_thread_priority, int, 0644); +MODULE_PARM_DESC(spl_taskq_thread_priority, + "Allow non-default priority for taskq threads"); + int spl_taskq_thread_sequential = 4; module_param(spl_taskq_thread_sequential, int, 0644); MODULE_PARM_DESC(spl_taskq_thread_sequential, @@ -913,7 +918,9 @@ taskq_thread_create(taskq_t *tq) kthread_bind(tqt->tqt_thread, last_used_cpu); } - set_user_nice(tqt->tqt_thread, PRIO_TO_NICE(tq->tq_pri)); + if (spl_taskq_thread_priority) + set_user_nice(tqt->tqt_thread, PRIO_TO_NICE(tq->tq_pri)); + wake_up_process(tqt->tqt_thread); return (tqt); @@ -1070,12 +1077,12 @@ int spl_taskq_init(void) { system_taskq = taskq_create("spl_system_taskq", MAX(boot_ncpus, 64), - minclsyspri, boot_ncpus, INT_MAX, TASKQ_PREPOPULATE|TASKQ_DYNAMIC); + defclsyspri, boot_ncpus, INT_MAX, TASKQ_PREPOPULATE|TASKQ_DYNAMIC); if (system_taskq == NULL) return (1); dynamic_taskq = taskq_create("spl_dynamic_taskq", 1, - minclsyspri, boot_ncpus, INT_MAX, TASKQ_PREPOPULATE); + defclsyspri, boot_ncpus, INT_MAX, TASKQ_PREPOPULATE); if (dynamic_taskq == NULL) { taskq_destroy(system_taskq); return (1); diff --git a/module/splat/splat-atomic.c b/module/splat/splat-atomic.c index e94f42f00b..999f4f0587 100644 --- a/module/splat/splat-atomic.c +++ b/module/splat/splat-atomic.c @@ -156,7 +156,7 @@ splat_atomic_test1(struct file *file, void *arg) thr = (kthread_t *)thread_create(NULL, 0, splat_atomic_work, &ap, 0, &p0, TS_RUN, - minclsyspri); + defclsyspri); if (thr == NULL) { rc = -ESRCH; mutex_exit(&ap.ap_lock); diff --git a/module/splat/splat-kmem.c b/module/splat/splat-kmem.c index cd0000bae6..b3fd1a84dc 100644 --- a/module/splat/splat-kmem.c +++ b/module/splat/splat-kmem.c @@ -739,7 +739,7 @@ splat_kmem_cache_thread_test(struct file *file, void *arg, char *name, for (i = 0; i < SPLAT_KMEM_THREADS; i++) { thr = thread_create(NULL, 0, splat_kmem_cache_test_thread, - kcp, 0, &p0, TS_RUN, minclsyspri); + kcp, 0, &p0, TS_RUN, defclsyspri); if (thr == NULL) { rc = -ESRCH; goto out_cache; diff --git a/module/splat/splat-mutex.c b/module/splat/splat-mutex.c index 909d730cb0..86bef8ee31 100644 --- a/module/splat/splat-mutex.c +++ b/module/splat/splat-mutex.c @@ -87,7 +87,7 @@ splat_mutex_test1(struct file *file, void *arg) if (mp == NULL) return -ENOMEM; - tq = taskq_create(SPLAT_MUTEX_TEST_TASKQ, 1, maxclsyspri, + tq = taskq_create(SPLAT_MUTEX_TEST_TASKQ, 1, defclsyspri, 50, INT_MAX, TASKQ_PREPOPULATE); if (tq == NULL) { rc = -ENOMEM; @@ -196,7 +196,7 @@ splat_mutex_test2(struct file *file, void *arg) /* Create several threads allowing tasks to race with each other */ tq = taskq_create(SPLAT_MUTEX_TEST_TASKQ, num_online_cpus(), - maxclsyspri, 50, INT_MAX, TASKQ_PREPOPULATE); + defclsyspri, 50, INT_MAX, TASKQ_PREPOPULATE); if (tq == NULL) { rc = -ENOMEM; goto out; @@ -266,7 +266,7 @@ splat_mutex_test3(struct file *file, void *arg) mp.mp_file = file; mutex_init(&mp.mp_mtx, SPLAT_MUTEX_TEST_NAME, MUTEX_DEFAULT, NULL); - if ((tq = taskq_create(SPLAT_MUTEX_TEST_NAME, 1, maxclsyspri, + if ((tq = taskq_create(SPLAT_MUTEX_TEST_NAME, 1, defclsyspri, 50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) { splat_vprint(file, SPLAT_MUTEX_TEST3_NAME, "Taskq '%s' " "create failed\n", SPLAT_MUTEX_TEST3_NAME); diff --git a/module/splat/splat-rwlock.c b/module/splat/splat-rwlock.c index 6c623792e6..284f77370d 100644 --- a/module/splat/splat-rwlock.c +++ b/module/splat/splat-rwlock.c @@ -327,7 +327,7 @@ splat_rwlock_test2(struct file *file, void *arg) /* Create several threads allowing tasks to race with each other */ tq = taskq_create(SPLAT_RWLOCK_TEST_TASKQ, num_online_cpus(), - maxclsyspri, 50, INT_MAX, TASKQ_PREPOPULATE); + defclsyspri, 50, INT_MAX, TASKQ_PREPOPULATE); if (tq == NULL) { rc = -ENOMEM; goto out; @@ -500,7 +500,7 @@ splat_rwlock_test4(struct file *file, void *arg) if (rwp == NULL) return -ENOMEM; - tq = taskq_create(SPLAT_RWLOCK_TEST_TASKQ, 1, maxclsyspri, + tq = taskq_create(SPLAT_RWLOCK_TEST_TASKQ, 1, defclsyspri, 50, INT_MAX, TASKQ_PREPOPULATE); if (tq == NULL) { rc = -ENOMEM; diff --git a/module/splat/splat-taskq.c b/module/splat/splat-taskq.c index 645bc91459..8f06f413d5 100644 --- a/module/splat/splat-taskq.c +++ b/module/splat/splat-taskq.c @@ -134,7 +134,7 @@ splat_taskq_test1_impl(struct file *file, void *arg, boolean_t prealloc) "Taskq '%s' creating (%s dispatch)\n", SPLAT_TASKQ_TEST1_NAME, prealloc ? "prealloc" : "dynamic"); - if ((tq = taskq_create(SPLAT_TASKQ_TEST1_NAME, 1, maxclsyspri, + if ((tq = taskq_create(SPLAT_TASKQ_TEST1_NAME, 1, defclsyspri, 50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) { splat_vprint(file, SPLAT_TASKQ_TEST1_NAME, "Taskq '%s' create failed\n", @@ -269,7 +269,7 @@ splat_taskq_test2_impl(struct file *file, void *arg, boolean_t prealloc) { prealloc ? "prealloc" : "dynamic"); if ((tq[i] = taskq_create(SPLAT_TASKQ_TEST2_NAME, TEST2_THREADS_PER_TASKQ, - maxclsyspri, 50, INT_MAX, + defclsyspri, 50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) { splat_vprint(file, SPLAT_TASKQ_TEST2_NAME, "Taskq '%s/%d' create failed\n", @@ -494,7 +494,7 @@ splat_taskq_test4_common(struct file *file, void *arg, int minalloc, SPLAT_TASKQ_TEST4_NAME, prealloc ? "prealloc" : "dynamic", minalloc, maxalloc, nr_tasks); - if ((tq = taskq_create(SPLAT_TASKQ_TEST4_NAME, 1, maxclsyspri, + if ((tq = taskq_create(SPLAT_TASKQ_TEST4_NAME, 1, defclsyspri, minalloc, maxalloc, TASKQ_PREPOPULATE)) == NULL) { splat_vprint(file, SPLAT_TASKQ_TEST4_NAME, "Taskq '%s' create failed\n", @@ -712,7 +712,7 @@ splat_taskq_test5_impl(struct file *file, void *arg, boolean_t prealloc) "Taskq '%s' creating (%s dispatch)\n", SPLAT_TASKQ_TEST5_NAME, prealloc ? "prealloc" : "dynamic"); - if ((tq = taskq_create(SPLAT_TASKQ_TEST5_NAME, 3, maxclsyspri, + if ((tq = taskq_create(SPLAT_TASKQ_TEST5_NAME, 3, defclsyspri, 50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) { splat_vprint(file, SPLAT_TASKQ_TEST5_NAME, "Taskq '%s' create failed\n", @@ -873,7 +873,7 @@ splat_taskq_test6_impl(struct file *file, void *arg, boolean_t prealloc) "Taskq '%s' creating (%s dispatch)\n", SPLAT_TASKQ_TEST6_NAME, prealloc ? "prealloc" : "dynamic"); - if ((tq = taskq_create(SPLAT_TASKQ_TEST6_NAME, 3, maxclsyspri, + if ((tq = taskq_create(SPLAT_TASKQ_TEST6_NAME, 3, defclsyspri, 50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) { splat_vprint(file, SPLAT_TASKQ_TEST6_NAME, "Taskq '%s' create failed\n", @@ -1005,7 +1005,7 @@ splat_taskq_test7_impl(struct file *file, void *arg, boolean_t prealloc) "Taskq '%s' creating (%s dispatch)\n", SPLAT_TASKQ_TEST7_NAME, prealloc ? "prealloc" : "dynamic"); - if ((tq = taskq_create(SPLAT_TASKQ_TEST7_NAME, 1, maxclsyspri, + if ((tq = taskq_create(SPLAT_TASKQ_TEST7_NAME, 1, defclsyspri, 50, INT_MAX, TASKQ_PREPOPULATE)) == NULL) { splat_vprint(file, SPLAT_TASKQ_TEST7_NAME, "Taskq '%s' create failed\n", @@ -1094,7 +1094,7 @@ splat_taskq_throughput(struct file *file, void *arg, const char *name, splat_vprint(file, name, "Taskq '%s' creating (%d/%d/%d/%d)\n", name, nthreads, minalloc, maxalloc, tasks); - if ((tq = taskq_create(name, nthreads, maxclsyspri, + if ((tq = taskq_create(name, nthreads, defclsyspri, minalloc, maxalloc, flags)) == NULL) { splat_vprint(file, name, "Taskq '%s' create failed\n", name); rc = -EINVAL; @@ -1203,7 +1203,7 @@ splat_taskq_test9(struct file *file, void *arg) splat_vprint(file, SPLAT_TASKQ_TEST9_NAME, "Taskq '%s' creating (%s dispatch) (%d/%d/%d)\n", SPLAT_TASKQ_TEST9_NAME, "delay", minalloc, maxalloc, nr_tasks); - if ((tq = taskq_create(SPLAT_TASKQ_TEST9_NAME, 3, maxclsyspri, + if ((tq = taskq_create(SPLAT_TASKQ_TEST9_NAME, 3, defclsyspri, minalloc, maxalloc, TASKQ_PREPOPULATE)) == NULL) { splat_vprint(file, SPLAT_TASKQ_TEST9_NAME, "Taskq '%s' create failed\n", SPLAT_TASKQ_TEST9_NAME); @@ -1303,7 +1303,7 @@ splat_taskq_test10(struct file *file, void *arg) splat_vprint(file, SPLAT_TASKQ_TEST10_NAME, "Taskq '%s' creating (%s dispatch) (%d/%d/%d)\n", SPLAT_TASKQ_TEST10_NAME, "delay", minalloc, maxalloc, nr_tasks); - if ((tq = taskq_create(SPLAT_TASKQ_TEST10_NAME, 3, maxclsyspri, + if ((tq = taskq_create(SPLAT_TASKQ_TEST10_NAME, 3, defclsyspri, minalloc, maxalloc, TASKQ_PREPOPULATE)) == NULL) { splat_vprint(file, SPLAT_TASKQ_TEST10_NAME, "Taskq '%s' create failed\n", SPLAT_TASKQ_TEST10_NAME); diff --git a/module/splat/splat-thread.c b/module/splat/splat-thread.c index 3255e37e5b..8a44714078 100644 --- a/module/splat/splat-thread.c +++ b/module/splat/splat-thread.c @@ -112,7 +112,7 @@ splat_thread_test1(struct file *file, void *arg) tp.tp_rc = 0; thr = (kthread_t *)thread_create(NULL, 0, splat_thread_work1, &tp, 0, - &p0, TS_RUN, minclsyspri); + &p0, TS_RUN, defclsyspri); /* Must never fail under Solaris, but we check anyway since this * can happen in the linux SPL, we may want to change this behavior */ if (thr == NULL) @@ -161,7 +161,7 @@ splat_thread_test2(struct file *file, void *arg) tp.tp_rc = 0; thr = (kthread_t *)thread_create(NULL, 0, splat_thread_work2, &tp, 0, - &p0, TS_RUN, minclsyspri); + &p0, TS_RUN, defclsyspri); /* Must never fail under Solaris, but we check anyway since this * can happen in the linux SPL, we may want to change this behavior */ if (thr == NULL) @@ -278,7 +278,7 @@ splat_thread_test3(struct file *file, void *arg) /* Start tsd wait threads */ for (i = 0; i < SPLAT_THREAD_TEST_THREADS; i++) { if (thread_create(NULL, 0, splat_thread_work3_wait, - &tp, 0, &p0, TS_RUN, minclsyspri)) + &tp, 0, &p0, TS_RUN, defclsyspri)) wait_count++; } @@ -295,7 +295,7 @@ splat_thread_test3(struct file *file, void *arg) /* Start tsd exit threads */ for (i = 0; i < SPLAT_THREAD_TEST_THREADS; i++) { if (thread_create(NULL, 0, splat_thread_work3_exit, - &tp, 0, &p0, TS_RUN, minclsyspri)) + &tp, 0, &p0, TS_RUN, defclsyspri)) exit_count++; }