diff options
Diffstat (limited to 'module/spl/spl-taskq.c')
-rw-r--r-- | module/spl/spl-taskq.c | 32 |
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); /* |