diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/workqueue.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 1e1373bcb3e3..b80065a2450a 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -1349,8 +1349,16 @@ static void busy_worker_rebind_fn(struct work_struct *work) | |||
1349 | struct worker *worker = container_of(work, struct worker, rebind_work); | 1349 | struct worker *worker = container_of(work, struct worker, rebind_work); |
1350 | struct global_cwq *gcwq = worker->pool->gcwq; | 1350 | struct global_cwq *gcwq = worker->pool->gcwq; |
1351 | 1351 | ||
1352 | if (worker_maybe_bind_and_lock(worker)) | 1352 | worker_maybe_bind_and_lock(worker); |
1353 | worker_clr_flags(worker, WORKER_REBIND); | 1353 | |
1354 | /* | ||
1355 | * %WORKER_REBIND must be cleared even if the above binding failed; | ||
1356 | * otherwise, we may confuse the next CPU_UP cycle or oops / get | ||
1357 | * stuck by calling idle_worker_rebind() prematurely. If CPU went | ||
1358 | * down again inbetween, %WORKER_UNBOUND would be set, so clearing | ||
1359 | * %WORKER_REBIND is always safe. | ||
1360 | */ | ||
1361 | worker_clr_flags(worker, WORKER_REBIND); | ||
1354 | 1362 | ||
1355 | spin_unlock_irq(&gcwq->lock); | 1363 | spin_unlock_irq(&gcwq->lock); |
1356 | } | 1364 | } |