Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 322612
b: refs/heads/master
c: ec58815
h: refs/heads/master
v: v3
  • Loading branch information
Tejun Heo committed Sep 5, 2012
1 parent 58fd476 commit 76d1920
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 90beca5de591e12482a812f23a7f10690962ed4a
refs/heads/master: ec58815ab0409a921a7c9744eb4ca44866b14d71
29 changes: 27 additions & 2 deletions trunk/kernel/workqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -1326,6 +1326,15 @@ static void idle_worker_rebind(struct worker *worker)

/* we did our part, wait for rebind_workers() to finish up */
wait_event(gcwq->rebind_hold, !(worker->flags & WORKER_REBIND));

/*
* rebind_workers() shouldn't finish until all workers passed the
* above WORKER_REBIND wait. Tell it when done.
*/
spin_lock_irq(&worker->pool->gcwq->lock);
if (!--worker->idle_rebind->cnt)
complete(&worker->idle_rebind->done);
spin_unlock_irq(&worker->pool->gcwq->lock);
}

/*
Expand Down Expand Up @@ -1448,12 +1457,28 @@ static void rebind_workers(struct global_cwq *gcwq)
* be cleared inside idle_worker_rebind(). Clear and release.
* Clearing %WORKER_REBIND from this foreign context is safe
* because these workers are still guaranteed to be idle.
*
* We need to make sure all idle workers passed WORKER_REBIND wait
* in idle_worker_rebind() before returning; otherwise, workers can
* get stuck at the wait if hotplug cycle repeats.
*/
for_each_worker_pool(pool, gcwq)
list_for_each_entry(worker, &pool->idle_list, entry)
idle_rebind.cnt = 1;
INIT_COMPLETION(idle_rebind.done);

for_each_worker_pool(pool, gcwq) {
list_for_each_entry(worker, &pool->idle_list, entry) {
worker->flags &= ~WORKER_REBIND;
idle_rebind.cnt++;
}
}

wake_up_all(&gcwq->rebind_hold);

if (--idle_rebind.cnt) {
spin_unlock_irq(&gcwq->lock);
wait_for_completion(&idle_rebind.done);
spin_lock_irq(&gcwq->lock);
}
}

static struct worker *alloc_worker(void)
Expand Down

0 comments on commit 76d1920

Please sign in to comment.