diff options
author | Tejun Heo <tj@kernel.org> | 2010-08-31 04:54:35 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2010-08-31 04:54:35 -0400 |
commit | 477a3c33d1efa0342a74bd02da2e049191993e2c (patch) | |
tree | 03d4ae1338f47016fbad6ff131007e009959b4a8 /kernel/workqueue.c | |
parent | 7c38875a0d0a9b90eee66be79e36995c86acc70c (diff) |
workqueue: fix GCWQ_DISASSOCIATED initialization
init_workqueues() incorrectly marks workqueues for all possible CPUs
associated. Combined with mayday_mask initialization bug, this can
make rescuers keep trying to bind to an offline gcwq indefinitely.
Fix init_workqueues() such that only online CPUs have their gcwqs have
GCWQ_DISASSOCIATED cleared.
Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: CAI Qian <caiqian@redhat.com>
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r-- | kernel/workqueue.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index a2dccfca03ba..c8183b235d16 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -3558,8 +3558,7 @@ static int __init init_workqueues(void) | |||
3558 | spin_lock_init(&gcwq->lock); | 3558 | spin_lock_init(&gcwq->lock); |
3559 | INIT_LIST_HEAD(&gcwq->worklist); | 3559 | INIT_LIST_HEAD(&gcwq->worklist); |
3560 | gcwq->cpu = cpu; | 3560 | gcwq->cpu = cpu; |
3561 | if (cpu == WORK_CPU_UNBOUND) | 3561 | gcwq->flags |= GCWQ_DISASSOCIATED; |
3562 | gcwq->flags |= GCWQ_DISASSOCIATED; | ||
3563 | 3562 | ||
3564 | INIT_LIST_HEAD(&gcwq->idle_list); | 3563 | INIT_LIST_HEAD(&gcwq->idle_list); |
3565 | for (i = 0; i < BUSY_WORKER_HASH_SIZE; i++) | 3564 | for (i = 0; i < BUSY_WORKER_HASH_SIZE; i++) |
@@ -3583,6 +3582,8 @@ static int __init init_workqueues(void) | |||
3583 | struct global_cwq *gcwq = get_gcwq(cpu); | 3582 | struct global_cwq *gcwq = get_gcwq(cpu); |
3584 | struct worker *worker; | 3583 | struct worker *worker; |
3585 | 3584 | ||
3585 | if (cpu != WORK_CPU_UNBOUND) | ||
3586 | gcwq->flags &= ~GCWQ_DISASSOCIATED; | ||
3586 | worker = create_worker(gcwq, true); | 3587 | worker = create_worker(gcwq, true); |
3587 | BUG_ON(!worker); | 3588 | BUG_ON(!worker); |
3588 | spin_lock_irq(&gcwq->lock); | 3589 | spin_lock_irq(&gcwq->lock); |