diff options
author | Tejun Heo <tj@kernel.org> | 2012-09-17 19:07:34 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2012-09-17 19:09:09 -0400 |
commit | 6c1423ba5dbdab45bcd8c1bc3bc6e07fe3f6a470 (patch) | |
tree | 3c7899ba9eee94f408faf483622faa23cbdbfed2 /kernel | |
parent | 136b5721d75a62a8f02c601c89122e32c1a85a84 (diff) | |
parent | 960bd11bf2daf669d0d910428fd9ef5a15c3d7cb (diff) |
Merge branch 'for-3.6-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq into for-3.7
This merge is necessary as Lai's CPU hotplug restructuring series
depends on the CPU hotplug bug fixes in for-3.6-fixes.
The merge creates one trivial conflict between the following two
commits.
96e65306b8 "workqueue: UNBOUND -> REBIND morphing in rebind_workers() should be atomic"
e2b6a6d570 "workqueue: use system_highpri_wq for highpri workers in rebind_workers()"
Both add local variable definitions to the same block and can be
merged in any order.
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/workqueue.c | 122 |
1 files changed, 99 insertions, 23 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 039d0fae171a..31d8a4586d4c 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -66,6 +66,7 @@ enum { | |||
66 | 66 | ||
67 | /* pool flags */ | 67 | /* pool flags */ |
68 | POOL_MANAGE_WORKERS = 1 << 0, /* need to manage workers */ | 68 | POOL_MANAGE_WORKERS = 1 << 0, /* need to manage workers */ |
69 | POOL_MANAGING_WORKERS = 1 << 1, /* managing workers */ | ||
69 | 70 | ||
70 | /* worker flags */ | 71 | /* worker flags */ |
71 | WORKER_STARTED = 1 << 0, /* started */ | 72 | WORKER_STARTED = 1 << 0, /* started */ |
@@ -682,7 +683,7 @@ static bool need_to_manage_workers(struct worker_pool *pool) | |||
682 | /* Do we have too many workers and should some go away? */ | 683 | /* Do we have too many workers and should some go away? */ |
683 | static bool too_many_workers(struct worker_pool *pool) | 684 | static bool too_many_workers(struct worker_pool *pool) |
684 | { | 685 | { |
685 | bool managing = mutex_is_locked(&pool->manager_mutex); | 686 | bool managing = pool->flags & POOL_MANAGING_WORKERS; |
686 | int nr_idle = pool->nr_idle + managing; /* manager is considered idle */ | 687 | int nr_idle = pool->nr_idle + managing; /* manager is considered idle */ |
687 | int nr_busy = pool->nr_workers - nr_idle; | 688 | int nr_busy = pool->nr_workers - nr_idle; |
688 | 689 | ||
@@ -1632,6 +1633,15 @@ static void idle_worker_rebind(struct worker *worker) | |||
1632 | 1633 | ||
1633 | /* we did our part, wait for rebind_workers() to finish up */ | 1634 | /* we did our part, wait for rebind_workers() to finish up */ |
1634 | wait_event(gcwq->rebind_hold, !(worker->flags & WORKER_REBIND)); | 1635 | wait_event(gcwq->rebind_hold, !(worker->flags & WORKER_REBIND)); |
1636 | |||
1637 | /* | ||
1638 | * rebind_workers() shouldn't finish until all workers passed the | ||
1639 | * above WORKER_REBIND wait. Tell it when done. | ||
1640 | */ | ||
1641 | spin_lock_irq(&worker->pool->gcwq->lock); | ||
1642 | if (!--worker->idle_rebind->cnt) | ||
1643 | complete(&worker->idle_rebind->done); | ||
1644 | spin_unlock_irq(&worker->pool->gcwq->lock); | ||
1635 | } | 1645 | } |
1636 | 1646 | ||
1637 | /* | 1647 | /* |
@@ -1645,8 +1655,16 @@ static void busy_worker_rebind_fn(struct work_struct *work) | |||
1645 | struct worker *worker = container_of(work, struct worker, rebind_work); | 1655 | struct worker *worker = container_of(work, struct worker, rebind_work); |
1646 | struct global_cwq *gcwq = worker->pool->gcwq; | 1656 | struct global_cwq *gcwq = worker->pool->gcwq; |
1647 | 1657 | ||
1648 | if (worker_maybe_bind_and_lock(worker)) | 1658 | worker_maybe_bind_and_lock(worker); |
1649 | worker_clr_flags(worker, WORKER_REBIND); | 1659 | |
1660 | /* | ||
1661 | * %WORKER_REBIND must be cleared even if the above binding failed; | ||
1662 | * otherwise, we may confuse the next CPU_UP cycle or oops / get | ||
1663 | * stuck by calling idle_worker_rebind() prematurely. If CPU went | ||
1664 | * down again inbetween, %WORKER_UNBOUND would be set, so clearing | ||
1665 | * %WORKER_REBIND is always safe. | ||
1666 | */ | ||
1667 | worker_clr_flags(worker, WORKER_REBIND); | ||
1650 | 1668 | ||
1651 | spin_unlock_irq(&gcwq->lock); | 1669 | spin_unlock_irq(&gcwq->lock); |
1652 | } | 1670 | } |
@@ -1702,12 +1720,15 @@ retry: | |||
1702 | /* set REBIND and kick idle ones, we'll wait for these later */ | 1720 | /* set REBIND and kick idle ones, we'll wait for these later */ |
1703 | for_each_worker_pool(pool, gcwq) { | 1721 | for_each_worker_pool(pool, gcwq) { |
1704 | list_for_each_entry(worker, &pool->idle_list, entry) { | 1722 | list_for_each_entry(worker, &pool->idle_list, entry) { |
1723 | unsigned long worker_flags = worker->flags; | ||
1724 | |||
1705 | if (worker->flags & WORKER_REBIND) | 1725 | if (worker->flags & WORKER_REBIND) |
1706 | continue; | 1726 | continue; |
1707 | 1727 | ||
1708 | /* morph UNBOUND to REBIND */ | 1728 | /* morph UNBOUND to REBIND atomically */ |
1709 | worker->flags &= ~WORKER_UNBOUND; | 1729 | worker_flags &= ~WORKER_UNBOUND; |
1710 | worker->flags |= WORKER_REBIND; | 1730 | worker_flags |= WORKER_REBIND; |
1731 | ACCESS_ONCE(worker->flags) = worker_flags; | ||
1711 | 1732 | ||
1712 | idle_rebind.cnt++; | 1733 | idle_rebind.cnt++; |
1713 | worker->idle_rebind = &idle_rebind; | 1734 | worker->idle_rebind = &idle_rebind; |
@@ -1725,26 +1746,16 @@ retry: | |||
1725 | goto retry; | 1746 | goto retry; |
1726 | } | 1747 | } |
1727 | 1748 | ||
1728 | /* | 1749 | /* all idle workers are rebound, rebind busy workers */ |
1729 | * All idle workers are rebound and waiting for %WORKER_REBIND to | ||
1730 | * be cleared inside idle_worker_rebind(). Clear and release. | ||
1731 | * Clearing %WORKER_REBIND from this foreign context is safe | ||
1732 | * because these workers are still guaranteed to be idle. | ||
1733 | */ | ||
1734 | for_each_worker_pool(pool, gcwq) | ||
1735 | list_for_each_entry(worker, &pool->idle_list, entry) | ||
1736 | worker->flags &= ~WORKER_REBIND; | ||
1737 | |||
1738 | wake_up_all(&gcwq->rebind_hold); | ||
1739 | |||
1740 | /* rebind busy workers */ | ||
1741 | for_each_busy_worker(worker, i, pos, gcwq) { | 1750 | for_each_busy_worker(worker, i, pos, gcwq) { |
1751 | unsigned long worker_flags = worker->flags; | ||
1742 | struct work_struct *rebind_work = &worker->rebind_work; | 1752 | struct work_struct *rebind_work = &worker->rebind_work; |
1743 | struct workqueue_struct *wq; | 1753 | struct workqueue_struct *wq; |
1744 | 1754 | ||
1745 | /* morph UNBOUND to REBIND */ | 1755 | /* morph UNBOUND to REBIND atomically */ |
1746 | worker->flags &= ~WORKER_UNBOUND; | 1756 | worker_flags &= ~WORKER_UNBOUND; |
1747 | worker->flags |= WORKER_REBIND; | 1757 | worker_flags |= WORKER_REBIND; |
1758 | ACCESS_ONCE(worker->flags) = worker_flags; | ||
1748 | 1759 | ||
1749 | if (test_and_set_bit(WORK_STRUCT_PENDING_BIT, | 1760 | if (test_and_set_bit(WORK_STRUCT_PENDING_BIT, |
1750 | work_data_bits(rebind_work))) | 1761 | work_data_bits(rebind_work))) |
@@ -1765,6 +1776,34 @@ retry: | |||
1765 | worker->scheduled.next, | 1776 | worker->scheduled.next, |
1766 | work_color_to_flags(WORK_NO_COLOR)); | 1777 | work_color_to_flags(WORK_NO_COLOR)); |
1767 | } | 1778 | } |
1779 | |||
1780 | /* | ||
1781 | * All idle workers are rebound and waiting for %WORKER_REBIND to | ||
1782 | * be cleared inside idle_worker_rebind(). Clear and release. | ||
1783 | * Clearing %WORKER_REBIND from this foreign context is safe | ||
1784 | * because these workers are still guaranteed to be idle. | ||
1785 | * | ||
1786 | * We need to make sure all idle workers passed WORKER_REBIND wait | ||
1787 | * in idle_worker_rebind() before returning; otherwise, workers can | ||
1788 | * get stuck at the wait if hotplug cycle repeats. | ||
1789 | */ | ||
1790 | idle_rebind.cnt = 1; | ||
1791 | INIT_COMPLETION(idle_rebind.done); | ||
1792 | |||
1793 | for_each_worker_pool(pool, gcwq) { | ||
1794 | list_for_each_entry(worker, &pool->idle_list, entry) { | ||
1795 | worker->flags &= ~WORKER_REBIND; | ||
1796 | idle_rebind.cnt++; | ||
1797 | } | ||
1798 | } | ||
1799 | |||
1800 | wake_up_all(&gcwq->rebind_hold); | ||
1801 | |||
1802 | if (--idle_rebind.cnt) { | ||
1803 | spin_unlock_irq(&gcwq->lock); | ||
1804 | wait_for_completion(&idle_rebind.done); | ||
1805 | spin_lock_irq(&gcwq->lock); | ||
1806 | } | ||
1768 | } | 1807 | } |
1769 | 1808 | ||
1770 | static struct worker *alloc_worker(void) | 1809 | static struct worker *alloc_worker(void) |
@@ -2110,9 +2149,45 @@ static bool manage_workers(struct worker *worker) | |||
2110 | struct worker_pool *pool = worker->pool; | 2149 | struct worker_pool *pool = worker->pool; |
2111 | bool ret = false; | 2150 | bool ret = false; |
2112 | 2151 | ||
2113 | if (!mutex_trylock(&pool->manager_mutex)) | 2152 | if (pool->flags & POOL_MANAGING_WORKERS) |
2114 | return ret; | 2153 | return ret; |
2115 | 2154 | ||
2155 | pool->flags |= POOL_MANAGING_WORKERS; | ||
2156 | |||
2157 | /* | ||
2158 | * To simplify both worker management and CPU hotplug, hold off | ||
2159 | * management while hotplug is in progress. CPU hotplug path can't | ||
2160 | * grab %POOL_MANAGING_WORKERS to achieve this because that can | ||
2161 | * lead to idle worker depletion (all become busy thinking someone | ||
2162 | * else is managing) which in turn can result in deadlock under | ||
2163 | * extreme circumstances. Use @pool->manager_mutex to synchronize | ||
2164 | * manager against CPU hotplug. | ||
2165 | * | ||
2166 | * manager_mutex would always be free unless CPU hotplug is in | ||
2167 | * progress. trylock first without dropping @gcwq->lock. | ||
2168 | */ | ||
2169 | if (unlikely(!mutex_trylock(&pool->manager_mutex))) { | ||
2170 | spin_unlock_irq(&pool->gcwq->lock); | ||
2171 | mutex_lock(&pool->manager_mutex); | ||
2172 | /* | ||
2173 | * CPU hotplug could have happened while we were waiting | ||
2174 | * for manager_mutex. Hotplug itself can't handle us | ||
2175 | * because manager isn't either on idle or busy list, and | ||
2176 | * @gcwq's state and ours could have deviated. | ||
2177 | * | ||
2178 | * As hotplug is now excluded via manager_mutex, we can | ||
2179 | * simply try to bind. It will succeed or fail depending | ||
2180 | * on @gcwq's current state. Try it and adjust | ||
2181 | * %WORKER_UNBOUND accordingly. | ||
2182 | */ | ||
2183 | if (worker_maybe_bind_and_lock(worker)) | ||
2184 | worker->flags &= ~WORKER_UNBOUND; | ||
2185 | else | ||
2186 | worker->flags |= WORKER_UNBOUND; | ||
2187 | |||
2188 | ret = true; | ||
2189 | } | ||
2190 | |||
2116 | pool->flags &= ~POOL_MANAGE_WORKERS; | 2191 | pool->flags &= ~POOL_MANAGE_WORKERS; |
2117 | 2192 | ||
2118 | /* | 2193 | /* |
@@ -2122,6 +2197,7 @@ static bool manage_workers(struct worker *worker) | |||
2122 | ret |= maybe_destroy_workers(pool); | 2197 | ret |= maybe_destroy_workers(pool); |
2123 | ret |= maybe_create_worker(pool); | 2198 | ret |= maybe_create_worker(pool); |
2124 | 2199 | ||
2200 | pool->flags &= ~POOL_MANAGING_WORKERS; | ||
2125 | mutex_unlock(&pool->manager_mutex); | 2201 | mutex_unlock(&pool->manager_mutex); |
2126 | return ret; | 2202 | return ret; |
2127 | } | 2203 | } |