summaryrefslogtreecommitdiffstats
path: root/module/spl/spl-taskq.c
diff options
context:
space:
mode:
Diffstat (limited to 'module/spl/spl-taskq.c')
-rw-r--r--module/spl/spl-taskq.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/module/spl/spl-taskq.c b/module/spl/spl-taskq.c
index ece99aad6..b0677666d 100644
--- a/module/spl/spl-taskq.c
+++ b/module/spl/spl-taskq.c
@@ -286,10 +286,11 @@ __taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t flags)
ASSERT(!(t->tqent_flags & TQENT_FLAG_PREALLOC));
spin_unlock(&t->tqent_lock);
-
- wake_up(&tq->tq_work_waitq);
out:
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+ if (rc > 0)
+ wake_up(&tq->tq_work_waitq);
+
SRETURN(rc);
}
EXPORT_SYMBOL(__taskq_dispatch);
@@ -309,6 +310,7 @@ __taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
/* Taskq being destroyed and all tasks drained */
if (!(tq->tq_flags & TQ_ACTIVE)) {
t->tqent_id = 0;
+ spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
goto out;
}
@@ -332,10 +334,10 @@ __taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
t->tqent_arg = arg;
spin_unlock(&t->tqent_lock);
+ spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
wake_up(&tq->tq_work_waitq);
out:
- spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
SEXIT;
}
EXPORT_SYMBOL(__taskq_dispatch_ent);
@@ -454,17 +456,17 @@ taskq_thread(void *args)
while (!kthread_should_stop()) {
- add_wait_queue(&tq->tq_work_waitq, &wait);
if (list_empty(&tq->tq_pend_list) &&
list_empty(&tq->tq_prio_list)) {
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
+ add_wait_queue_exclusive(&tq->tq_work_waitq, &wait);
schedule();
+ remove_wait_queue(&tq->tq_work_waitq, &wait);
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
} else {
__set_current_state(TASK_RUNNING);
}
- remove_wait_queue(&tq->tq_work_waitq, &wait);
if (!list_empty(&tq->tq_prio_list))
pend_list = &tq->tq_prio_list;