Skip to content

Commit

Permalink
workqueue: fix HIGHPRI handling in keep_working()
Browse files Browse the repository at this point in the history
The policy function keep_working() didn't check GCWQ_HIGHPRI_PENDING
and could return %false with highpri work pending.  This could lead to
late execution of a highpri work which was delayed due to @max_active
throttling if other works are actively consuming CPU cycles.

For example, the following could happen.

1. Work W0 which burns CPU cycles.

2. Two works W1 and W2 are queued to a highpri wq w/ @max_active of 1.

3. W1 starts executing and W2 is put to delayed queue.  W0 and W1 are
   both runnable.

4. W1 finishes which puts W2 to pending queue but keep_working()
   incorrectly returns %false and the worker goes to sleep.

5. W0 finishes and W2 starts execution.

With this patch applied, W2 starts execution as soon as W1 finishes.

Signed-off-by: Tejun Heo <tj@kernel.org>
  • Loading branch information
Tejun Heo committed Oct 11, 2010
1 parent cdadf00 commit 3031004
Showing 1 changed file with 3 additions and 1 deletion.
4 changes: 3 additions & 1 deletion kernel/workqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,9 @@ static bool keep_working(struct global_cwq *gcwq)
{
atomic_t *nr_running = get_gcwq_nr_running(gcwq->cpu);

return !list_empty(&gcwq->worklist) && atomic_read(nr_running) <= 1;
return !list_empty(&gcwq->worklist) &&
(atomic_read(nr_running) <= 1 ||
gcwq->flags & GCWQ_HIGHPRI_PENDING);
}

/* Do we need a new worker? Called from manager. */
Expand Down

0 comments on commit 3031004

Please sign in to comment.