* [PATCH 1/3] workqueue: Update the rescuer's affinity only when it is detached
2025-11-17 3:09 [PATCH 0/3] workqueue: Cleanup affnity for detached/DISASSOCIATED workers Lai Jiangshan
@ 2025-11-17 3:09 ` Lai Jiangshan
2025-11-17 3:09 ` [PATCH 2/3] workqueue: Let DISASSOCIATED workers follow unbound wq cpumask changes Lai Jiangshan
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Lai Jiangshan @ 2025-11-17 3:09 UTC (permalink / raw)
To: linux-kernel
Cc: Lai Jiangshan, Juri Lelli, Waiman Long, Tejun Heo, Lai Jiangshan
From: Lai Jiangshan <jiangshan.ljs@antgroup.com>
When a rescuer is attached to a pool, its affinity should be only
managed by the pool.
But updating the detached rescuer's affinity is still meaningful so
that it will not disrupt isolated CPUs when it is to be waken up.
But the commit d64f2fa064f8 ("kernel/workqueue: Let rescuers follow
unbound wq cpumask changes") updates the affinity unconditionally, and
causes some issues
1) it also changes the affinity when the rescuer is already attached to
a pool, which violates the affinity management.
2) the said commit tries to update the affinity of the rescuers, but it
misses the rescuers of the PERCPU workqueues, and isolated CPUs can
be possibly disrupted by these rescuers when they are summoned.
3) The affinity to set to the rescuers should be consistent in all paths
when a rescuer is in detached state. The affinity could be either
wq_unbound_cpumask or unbound_effective_cpumask(wq). Related paths:
rescuer's worker_detach_from_pool()
update wq_unbound_cpumask
update wq's cpumask
init_rescuer()
Both affinities are Ok as long as they are consistent in all paths.
But using unbound_effective_cpumask(wq) requres much more code to
maintain the consistency, and it doesn't make much sense since the
affinity is only effective when the rescuer is not processing works.
wq_unbound_cpumask is more favorable.
Fix the 1) issue by testing rescuer->pool before updating with
wq_pool_attach_mutex held.
Fix the 2) issue by moving the rescuer's affinity updating code to
the place updating wq_unbound_cpumask and make it also update for
PERCPU workqueues.
Partially cleanup the 3) consistency issue by using wq_unbound_cpumask.
So that the path of "updating wq's cpumask" doesn't need to maintain it.
and both the paths of "updating wq_unbound_cpumask" and "rescuer's
worker_detach_from_pool()" use wq_unbound_cpumask.
Cleanup for init_rescuer()'s consistency for affinity can be done in
future.
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Waiman Long <longman@redhat.com>
Signed-off-by: Lai Jiangshan <jiangshan.ljs@antgroup.com>
---
kernel/workqueue.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index af182a19a8b1..9da679c621dc 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -5411,11 +5411,6 @@ static void apply_wqattrs_commit(struct apply_wqattrs_ctx *ctx)
/* update node_nr_active->max */
wq_update_node_max_active(ctx->wq, -1);
- /* rescuer needs to respect wq cpumask changes */
- if (ctx->wq->rescuer)
- set_cpus_allowed_ptr(ctx->wq->rescuer->task,
- unbound_effective_cpumask(ctx->wq));
-
mutex_unlock(&ctx->wq->mutex);
}
@@ -6974,6 +6969,11 @@ static int workqueue_apply_unbound_cpumask(const cpumask_var_t unbound_cpumask)
if (!ret) {
mutex_lock(&wq_pool_attach_mutex);
cpumask_copy(wq_unbound_cpumask, unbound_cpumask);
+ /* rescuer needs to respect cpumask changes when it is not attached */
+ list_for_each_entry(wq, &workqueues, list) {
+ if (wq->rescuer && !wq->rescuer->pool)
+ unbind_worker(wq->rescuer);
+ }
mutex_unlock(&wq_pool_attach_mutex);
}
return ret;
--
2.19.1.6.gb485710b
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 2/3] workqueue: Let DISASSOCIATED workers follow unbound wq cpumask changes
2025-11-17 3:09 [PATCH 0/3] workqueue: Cleanup affnity for detached/DISASSOCIATED workers Lai Jiangshan
2025-11-17 3:09 ` [PATCH 1/3] workqueue: Update the rescuer's affinity only when it is detached Lai Jiangshan
@ 2025-11-17 3:09 ` Lai Jiangshan
2025-11-17 3:09 ` [PATCH 3/3] workqueue: Init rescuer's affinities as wq_unbound_cpumask Lai Jiangshan
2025-11-20 20:32 ` [PATCH 0/3] workqueue: Cleanup affnity for detached/DISASSOCIATED workers Tejun Heo
3 siblings, 0 replies; 5+ messages in thread
From: Lai Jiangshan @ 2025-11-17 3:09 UTC (permalink / raw)
To: linux-kernel
Cc: Lai Jiangshan, Juri Lelli, Waiman Long, Tejun Heo, Lai Jiangshan
From: Lai Jiangshan <jiangshan.ljs@antgroup.com>
When workqueue cpumask changes are committed, the DISASSOCIATED workers
affinity is not touched and this might be a problem down the line for
isolated setups when the DISASSOCIATED pools still have works to run
after the cpu is offline.
Make sure the workers' affinity is updated every time a workqueue cpumask
changes, so these workers can't break isolation.
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Waiman Long <longman@redhat.com>
Signed-off-by: Lai Jiangshan <jiangshan.ljs@antgroup.com>
---
kernel/workqueue.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 9da679c621dc..ccf03a0ff122 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -6967,6 +6967,10 @@ static int workqueue_apply_unbound_cpumask(const cpumask_var_t unbound_cpumask)
}
if (!ret) {
+ int cpu;
+ struct worker_pool *pool;
+ struct worker *worker;
+
mutex_lock(&wq_pool_attach_mutex);
cpumask_copy(wq_unbound_cpumask, unbound_cpumask);
/* rescuer needs to respect cpumask changes when it is not attached */
@@ -6974,6 +6978,15 @@ static int workqueue_apply_unbound_cpumask(const cpumask_var_t unbound_cpumask)
if (wq->rescuer && !wq->rescuer->pool)
unbind_worker(wq->rescuer);
}
+ /* DISASSOCIATED worker needs to respect wq_unbound_cpumask */
+ for_each_possible_cpu(cpu) {
+ for_each_cpu_worker_pool(pool, cpu) {
+ if (!(pool->flags & POOL_DISASSOCIATED))
+ continue;
+ for_each_pool_worker(worker, pool)
+ unbind_worker(worker);
+ }
+ }
mutex_unlock(&wq_pool_attach_mutex);
}
return ret;
--
2.19.1.6.gb485710b
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 3/3] workqueue: Init rescuer's affinities as wq_unbound_cpumask
2025-11-17 3:09 [PATCH 0/3] workqueue: Cleanup affnity for detached/DISASSOCIATED workers Lai Jiangshan
2025-11-17 3:09 ` [PATCH 1/3] workqueue: Update the rescuer's affinity only when it is detached Lai Jiangshan
2025-11-17 3:09 ` [PATCH 2/3] workqueue: Let DISASSOCIATED workers follow unbound wq cpumask changes Lai Jiangshan
@ 2025-11-17 3:09 ` Lai Jiangshan
2025-11-20 20:32 ` [PATCH 0/3] workqueue: Cleanup affnity for detached/DISASSOCIATED workers Tejun Heo
3 siblings, 0 replies; 5+ messages in thread
From: Lai Jiangshan @ 2025-11-17 3:09 UTC (permalink / raw)
To: linux-kernel
Cc: Lai Jiangshan, Juri Lelli, Waiman Long, Tejun Heo, Lai Jiangshan
From: Lai Jiangshan <jiangshan.ljs@antgroup.com>
The affinity to set to the rescuers should be consistent in all paths
when a rescuer is in detached state. The affinity could be either
wq_unbound_cpumask or unbound_effective_cpumask(wq).
Related paths:
rescuer's worker_detach_from_pool()
update wq_unbound_cpumask
update wq's cpumask
init_rescuer()
Both affinities are Ok as long as they are consistent in all paths.
In the commit 449b31ad2937 ("workqueue: Init rescuer's affinities as
the wq's effective cpumask") makes init_rescuer use
unbound_effective_cpumask(wq) which is consistent with then
apply_wqattrs_commit().
But using unbound_effective_cpumask(wq) requres much more code to
maintain the consistency, and it doesn't make much sense since the
affinity is only effective when the rescuer is not processing works.
wq_unbound_cpumask is more favorable.
So apply_wqattrs_commit() and the path of "updating wq's cpumask" had
been changed to not update the rescuer's affinity, and both the paths
of "updating wq_unbound_cpumask" and "rescuer's
worker_detach_from_pool()" had been changed to use wq_unbound_cpumask.
Now, make init_rescuer() use wq_unbound_cpumask for rescuer's affinity
and make all the paths consistent.
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Waiman Long <longman@redhat.com>
Signed-off-by: Lai Jiangshan <jiangshan.ljs@antgroup.com>
---
kernel/workqueue.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index ccf03a0ff122..acec76a22ce4 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -5644,10 +5644,13 @@ static int init_rescuer(struct workqueue_struct *wq)
}
wq->rescuer = rescuer;
- if (wq->flags & WQ_UNBOUND)
- kthread_bind_mask(rescuer->task, unbound_effective_cpumask(wq));
+
+ /* initial cpumask is consistent with the detached rescuer and unbind_worker() */
+ if (cpumask_intersects(wq_unbound_cpumask, cpu_active_mask))
+ kthread_bind_mask(rescuer->task, wq_unbound_cpumask);
else
kthread_bind_mask(rescuer->task, cpu_possible_mask);
+
wake_up_process(rescuer->task);
return 0;
--
2.19.1.6.gb485710b
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH 0/3] workqueue: Cleanup affnity for detached/DISASSOCIATED workers
2025-11-17 3:09 [PATCH 0/3] workqueue: Cleanup affnity for detached/DISASSOCIATED workers Lai Jiangshan
` (2 preceding siblings ...)
2025-11-17 3:09 ` [PATCH 3/3] workqueue: Init rescuer's affinities as wq_unbound_cpumask Lai Jiangshan
@ 2025-11-20 20:32 ` Tejun Heo
3 siblings, 0 replies; 5+ messages in thread
From: Tejun Heo @ 2025-11-20 20:32 UTC (permalink / raw)
To: Lai Jiangshan; +Cc: linux-kernel, Lai Jiangshan, Juri Lelli, Waiman Long
On Mon, Nov 17, 2025 at 11:09:10AM +0800, Lai Jiangshan wrote:
> Lai Jiangshan (3):
> workqueue: Update the rescuer's affinity only when it is detached
> workqueue: Let DISASSOCIATED workers follow unbound wq cpumask changes
> workqueue: Init rescuer's affinities as wq_unbound_cpumask
Applied 1-3 to wq/for-6.19.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 5+ messages in thread