aboutsummaryrefslogtreecommitdiffstats
path: root/module/spl/spl-taskq.c
diff options
context:
space:
mode:
authorTim Chase <[email protected]>2015-10-19 07:47:52 -0500
committerBrian Behlendorf <[email protected]>2015-12-16 09:35:22 -0800
commit200366f23f1a16874d78a07936c5a33f2d488022 (patch)
tree6bd2f868fcd8a8118d986782da77de010d0b088a /module/spl/spl-taskq.c
parente0ed96fa43e1d34751ef8a750a7816852b1d09b3 (diff)
Provide kstat for taskqs
This patch provides 2 new kstats to display task queues: /proc/spl/taskqs-all - Display all task queues /proc/spl/taskqs - Display only "active" task queues A task queue is considered to be "active" if it currently has active (running) threads or if any of its pending, priority, delay or waitq lists are not empty. If the task queue has running threads, displays each thread function's address (symbolically, if possibly) and its argument. If the task queue has a non-empty list of pending, priority or delayed task queue entries (taskq_ent_t), displays each entry's thread function address and arguemnt. If the task queue has any waiters, displays each waiting task's pid. Note: This patch also updates some comments in taskq.h which referred to "taskq_t" when they should have referred to "taskq_ent_t". Signed-off-by: Tim Chase <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Closes #491
Diffstat (limited to 'module/spl/spl-taskq.c')
-rw-r--r--module/spl/spl-taskq.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/module/spl/spl-taskq.c b/module/spl/spl-taskq.c
index 89d68f33c..db5d8fba1 100644
--- a/module/spl/spl-taskq.c
+++ b/module/spl/spl-taskq.c
@@ -54,6 +54,10 @@ EXPORT_SYMBOL(system_taskq);
static taskq_t *dynamic_taskq;
static taskq_thread_t *taskq_thread_create(taskq_t *);
+/* List of all taskqs */
+LIST_HEAD(tq_list);
+DECLARE_RWSEM(tq_list_sem);
+
static int
task_km_flags(uint_t flags)
{
@@ -67,6 +71,23 @@ task_km_flags(uint_t flags)
}
/*
+ * taskq_find_by_name - Find the largest instance number of a named taskq.
+ */
+static int
+taskq_find_by_name(const char *name)
+{
+ struct list_head *tql;
+ taskq_t *tq;
+
+ list_for_each_prev(tql, &tq_list) {
+ tq = list_entry(tql, taskq_t, tq_taskqs);
+ if (strcmp(name, tq->tq_name) == 0)
+ return tq->tq_instance;
+ }
+ return (-1);
+}
+
+/*
* NOTE: Must be called with tq->tq_lock held, returns a list_t which
* is not attached to the free, work, or pending taskq lists.
*/
@@ -1024,6 +1045,7 @@ taskq_create(const char *name, int nthreads, pri_t pri,
init_waitqueue_head(&tq->tq_work_waitq);
init_waitqueue_head(&tq->tq_wait_waitq);
tq->tq_lock_class = TQ_LOCK_GENERAL;
+ INIT_LIST_HEAD(&tq->tq_taskqs);
if (flags & TASKQ_PREPOPULATE) {
spin_lock_irqsave_nested(&tq->tq_lock, irqflags,
@@ -1053,6 +1075,11 @@ taskq_create(const char *name, int nthreads, pri_t pri,
if (rc) {
taskq_destroy(tq);
tq = NULL;
+ } else {
+ down_write(&tq_list_sem);
+ tq->tq_instance = taskq_find_by_name(name) + 1;
+ list_add_tail(&tq->tq_taskqs, &tq_list);
+ up_write(&tq_list_sem);
}
return (tq);
@@ -1081,6 +1108,11 @@ taskq_destroy(taskq_t *tq)
taskq_wait(tq);
+ /* remove taskq from global list used by the kstats */
+ down_write(&tq_list_sem);
+ list_del(&tq->tq_taskqs);
+ up_write(&tq_list_sem);
+
spin_lock_irqsave_nested(&tq->tq_lock, flags, tq->tq_lock_class);
/*