Skip to content
This repository has been archived by the owner on Feb 26, 2020. It is now read-only.

Commit

Permalink
Taskq locking optimizations
Browse files Browse the repository at this point in the history
Testing has shown that tq->tq_lock can be highly contended when a
large number of small work items are dispatched.  The lock hold time
is reduced by the following changes:

1) Use exclusive threads in the work_waitq

When a single work item is dispatched we only need to wake a single
thread to service it.  The current implementation uses non-exclusive
threads so all threads are woken when the dispatcher calls wake_up().
If a large number of threads are in the queue this overhead can become
non-negligible.

2) Conditionally add/remove threads from work waitq

Taskq threads need only add themselves to the work wait queue if
there are no pending work items.

Signed-off-by: Brian Behlendorf <[email protected]>
Issue #32
  • Loading branch information
nedbass authored and behlendorf committed Jan 19, 2012
1 parent 0bb43ca commit 3c6ed54
Showing 1 changed file with 2 additions and 2 deletions.
4 changes: 2 additions & 2 deletions module/spl/spl-taskq.c
Original file line number Diff line number Diff line change
Expand Up @@ -454,17 +454,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)) {
add_wait_queue_exclusive(&tq->tq_work_waitq, &wait);
spin_unlock_irqrestore(&tq->tq_lock, tq->tq_lock_flags);
schedule();
spin_lock_irqsave(&tq->tq_lock, tq->tq_lock_flags);
remove_wait_queue(&tq->tq_work_waitq, &wait);
} 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;
Expand Down

0 comments on commit 3c6ed54

Please sign in to comment.