[PATCH wq/for-7.4 v3 3/3] workqueue: Rescale max_active domains once CPU topology is known

From: Breno Leitao

Date: Fri Oct 09 2026 - 09:23:04 EST


wq_init_max_active() derives the domain a workqueue's backend doesn't use
(percpu_max_active for an unbound workqueue, max_active for a percpu one)
from the number of online CPUs at creation time. Workqueues created by
workqueue_init_early() or an early initcall run before smp_init() brings
up the secondary CPUs, so that count is 1 for them, and nothing
recomputes it afterwards.

Redo wq_init_max_active() once workqueue_init_topology() has the real
CPU count, in the same pass that already walks every workqueue to update
per-node max_active. With one CPU online both domains were equal, so
saved_max_active is still the max_active the workqueue was created with
and can be passed back as is.

Signed-off-by: Breno Leitao <leitao@xxxxxxxxxx>
---
kernel/workqueue.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 244a199f2dd61a..dd52a7d0999d17 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -8870,6 +8870,16 @@ void __init workqueue_init_topology(void)
list_for_each_entry(wq, &workqueues, list) {
for_each_online_cpu(cpu)
unbound_wq_update_pwq(wq, cpu);
+
+ /*
+ * wq_init_max_active() ran before smp_init() for these, so
+ * saved_max_active is still their max_active argument. Redo it
+ * now that all CPUs are online.
+ */
+ mutex_lock(&wq->mutex);
+ wq_init_max_active(wq, wq->saved_max_active);
+ mutex_unlock(&wq->mutex);
+
if (wq->flags & WQ_UNBOUND) {
mutex_lock(&wq->mutex);
wq_update_node_max_active(wq, -1);

--
2.53.0-Meta