Skip to content
This repository has been archived by the owner on Feb 26, 2020. It is now read-only.

Commit

Permalink
Add defclsyspri macro
Browse files Browse the repository at this point in the history
Add a new defclsyspri macro which can be used to request the default
Linux scheduler priority.  Neither the minclsyspri or maxclsyspri map
to the default Linux kernel thread priority.  This makes it awkward to
create taskqs which run with the same priority as the rest of the kernel
threads on the system which can lead to performance issues.

All SPL callers which previously used minclsyspri or maxclsyspri have
been changed to use defclsyspri.  The vast majority of callers were
part of the test suite which won't have an external impact.  The few
places where it could impact performance the change was from maxclsyspri
to defclsyspri.  This makes it more likely the process will be scheduled
which may help performance.

To facilitate further performance analysis the spl_taskq_thread_priority
module option has been added.  When disabled (0) all newly created kernel
threads will use the default kernel thread priority.  When enabled (1)
the specified taskq priority will be used.  By default this value is
enabled (1).

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
  • Loading branch information
behlendorf committed Jul 23, 2015
1 parent 9eb361a commit 62aa81a
Show file tree
Hide file tree
Showing 11 changed files with 48 additions and 25 deletions.
1 change: 1 addition & 0 deletions include/sys/sysmacros.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion include/sys/taskq.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
15 changes: 15 additions & 0 deletions man/man5/spl-module-parameters.5
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion module/spl/spl-kmem-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
13 changes: 10 additions & 3 deletions module/spl/spl-taskq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion module/splat/splat-atomic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion module/splat/splat-kmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions module/splat/splat-mutex.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions module/splat/splat-rwlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
18 changes: 9 additions & 9 deletions module/splat/splat-taskq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 4 additions & 4 deletions module/splat/splat-thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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++;
}

Expand All @@ -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++;
}

Expand Down

0 comments on commit 62aa81a

Please sign in to comment.