Skip to content

Commit

Permalink
workqueue: introduce for_each_pool()
Browse files Browse the repository at this point in the history
With the scheduled unbound pools with custom attributes, there will be
multiple unbound pools, so it wouldn't be able to use
for_each_wq_cpu() + for_each_std_worker_pool() to iterate through all
pools.

Introduce for_each_pool() which iterates through all pools using
worker_pool_idr and use it instead of for_each_wq_cpu() +
for_each_std_worker_pool() combination in freeze_workqueues_begin().

Signed-off-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Lai Jiangshan <laijs@cn.fujitsu.com>
  • Loading branch information
Tejun Heo committed Mar 12, 2013
1 parent 49e3cf4 commit 1711696
Showing 1 changed file with 21 additions and 15 deletions.
36 changes: 21 additions & 15 deletions kernel/workqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,14 @@ static inline int __next_wq_cpu(int cpu, const struct cpumask *mask,
(cpu) < WORK_CPU_END; \
(cpu) = __next_wq_cpu((cpu), cpu_online_mask, 3))

/**
* for_each_pool - iterate through all worker_pools in the system
* @pool: iteration cursor
* @id: integer used for iteration
*/
#define for_each_pool(pool, id) \
idr_for_each_entry(&worker_pool_idr, pool, id)

/**
* for_each_pwq - iterate through all pool_workqueues of the specified workqueue
* @pwq: iteration cursor
Expand Down Expand Up @@ -3586,33 +3594,31 @@ EXPORT_SYMBOL_GPL(work_on_cpu);
*/
void freeze_workqueues_begin(void)
{
unsigned int cpu;
struct worker_pool *pool;
int id;

spin_lock_irq(&workqueue_lock);

WARN_ON_ONCE(workqueue_freezing);
workqueue_freezing = true;

for_each_wq_cpu(cpu) {
struct worker_pool *pool;
for_each_pool(pool, id) {
struct workqueue_struct *wq;

for_each_std_worker_pool(pool, cpu) {
spin_lock(&pool->lock);

WARN_ON_ONCE(pool->flags & POOL_FREEZING);
pool->flags |= POOL_FREEZING;
spin_lock(&pool->lock);

list_for_each_entry(wq, &workqueues, list) {
struct pool_workqueue *pwq = get_pwq(cpu, wq);
WARN_ON_ONCE(pool->flags & POOL_FREEZING);
pool->flags |= POOL_FREEZING;

if (pwq && pwq->pool == pool &&
(wq->flags & WQ_FREEZABLE))
pwq->max_active = 0;
}
list_for_each_entry(wq, &workqueues, list) {
struct pool_workqueue *pwq = get_pwq(pool->cpu, wq);

spin_unlock(&pool->lock);
if (pwq && pwq->pool == pool &&
(wq->flags & WQ_FREEZABLE))
pwq->max_active = 0;
}

spin_unlock(&pool->lock);
}

spin_unlock_irq(&workqueue_lock);
Expand Down

0 comments on commit 1711696

Please sign in to comment.