aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/workqueue.c
diff options
context:
space:
mode:
authorLai Jiangshan <laijs@cn.fujitsu.com>2013-02-06 21:04:53 -0500
committerTejun Heo <tj@kernel.org>2013-02-06 21:04:53 -0500
commit038366c5cf23ae737b9f72169dd8ade2d105755b (patch)
tree7119031b23ba32e02b3fc8621cc8666b41f95f8a /kernel/workqueue.c
parent6be195886ac26abe0194ed1bc7a9224f8a97c310 (diff)
workqueue: make work_busy() test WORK_STRUCT_PENDING first
Currently, work_busy() first tests whether the work has a pool associated with it and if not, considers it idle. This works fine even for delayed_work.work queued on timer, as __queue_delayed_work() sets cwq on delayed_work.work - a queued delayed_work always has its cwq and thus pool associated with it. However, we're about to update delayed_work queueing and this won't hold. Update work_busy() such that it tests WORK_STRUCT_PENDING before the associated pool. This doesn't make any noticeable behavior difference now. With work_pending() test moved, the function read a lot better with "if (!pool)" test flipped to positive. Flip it. While at it, lose the comment about now non-existent reentrant workqueues. tj: Reorganized the function and rewrote the description. Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r--kernel/workqueue.c16
1 files changed, 6 insertions, 10 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 7e11334a119f..a229a56f3a32 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -3443,8 +3443,6 @@ EXPORT_SYMBOL_GPL(workqueue_congested);
3443 * Test whether @work is currently pending or running. There is no 3443 * Test whether @work is currently pending or running. There is no
3444 * synchronization around this function and the test result is 3444 * synchronization around this function and the test result is
3445 * unreliable and only useful as advisory hints or for debugging. 3445 * unreliable and only useful as advisory hints or for debugging.
3446 * Especially for reentrant wqs, the pending state might hide the
3447 * running state.
3448 * 3446 *
3449 * RETURNS: 3447 * RETURNS:
3450 * OR'd bitmask of WORK_BUSY_* bits. 3448 * OR'd bitmask of WORK_BUSY_* bits.
@@ -3455,17 +3453,15 @@ unsigned int work_busy(struct work_struct *work)
3455 unsigned long flags; 3453 unsigned long flags;
3456 unsigned int ret = 0; 3454 unsigned int ret = 0;
3457 3455
3458 if (!pool)
3459 return 0;
3460
3461 spin_lock_irqsave(&pool->lock, flags);
3462
3463 if (work_pending(work)) 3456 if (work_pending(work))
3464 ret |= WORK_BUSY_PENDING; 3457 ret |= WORK_BUSY_PENDING;
3465 if (find_worker_executing_work(pool, work))
3466 ret |= WORK_BUSY_RUNNING;
3467 3458
3468 spin_unlock_irqrestore(&pool->lock, flags); 3459 if (pool) {
3460 spin_lock_irqsave(&pool->lock, flags);
3461 if (find_worker_executing_work(pool, work))
3462 ret |= WORK_BUSY_RUNNING;
3463 spin_unlock_irqrestore(&pool->lock, flags);
3464 }
3469 3465
3470 return ret; 3466 return ret;
3471} 3467}