Skip to content

Commit

Permalink
Allow spawning a new thread for TQ_NOQUEUE dispatch with dynamic taskq
Browse files Browse the repository at this point in the history
When a TQ_NOQUEUE dispatch is done on a dynamic taskq, allow another
thread to be spawned.  This will cause TQ_NOQUEUE to behave similarly
as it does with non-dynamic taskqs.

Add support for TQ_NOQUEUE to taskq_dispatch_ent().
  • Loading branch information
Tim Chase authored and dweeezil committed Mar 7, 2016
1 parent 8f3b403 commit a3cce0a
Showing 1 changed file with 18 additions and 4 deletions.
22 changes: 18 additions & 4 deletions module/spl/spl-taskq.c
Original file line number Diff line number Diff line change
Expand Up @@ -562,16 +562,22 @@ taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t flags)

/* Do not queue the task unless there is idle thread for it */
ASSERT(tq->tq_nactive <= tq->tq_nthreads);
if ((flags & TQ_NOQUEUE) && (tq->tq_nactive == tq->tq_nthreads))
goto out;
if ((flags & TQ_NOQUEUE) && (tq->tq_nactive == tq->tq_nthreads)) {
/* Dynamic taskq may be able to spawn another thread */
if (!(tq->tq_flags & TASKQ_DYNAMIC) || taskq_thread_spawn(tq) == 0)
goto out;
}

if ((t = task_alloc(tq, flags, &irqflags)) == NULL)
goto out;

spin_lock(&t->tqent_lock);

/* Queue to the front of the list to enforce TQ_NOQUEUE semantics */
if (flags & TQ_NOQUEUE)
list_add(&t->tqent_list, &tq->tq_prio_list);
/* Queue to the priority list instead of the pending list */
if (flags & TQ_FRONT)
else if (flags & TQ_FRONT)
list_add_tail(&t->tqent_list, &tq->tq_prio_list);
else
list_add_tail(&t->tqent_list, &tq->tq_pend_list);
Expand All @@ -593,7 +599,7 @@ taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t flags)
wake_up(&tq->tq_work_waitq);
out:
/* Spawn additional taskq threads if required. */
if (tq->tq_nactive == tq->tq_nthreads)
if (!(flags & TQ_NOQUEUE) && tq->tq_nactive == tq->tq_nthreads)
(void) taskq_thread_spawn(tq);

spin_unlock_irqrestore(&tq->tq_lock, irqflags);
Expand Down Expand Up @@ -665,6 +671,13 @@ taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
goto out;
}

if ((flags & TQ_NOQUEUE) && (tq->tq_nactive == tq->tq_nthreads)) {
/* Dynamic taskq may be able to spawn another thread */
if (!(tq->tq_flags & TASKQ_DYNAMIC) || taskq_thread_spawn(tq) == 0)
goto out2;
flags |= TQ_FRONT;
}

spin_lock(&t->tqent_lock);

/*
Expand Down Expand Up @@ -693,6 +706,7 @@ taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
/* Spawn additional taskq threads if required. */
if (tq->tq_nactive == tq->tq_nthreads)
(void) taskq_thread_spawn(tq);
out2:
spin_unlock_irqrestore(&tq->tq_lock, irqflags);
}
EXPORT_SYMBOL(taskq_dispatch_ent);
Expand Down

0 comments on commit a3cce0a

Please sign in to comment.