diff options
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r-- | kernel/workqueue.c | 62 |
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 | } |