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>
This commit is contained in:
parent
6be195886a
commit
038366c5cf
@ -3443,8 +3443,6 @@ EXPORT_SYMBOL_GPL(workqueue_congested);
|
|||||||
* Test whether @work is currently pending or running. There is no
|
* Test whether @work is currently pending or running. There is no
|
||||||
* synchronization around this function and the test result is
|
* synchronization around this function and the test result is
|
||||||
* unreliable and only useful as advisory hints or for debugging.
|
* unreliable and only useful as advisory hints or for debugging.
|
||||||
* Especially for reentrant wqs, the pending state might hide the
|
|
||||||
* running state.
|
|
||||||
*
|
*
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
* OR'd bitmask of WORK_BUSY_* bits.
|
* OR'd bitmask of WORK_BUSY_* bits.
|
||||||
@ -3455,17 +3453,15 @@ unsigned int work_busy(struct work_struct *work)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned int ret = 0;
|
unsigned int ret = 0;
|
||||||
|
|
||||||
if (!pool)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&pool->lock, flags);
|
|
||||||
|
|
||||||
if (work_pending(work))
|
if (work_pending(work))
|
||||||
ret |= WORK_BUSY_PENDING;
|
ret |= WORK_BUSY_PENDING;
|
||||||
if (find_worker_executing_work(pool, work))
|
|
||||||
ret |= WORK_BUSY_RUNNING;
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&pool->lock, flags);
|
if (pool) {
|
||||||
|
spin_lock_irqsave(&pool->lock, flags);
|
||||||
|
if (find_worker_executing_work(pool, work))
|
||||||
|
ret |= WORK_BUSY_RUNNING;
|
||||||
|
spin_unlock_irqrestore(&pool->lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user