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 | 1741 | worker->flags |= WORKER_UNBOUND; |
| 1742 | 1742 | |
| 1743 | 1743 | list_add_tail(&worker->node, &pool->workers); |
| 1744 | + worker->pool = pool; | |
| 1744 | 1745 | |
| 1745 | 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 | 1750 | * worker_detach_from_pool() - detach a worker from its pool |
| 1750 | 1751 | * @worker: worker which is attached to its pool |
| 1751 | − * @pool: the pool @worker is attached to | |
| 1752 | 1752 | * |
| 1753 | 1753 | * Undo the attaching which had been done in worker_attach_to_pool(). The |
| 1754 | 1754 | * caller worker shouldn't access to the pool after detached except it has |
| 1755 | 1755 | * other reference to the pool. |
| 1756 | 1756 | */ |
| 1757 | −static void worker_detach_from_pool(struct worker *worker, | |
| 1758 | − struct worker_pool *pool) | |
| 1757 | +static void worker_detach_from_pool(struct worker *worker) | |
| 1759 | 1758 | { |
| 1759 | + struct worker_pool *pool = worker->pool; | |
| 1760 | 1760 | struct completion *detach_completion = NULL; |
| 1761 | 1761 | |
| 1762 | 1762 | mutex_lock(&wq_pool_attach_mutex); |
| 1763 | + | |
| 1763 | 1764 | list_del(&worker->node); |
| 1765 | + worker->pool = NULL; | |
| 1766 | + | |
| 1764 | 1767 | if (list_empty(&pool->workers)) |
| 1765 | 1768 | detach_completion = pool->detach_completion; |
| 1766 | 1769 | mutex_unlock(&wq_pool_attach_mutex); |
| @@ -1799,7 +1802,6 @@ static struct worker *create_worker(struct worker_pool *pool) · 32 unmodified lines | ||
| 1799 | 1802 | if (!worker) |
| 1800 | 1803 | goto fail; |
| 1801 | 1804 | |
| 1802 | − worker->pool = pool; | |
| 1803 | 1805 | worker->id = id; |
| 1804 | 1806 | |
| 1805 | 1807 | if (pool->cpu >= 0) |
| @@ -2236,7 +2238,7 @@ woke_up: · 430 unmodified lines | ||
| 2236 | 2238 | |
| 2237 | 2239 | set_task_comm(worker->task, "kworker/dying"); |
| 2238 | 2240 | ida_simple_remove(&pool->worker_ida, worker->id); |
| 2239 | − worker_detach_from_pool(worker, pool); | |
| 2241 | + worker_detach_from_pool(worker); | |
| 2240 | 2242 | kfree(worker); |
| 2241 | 2243 | return 0; |
| 2242 | 2244 | } |
| @@ -2367,7 +2369,6 @@ repeat: · 124 unmodified lines | ||
| 2367 | 2369 | worker_attach_to_pool(rescuer, pool); |
| 2368 | 2370 | |
| 2369 | 2371 | spin_lock_irq(&pool->lock); |
| 2370 | − rescuer->pool = pool; | |
| 2371 | 2372 | |
| 2372 | 2373 | /* |
| 2373 | 2374 | * Slurp in all works issued via this workqueue and |
| @@ -2417,10 +2418,9 @@ repeat: · 43 unmodified lines | ||
| 2417 | 2418 | if (need_more_worker(pool)) |
| 2418 | 2419 | wake_up_worker(pool); |
| 2419 | 2420 | |
| 2420 | − rescuer->pool = NULL; | |
| 2421 | 2421 | spin_unlock_irq(&pool->lock); |
| 2422 | 2422 | |
| 2423 | − worker_detach_from_pool(rescuer, pool); | |
| 2423 | + worker_detach_from_pool(rescuer); | |
| 2424 | 2424 | |
| 2425 | 2425 | spin_lock_irq(&wq_mayday_lock); |
| 2426 | 2426 | } |