For historical reasons, the worker attach/detach functions don't currently manage worker->pool and the callers are manually and inconsistently updating it. This patch moves worker->pool updates into the worker attach/detach functions. This makes worker->pool consistent and clearly defines how worker->pool updates are synchronized. This will help later workqueue visibility improvements by allowing safe access to workqueue information from worker->task.
Showing the changes to kernel/workqueue.c (1 of 2 files). Show all
Unified · Split
| @@ -1741,6 +1741,7 @@ static void worker_attach_to_pool(struct worker *worker, · 1740 unmodified lines | |||
| 1741 | worker->flags |= WORKER_UNBOUND; | 1741 | worker->flags |= WORKER_UNBOUND; |
| 1742 | 1742 | ||
| 1743 | list_add_tail(&worker->node, &pool->workers); | 1743 | list_add_tail(&worker->node, &pool->workers); |
| 1744 | worker->pool = pool; | ||
| 1744 | 1745 | ||
| 1745 | mutex_unlock(&wq_pool_attach_mutex); | 1746 | mutex_unlock(&wq_pool_attach_mutex); |
| 1746 | } | 1747 | } |
| @@ -1748,19 +1749,21 @@ static void worker_attach_to_pool(struct worker *worker, · 1 unmodified line | |||
| 1748 | /** | 1749 | /** |
| 1749 | * worker_detach_from_pool() - detach a worker from its pool | 1750 | * worker_detach_from_pool() - detach a worker from its pool |
| 1750 | * @worker: worker which is attached to its pool | 1751 | * @worker: worker which is attached to its pool |
| 1751 | * @pool: the pool @worker is attached to | ||
| 1752 | * | 1752 | * |
| 1753 | * Undo the attaching which had been done in worker_attach_to_pool(). The | 1753 | * Undo the attaching which had been done in worker_attach_to_pool(). The |
| 1754 | * caller worker shouldn't access to the pool after detached except it has | 1754 | * caller worker shouldn't access to the pool after detached except it has |
| 1755 | * other reference to the pool. | 1755 | * other reference to the pool. |
| 1756 | */ | 1756 | */ |
| 1757 | static void worker_detach_from_pool(struct worker *worker, | 1757 | static void worker_detach_from_pool(struct worker *worker) |
| 1758 | struct worker_pool *pool) | ||
| 1759 | { | 1758 | { |
| 1759 | struct worker_pool *pool = worker->pool; | ||
| 1760 | struct completion *detach_completion = NULL; | 1760 | struct completion *detach_completion = NULL; |
| 1761 | 1761 | ||
| 1762 | mutex_lock(&wq_pool_attach_mutex); | 1762 | mutex_lock(&wq_pool_attach_mutex); |
| 1763 | |||
| 1763 | list_del(&worker->node); | 1764 | list_del(&worker->node); |
| 1765 | worker->pool = NULL; | ||
| 1766 | |||
| 1764 | if (list_empty(&pool->workers)) | 1767 | if (list_empty(&pool->workers)) |
| 1765 | detach_completion = pool->detach_completion; | 1768 | detach_completion = pool->detach_completion; |
| 1766 | mutex_unlock(&wq_pool_attach_mutex); | 1769 | mutex_unlock(&wq_pool_attach_mutex); |
| @@ -1799,7 +1802,6 @@ static struct worker *create_worker(struct worker_pool *pool) · 32 unmodified lines | |||
| 1799 | if (!worker) | 1802 | if (!worker) |
| 1800 | goto fail; | 1803 | goto fail; |
| 1801 | 1804 | ||
| 1802 | worker->pool = pool; | ||
| 1803 | worker->id = id; | 1805 | worker->id = id; |
| 1804 | 1806 | ||
| 1805 | if (pool->cpu >= 0) | 1807 | if (pool->cpu >= 0) |
| @@ -2236,7 +2238,7 @@ woke_up: · 430 unmodified lines | |||
| 2236 | 2238 | ||
| 2237 | set_task_comm(worker->task, "kworker/dying"); | 2239 | set_task_comm(worker->task, "kworker/dying"); |
| 2238 | ida_simple_remove(&pool->worker_ida, worker->id); | 2240 | ida_simple_remove(&pool->worker_ida, worker->id); |
| 2239 | worker_detach_from_pool(worker, pool); | 2241 | worker_detach_from_pool(worker); |
| 2240 | kfree(worker); | 2242 | kfree(worker); |
| 2241 | return 0; | 2243 | return 0; |
| 2242 | } | 2244 | } |
| @@ -2367,7 +2369,6 @@ repeat: · 124 unmodified lines | |||
| 2367 | worker_attach_to_pool(rescuer, pool); | 2369 | worker_attach_to_pool(rescuer, pool); |
| 2368 | 2370 | ||
| 2369 | spin_lock_irq(&pool->lock); | 2371 | spin_lock_irq(&pool->lock); |
| 2370 | rescuer->pool = pool; | ||
| 2371 | 2372 | ||
| 2372 | /* | 2373 | /* |
| 2373 | * Slurp in all works issued via this workqueue and | 2374 | * Slurp in all works issued via this workqueue and |
| @@ -2417,10 +2418,9 @@ repeat: · 43 unmodified lines | |||
| 2417 | if (need_more_worker(pool)) | 2418 | if (need_more_worker(pool)) |
| 2418 | wake_up_worker(pool); | 2419 | wake_up_worker(pool); |
| 2419 | 2420 | ||
| 2420 | rescuer->pool = NULL; | ||
| 2421 | spin_unlock_irq(&pool->lock); | 2421 | spin_unlock_irq(&pool->lock); |
| 2422 | 2422 | ||
| 2423 | worker_detach_from_pool(rescuer, pool); | 2423 | worker_detach_from_pool(rescuer); |
| 2424 | 2424 | ||
| 2425 | spin_lock_irq(&wq_mayday_lock); | 2425 | spin_lock_irq(&wq_mayday_lock); |
| 2426 | } | 2426 | } |