aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/workqueue.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r--kernel/workqueue.c62
1 files changed, 38 insertions, 24 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index f37421fb4f35..bc25bdfb4b42 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -60,8 +60,8 @@ enum {
60 * %WORKER_UNBOUND set and concurrency management disabled, and may 60 * %WORKER_UNBOUND set and concurrency management disabled, and may
61 * be executing on any CPU. The pool behaves as an unbound one. 61 * be executing on any CPU. The pool behaves as an unbound one.
62 * 62 *
63 * Note that DISASSOCIATED can be flipped only while holding 63 * Note that DISASSOCIATED should be flipped only while holding
64 * assoc_mutex to avoid changing binding state while 64 * manager_mutex to avoid changing binding state while
65 * create_worker() is in progress. 65 * create_worker() is in progress.
66 */ 66 */
67 POOL_MANAGE_WORKERS = 1 << 0, /* need to manage workers */ 67 POOL_MANAGE_WORKERS = 1 << 0, /* need to manage workers */
@@ -149,8 +149,9 @@ struct worker_pool {
149 DECLARE_HASHTABLE(busy_hash, BUSY_WORKER_HASH_ORDER); 149 DECLARE_HASHTABLE(busy_hash, BUSY_WORKER_HASH_ORDER);
150 /* L: hash of busy workers */ 150 /* L: hash of busy workers */
151 151
152 /* see manage_workers() for details on the two manager mutexes */
152 struct mutex manager_arb; /* manager arbitration */ 153 struct mutex manager_arb; /* manager arbitration */
153 struct mutex assoc_mutex; /* protect POOL_DISASSOCIATED */ 154 struct mutex manager_mutex; /* manager exclusion */
154 struct ida worker_ida; /* L: for worker IDs */ 155 struct ida worker_ida; /* L: for worker IDs */
155 156
156 struct workqueue_attrs *attrs; /* I: worker attributes */ 157 struct workqueue_attrs *attrs; /* I: worker attributes */
@@ -1635,7 +1636,7 @@ static void rebind_workers(struct worker_pool *pool)
1635 struct worker *worker, *n; 1636 struct worker *worker, *n;
1636 int i; 1637 int i;
1637 1638
1638 lockdep_assert_held(&pool->assoc_mutex); 1639 lockdep_assert_held(&pool->manager_mutex);
1639 lockdep_assert_held(&pool->lock); 1640 lockdep_assert_held(&pool->lock);
1640 1641
1641 /* dequeue and kick idle ones */ 1642 /* dequeue and kick idle ones */
@@ -2022,31 +2023,44 @@ static bool manage_workers(struct worker *worker)
2022 struct worker_pool *pool = worker->pool; 2023 struct worker_pool *pool = worker->pool;
2023 bool ret = false; 2024 bool ret = false;
2024 2025
2026 /*
2027 * Managership is governed by two mutexes - manager_arb and
2028 * manager_mutex. manager_arb handles arbitration of manager role.
2029 * Anyone who successfully grabs manager_arb wins the arbitration
2030 * and becomes the manager. mutex_trylock() on pool->manager_arb
2031 * failure while holding pool->lock reliably indicates that someone
2032 * else is managing the pool and the worker which failed trylock
2033 * can proceed to executing work items. This means that anyone
2034 * grabbing manager_arb is responsible for actually performing
2035 * manager duties. If manager_arb is grabbed and released without
2036 * actual management, the pool may stall indefinitely.
2037 *
2038 * manager_mutex is used for exclusion of actual management
2039 * operations. The holder of manager_mutex can be sure that none
2040 * of management operations, including creation and destruction of
2041 * workers, won't take place until the mutex is released. Because
2042 * manager_mutex doesn't interfere with manager role arbitration,
2043 * it is guaranteed that the pool's management, while may be
2044 * delayed, won't be disturbed by someone else grabbing
2045 * manager_mutex.
2046 */
2025 if (!mutex_trylock(&pool->manager_arb)) 2047 if (!mutex_trylock(&pool->manager_arb))
2026 return ret; 2048 return ret;
2027 2049
2028 /* 2050 /*
2029 * To simplify both worker management and CPU hotplug, hold off 2051 * With manager arbitration won, manager_mutex would be free in
2030 * management while hotplug is in progress. CPU hotplug path can't 2052 * most cases. trylock first without dropping @pool->lock.
2031 * grab @pool->manager_arb to achieve this because that can lead to
2032 * idle worker depletion (all become busy thinking someone else is
2033 * managing) which in turn can result in deadlock under extreme
2034 * circumstances. Use @pool->assoc_mutex to synchronize manager
2035 * against CPU hotplug.
2036 *
2037 * assoc_mutex would always be free unless CPU hotplug is in
2038 * progress. trylock first without dropping @pool->lock.
2039 */ 2053 */
2040 if (unlikely(!mutex_trylock(&pool->assoc_mutex))) { 2054 if (unlikely(!mutex_trylock(&pool->manager_mutex))) {
2041 spin_unlock_irq(&pool->lock); 2055 spin_unlock_irq(&pool->lock);
2042 mutex_lock(&pool->assoc_mutex); 2056 mutex_lock(&pool->manager_mutex);
2043 /* 2057 /*
2044 * CPU hotplug could have happened while we were waiting 2058 * CPU hotplug could have happened while we were waiting
2045 * for assoc_mutex. Hotplug itself can't handle us 2059 * for assoc_mutex. Hotplug itself can't handle us
2046 * because manager isn't either on idle or busy list, and 2060 * because manager isn't either on idle or busy list, and
2047 * @pool's state and ours could have deviated. 2061 * @pool's state and ours could have deviated.
2048 * 2062 *
2049 * As hotplug is now excluded via assoc_mutex, we can 2063 * As hotplug is now excluded via manager_mutex, we can
2050 * simply try to bind. It will succeed or fail depending 2064 * simply try to bind. It will succeed or fail depending
2051 * on @pool's current state. Try it and adjust 2065 * on @pool's current state. Try it and adjust
2052 * %WORKER_UNBOUND accordingly. 2066 * %WORKER_UNBOUND accordingly.
@@ -2068,7 +2082,7 @@ static bool manage_workers(struct worker *worker)
2068 ret |= maybe_destroy_workers(pool); 2082 ret |= maybe_destroy_workers(pool);
2069 ret |= maybe_create_worker(pool); 2083 ret |= maybe_create_worker(pool);
2070 2084
2071 mutex_unlock(&pool->assoc_mutex); 2085 mutex_unlock(&pool->manager_mutex);
2072 mutex_unlock(&pool->manager_arb); 2086 mutex_unlock(&pool->manager_arb);
2073 return ret; 2087 return ret;
2074} 2088}
@@ -3436,7 +3450,7 @@ static int init_worker_pool(struct worker_pool *pool)
3436 (unsigned long)pool); 3450 (unsigned long)pool);
3437 3451
3438 mutex_init(&pool->manager_arb); 3452 mutex_init(&pool->manager_arb);
3439 mutex_init(&pool->assoc_mutex); 3453 mutex_init(&pool->manager_mutex);
3440 ida_init(&pool->worker_ida); 3454 ida_init(&pool->worker_ida);
3441 3455
3442 INIT_HLIST_NODE(&pool->hash_node); 3456 INIT_HLIST_NODE(&pool->hash_node);
@@ -4076,11 +4090,11 @@ static void wq_unbind_fn(struct work_struct *work)
4076 for_each_cpu_worker_pool(pool, cpu) { 4090 for_each_cpu_worker_pool(pool, cpu) {
4077 WARN_ON_ONCE(cpu != smp_processor_id()); 4091 WARN_ON_ONCE(cpu != smp_processor_id());
4078 4092
4079 mutex_lock(&pool->assoc_mutex); 4093 mutex_lock(&pool->manager_mutex);
4080 spin_lock_irq(&pool->lock); 4094 spin_lock_irq(&pool->lock);
4081 4095
4082 /* 4096 /*
4083 * We've claimed all manager positions. Make all workers 4097 * We've blocked all manager operations. Make all workers
4084 * unbound and set DISASSOCIATED. Before this, all workers 4098 * unbound and set DISASSOCIATED. Before this, all workers
4085 * except for the ones which are still executing works from 4099 * except for the ones which are still executing works from
4086 * before the last CPU down must be on the cpu. After 4100 * before the last CPU down must be on the cpu. After
@@ -4095,7 +4109,7 @@ static void wq_unbind_fn(struct work_struct *work)
4095 pool->flags |= POOL_DISASSOCIATED; 4109 pool->flags |= POOL_DISASSOCIATED;
4096 4110
4097 spin_unlock_irq(&pool->lock); 4111 spin_unlock_irq(&pool->lock);
4098 mutex_unlock(&pool->assoc_mutex); 4112 mutex_unlock(&pool->manager_mutex);
4099 } 4113 }
4100 4114
4101 /* 4115 /*
@@ -4152,14 +4166,14 @@ static int __cpuinit workqueue_cpu_up_callback(struct notifier_block *nfb,
4152 case CPU_DOWN_FAILED: 4166 case CPU_DOWN_FAILED:
4153 case CPU_ONLINE: 4167 case CPU_ONLINE:
4154 for_each_cpu_worker_pool(pool, cpu) { 4168 for_each_cpu_worker_pool(pool, cpu) {
4155 mutex_lock(&pool->assoc_mutex); 4169 mutex_lock(&pool->manager_mutex);
4156 spin_lock_irq(&pool->lock); 4170 spin_lock_irq(&pool->lock);
4157 4171
4158 pool->flags &= ~POOL_DISASSOCIATED; 4172 pool->flags &= ~POOL_DISASSOCIATED;
4159 rebind_workers(pool); 4173 rebind_workers(pool);
4160 4174
4161 spin_unlock_irq(&pool->lock); 4175 spin_unlock_irq(&pool->lock);
4162 mutex_unlock(&pool->assoc_mutex); 4176 mutex_unlock(&pool->manager_mutex);
4163 } 4177 }
4164 break; 4178 break;
4165 } 4179 }