[lkml]   [2013]   [Feb]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
Patch in this message
Subject[PATCH wq/for-3.9] workqueue: make work_busy() test WORK_STRUCT_PENDING first
From: Lai Jiangshan <>

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 queued on timer, as __queue_delayed_work()
sets cwq on - 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

tj: Reorganized the function and rewrote the description.

Signed-off-by: Lai Jiangshan <>
Signed-off-by: Tejun Heo <>
Hey, Lai.

Did I get the reason right? Can you *please* try to explain "why" a
patch is needed / beneficial for future postings like I did above? I
get that writing in English could be a bit stressful (it's not my
mother tongue either and I struggled with it a lot and still do to
certain extent) but the language doesn't have to be perfect. You just
need to communicate main points of your rationale somehow.


kernel/workqueue.c | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)

--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -3443,8 +3443,6 @@ EXPORT_SYMBOL_GPL(workqueue_congested);
* Test whether @work is currently pending or running. There is no
* synchronization around this function and the test result is
* unreliable and only useful as advisory hints or for debugging.
- * Especially for reentrant wqs, the pending state might hide the
- * running state.
* OR'd bitmask of WORK_BUSY_* bits.
@@ -3455,17 +3453,15 @@ unsigned int work_busy(struct work_struc
unsigned long flags;
unsigned int ret = 0;

- if (!pool)
- return 0;
- spin_lock_irqsave(&pool->lock, flags);
if (work_pending(work))
- if (find_worker_executing_work(pool, work))

- spin_unlock_irqrestore(&pool->lock, flags);
+ if (pool) {
+ spin_lock_irqsave(&pool->lock, flags);
+ if (find_worker_executing_work(pool, work))
+ spin_unlock_irqrestore(&pool->lock, flags);
+ }

return ret;

 \ /
  Last update: 2013-02-07 01:41    [W:0.724 / U:1.472 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site