diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/workqueue.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 692d97628a10..c462cd60c374 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
| @@ -1396,12 +1396,15 @@ retry: | |||
| 1396 | /* set REBIND and kick idle ones, we'll wait for these later */ | 1396 | /* set REBIND and kick idle ones, we'll wait for these later */ |
| 1397 | for_each_worker_pool(pool, gcwq) { | 1397 | for_each_worker_pool(pool, gcwq) { |
| 1398 | list_for_each_entry(worker, &pool->idle_list, entry) { | 1398 | list_for_each_entry(worker, &pool->idle_list, entry) { |
| 1399 | unsigned long worker_flags = worker->flags; | ||
| 1400 | |||
| 1399 | if (worker->flags & WORKER_REBIND) | 1401 | if (worker->flags & WORKER_REBIND) |
| 1400 | continue; | 1402 | continue; |
| 1401 | 1403 | ||
| 1402 | /* morph UNBOUND to REBIND */ | 1404 | /* morph UNBOUND to REBIND atomically */ |
| 1403 | worker->flags &= ~WORKER_UNBOUND; | 1405 | worker_flags &= ~WORKER_UNBOUND; |
| 1404 | worker->flags |= WORKER_REBIND; | 1406 | worker_flags |= WORKER_REBIND; |
| 1407 | ACCESS_ONCE(worker->flags) = worker_flags; | ||
| 1405 | 1408 | ||
| 1406 | idle_rebind.cnt++; | 1409 | idle_rebind.cnt++; |
| 1407 | worker->idle_rebind = &idle_rebind; | 1410 | worker->idle_rebind = &idle_rebind; |
| @@ -1434,10 +1437,12 @@ retry: | |||
| 1434 | /* rebind busy workers */ | 1437 | /* rebind busy workers */ |
| 1435 | for_each_busy_worker(worker, i, pos, gcwq) { | 1438 | for_each_busy_worker(worker, i, pos, gcwq) { |
| 1436 | struct work_struct *rebind_work = &worker->rebind_work; | 1439 | struct work_struct *rebind_work = &worker->rebind_work; |
| 1440 | unsigned long worker_flags = worker->flags; | ||
| 1437 | 1441 | ||
| 1438 | /* morph UNBOUND to REBIND */ | 1442 | /* morph UNBOUND to REBIND atomically */ |
| 1439 | worker->flags &= ~WORKER_UNBOUND; | 1443 | worker_flags &= ~WORKER_UNBOUND; |
| 1440 | worker->flags |= WORKER_REBIND; | 1444 | worker_flags |= WORKER_REBIND; |
| 1445 | ACCESS_ONCE(worker->flags) = worker_flags; | ||
| 1441 | 1446 | ||
| 1442 | if (test_and_set_bit(WORK_STRUCT_PENDING_BIT, | 1447 | if (test_and_set_bit(WORK_STRUCT_PENDING_BIT, |
| 1443 | work_data_bits(rebind_work))) | 1448 | work_data_bits(rebind_work))) |
