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>
This commit is contained in:
@@ -3558,8 +3558,7 @@ static int __init init_workqueues(void)
|
|||||||
spin_lock_init(&gcwq->lock);
|
spin_lock_init(&gcwq->lock);
|
||||||
INIT_LIST_HEAD(&gcwq->worklist);
|
INIT_LIST_HEAD(&gcwq->worklist);
|
||||||
gcwq->cpu = cpu;
|
gcwq->cpu = cpu;
|
||||||
if (cpu == WORK_CPU_UNBOUND)
|
gcwq->flags |= GCWQ_DISASSOCIATED;
|
||||||
gcwq->flags |= GCWQ_DISASSOCIATED;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&gcwq->idle_list);
|
INIT_LIST_HEAD(&gcwq->idle_list);
|
||||||
for (i = 0; i < BUSY_WORKER_HASH_SIZE; i++)
|
for (i = 0; i < BUSY_WORKER_HASH_SIZE; i++)
|
||||||
@@ -3583,6 +3582,8 @@ static int __init init_workqueues(void)
|
|||||||
struct global_cwq *gcwq = get_gcwq(cpu);
|
struct global_cwq *gcwq = get_gcwq(cpu);
|
||||||
struct worker *worker;
|
struct worker *worker;
|
||||||
|
|
||||||
|
if (cpu != WORK_CPU_UNBOUND)
|
||||||
|
gcwq->flags &= ~GCWQ_DISASSOCIATED;
|
||||||
worker = create_worker(gcwq, true);
|
worker = create_worker(gcwq, true);
|
||||||
BUG_ON(!worker);
|
BUG_ON(!worker);
|
||||||
spin_lock_irq(&gcwq->lock);
|
spin_lock_irq(&gcwq->lock);
|
||||||
|
Reference in New Issue
Block a user