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