[PATCH -tip V4 4/8] workqueue: Manually break affinity on pool detachment

From: Lai Jiangshan
Date: Mon Jan 11 2021 - 09:27:27 EST


From: Lai Jiangshan <laijs@xxxxxxxxxxxxxxxxx>

The pool->attrs->cpumask might be a single CPU and it may go
down after detachment, and the scheduler won't force to break
affinity for us since it is a per-cpu-ktrhead. So we have to
do it on our own and unbind this worker which can't be unbound
by workqueue_offline_cpu() since it doesn't belong to any pool
after detachment. Do it unconditionally for there is no harm
to break affinity for non-per-cpu-ktrhead and we don't need to
rely on the scheduler's policy on when to break affinity.

Fixes: 06249738a41a ("workqueue: Manually break affinity on hotplug")
Acked-by: Tejun Heo <tj@xxxxxxxxxx>
Tested-by: Paul E. McKenney <paulmck@xxxxxxxxxx>
Signed-off-by: Lai Jiangshan <laijs@xxxxxxxxxxxxxxxxx>
---
kernel/workqueue.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 3e92bc4f8a36..aed08eddeb83 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -1888,6 +1888,19 @@ static void worker_detach_from_pool(struct worker *worker)

if (list_empty(&pool->workers))
detach_completion = pool->detach_completion;
+
+ /*
+ * The pool->attrs->cpumask might be a single CPU and it may go
+ * down after detachment, and the scheduler won't force to break
+ * affinity for us since it is a per-cpu-ktrhead. So we have to
+ * do it on our own and unbind this worker which can't be unbound
+ * by workqueue_offline_cpu() since it doesn't belong to any pool
+ * after detachment. Do it unconditionally for there is no harm
+ * to break affinity for non-per-cpu-ktrhead and we don't need to
+ * rely on the scheduler's policy on when to break affinity.
+ */
+ set_cpus_allowed_ptr(worker->task, cpu_possible_mask);
+
mutex_unlock(&wq_pool_attach_mutex);

/* clear leftover flags without pool->lock after it is detached */
--
2.19.1.6.gb485710b