diff options
author | Joonsoo Kim <js1304@gmail.com> | 2012-08-15 10:25:40 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2012-08-16 17:21:15 -0400 |
commit | e2b6a6d570f070aa90ac00d2d10b1488512f8520 (patch) | |
tree | 4f61d435e55f764b1bd990540d533fd68d9fbaa2 /kernel/workqueue.c | |
parent | 1aabe902ca3638d862bf0dad5a697d3a8e046b0a (diff) |
workqueue: use system_highpri_wq for highpri workers in rebind_workers()
In rebind_workers(), we do inserting a work to rebind to cpu for busy workers.
Currently, in this case, we use only system_wq. This makes a possible
error situation as there is mismatch between cwq->pool and worker->pool.
To prevent this, we should use system_highpri_wq for highpri worker
to match theses. This implements it.
tj: Rephrased comment a bit.
Signed-off-by: Joonsoo Kim <js1304@gmail.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r-- | kernel/workqueue.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 329c404b68c2..8936761b814a 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -1741,6 +1741,7 @@ retry: | |||
1741 | /* rebind busy workers */ | 1741 | /* rebind busy workers */ |
1742 | for_each_busy_worker(worker, i, pos, gcwq) { | 1742 | for_each_busy_worker(worker, i, pos, gcwq) { |
1743 | struct work_struct *rebind_work = &worker->rebind_work; | 1743 | struct work_struct *rebind_work = &worker->rebind_work; |
1744 | struct workqueue_struct *wq; | ||
1744 | 1745 | ||
1745 | /* morph UNBOUND to REBIND */ | 1746 | /* morph UNBOUND to REBIND */ |
1746 | worker->flags &= ~WORKER_UNBOUND; | 1747 | worker->flags &= ~WORKER_UNBOUND; |
@@ -1750,11 +1751,20 @@ retry: | |||
1750 | work_data_bits(rebind_work))) | 1751 | work_data_bits(rebind_work))) |
1751 | continue; | 1752 | continue; |
1752 | 1753 | ||
1753 | /* wq doesn't matter, use the default one */ | ||
1754 | debug_work_activate(rebind_work); | 1754 | debug_work_activate(rebind_work); |
1755 | insert_work(get_cwq(gcwq->cpu, system_wq), rebind_work, | 1755 | |
1756 | worker->scheduled.next, | 1756 | /* |
1757 | work_color_to_flags(WORK_NO_COLOR)); | 1757 | * wq doesn't really matter but let's keep @worker->pool |
1758 | * and @cwq->pool consistent for sanity. | ||
1759 | */ | ||
1760 | if (worker_pool_pri(worker->pool)) | ||
1761 | wq = system_highpri_wq; | ||
1762 | else | ||
1763 | wq = system_wq; | ||
1764 | |||
1765 | insert_work(get_cwq(gcwq->cpu, wq), rebind_work, | ||
1766 | worker->scheduled.next, | ||
1767 | work_color_to_flags(WORK_NO_COLOR)); | ||
1758 | } | 1768 | } |
1759 | } | 1769 | } |
1760 | 1770 | ||