busy_worker_rebind_fn() can't return until all idle workers are rebound, the code of busy_worker_rebind_fn() ensure this.
So we can change the order of the code of rebind_workers(), and make it is a single pass to do the rebind_workers(). It makes the code much clean and better readability(still need later patch to improve the readability) Signed-off-by: Lai Jiangshan <la...@cn.fujitsu.com> --- kernel/workqueue.c | 23 ++++++++--------------- 1 files changed, 8 insertions(+), 15 deletions(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 16bcd84..6d68571 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -1458,16 +1458,11 @@ static void rebind_workers(struct global_cwq *gcwq) init_completion(&idle_rebind.ref_done); idle_rebind.ref_cnt = 1; gcwq->idle_rebind = &idle_rebind; -retry: idle_rebind.idle_cnt = 1; - INIT_COMPLETION(idle_rebind.idle_done); /* set REBIND and kick idle ones, we'll wait for these later */ for_each_worker_pool(pool, gcwq) { list_for_each_entry(worker, &pool->idle_list, entry) { - if (!(worker->flags & WORKER_UNBOUND)) - continue; - /* morph UNBOUND to REBIND */ worker->flags &= ~WORKER_UNBOUND; worker->flags |= WORKER_REBIND; @@ -1479,16 +1474,6 @@ retry: } } - if (--idle_rebind.idle_cnt) { - spin_unlock_irq(&gcwq->lock); - wait_for_completion(&idle_rebind.idle_done); - spin_lock_irq(&gcwq->lock); - /* busy ones might have become idle while waiting, retry */ - goto retry; - } - - complete_all(&idle_rebind.rebind_hold); - /* rebind busy workers */ for_each_busy_worker(worker, i, pos, gcwq) { struct work_struct *rebind_work = &worker->rebind_work; @@ -1515,6 +1500,14 @@ retry: * we will leave rebind_workers(), have to wait until no worker * has ref to this idle_rebind. */ + if (--idle_rebind.idle_cnt) { + spin_unlock_irq(&gcwq->lock); + wait_for_completion(&idle_rebind.idle_done); + spin_lock_irq(&gcwq->lock); + } + + complete_all(&idle_rebind.rebind_hold); + if (--idle_rebind.ref_cnt) { spin_unlock_irq(&gcwq->lock); wait_for_completion(&idle_rebind.ref_done); -- 1.7.4.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/