diff options
author | Lai Jiangshan <laijs@cn.fujitsu.com> | 2013-02-06 21:04:53 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2013-02-06 21:04:53 -0500 |
commit | 038366c5cf23ae737b9f72169dd8ade2d105755b (patch) | |
tree | 7119031b23ba32e02b3fc8621cc8666b41f95f8a /kernel/workqueue.c | |
parent | 6be195886ac26abe0194ed1bc7a9224f8a97c310 (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.c | 16 |
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 | } |