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

Commit

Permalink
Limit number of tasks shown in taskq proc
Browse files Browse the repository at this point in the history
To prevent holding tq_lock for too long.

Before openzfs/zfs@8e71ab9, hogging delay tasks and cat /proc/spl/taskq
would easily cause a lockup. While that bug has been fixed. It's probably
still a good idea to do this just in case task lists grow too large.

Reviewed-by: Tim Chase <tim@chase2k.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
Closes #586
  • Loading branch information
tuxoko authored and behlendorf committed Dec 1, 2016
1 parent cbba714 commit 4934925
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
15 changes: 15 additions & 0 deletions man/man5/spl-module-parameters.5
Original file line number Diff line number Diff line change
Expand Up @@ -326,3 +326,18 @@ configurations.
.sp
Default value: \fB4\fR
.RE

.sp
.ne 2
.na
\fBspl_max_show_tasks\fR (uint)
.ad
.RS 12n
The maximum number of tasks per pending list in each taskq shown in
/proc/spl/{taskq,taskq-all}. Write 0 to turn off the limit. The proc file will
walk the lists with lock held, reading it could cause a lock up if the list
grow too large without limiting the output. "(truncated)" will be shown if the
list is larger than the limit.
.sp
Default value: \fB512\fR
.RE
19 changes: 13 additions & 6 deletions module/spl/spl-proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@ taskq_seq_show_headers(struct seq_file *f)
#define LHEAD_ACTIVE 4
#define LHEAD_SIZE 5

static unsigned int spl_max_show_tasks = 512;
module_param(spl_max_show_tasks, uint, 0644);
MODULE_PARM_DESC(spl_max_show_tasks, "Max number of tasks shown in taskq proc");

static int
taskq_seq_show_impl(struct seq_file *f, void *p, boolean_t allflag)
{
Expand Down Expand Up @@ -308,16 +312,20 @@ taskq_seq_show_impl(struct seq_file *f, void *p, boolean_t allflag)
if (lheads[i]) {
j = 0;
list_for_each(lh, lheads[i]) {
if (spl_max_show_tasks != 0 &&
j >= spl_max_show_tasks) {
seq_printf(f, "\n\t(truncated)");
break;
}
/* show the wait waitq list */
if (i == LHEAD_WAIT) {
wq = list_entry(lh, wait_queue_t, task_list);
if (j == 0)
seq_printf(f, "\t%s:",
list_names[i]);
else if (j == 12) {
else if (j % 8 == 0)
seq_printf(f, "\n\t ");
j = 0;
}

tsk = wq->private;
seq_printf(f, " %d", tsk->pid);
/* pend, prio and delay lists */
Expand All @@ -327,10 +335,9 @@ taskq_seq_show_impl(struct seq_file *f, void *p, boolean_t allflag)
if (j == 0)
seq_printf(f, "\t%s:",
list_names[i]);
else if (j == 2) {
else if (j % 2 == 0)
seq_printf(f, "\n\t ");
j = 0;
}

seq_printf(f, " %pf(%ps)",
tqe->tqent_func,
tqe->tqent_arg);
Expand Down

0 comments on commit 4934925

Please sign in to comment.