[PATCH 3/5] workqueue: make the default pwq optional

From: Breno Leitao

Date: Wed Aug 19 2026 - 10:45:31 EST


apply_wqattrs_prepare() always creates a dfl_pwq, the fallback a CPU
uses when it has no pwq of its own. This is a CPU unbound field, so, we
don't need it for the per cpu affinity version of workqueue.

A percpu workqueue has no use for one. Skip the allocation for
a WQ_PERCPU workqueue and skip installing what was not allocated.

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

diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 7feefe0a4a5ff..8fac93574becb 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -5513,15 +5513,18 @@ apply_wqattrs_prepare(struct workqueue_struct *wq,

/*
* If something goes wrong during CPU up/down, we'll fall back to
- * the default pwq covering whole @attrs->cpumask. Always create
- * it even if we don't use it immediately.
+ * the default pwq covering whole @attrs->cpumask. Create it even
+ * if we don't use it immediately. A percpu workqueue has a pwq on
+ * every possible CPU and never falls back, so it has no default.
*/
copy_workqueue_attrs(new_attrs, attrs);
wqattrs_actualize_cpumask(new_attrs, unbound_cpumask);
cpumask_copy(new_attrs->__pod_cpumask, new_attrs->cpumask);
- ctx->dfl_pwq = alloc_unbound_pwq(wq, new_attrs);
- if (!ctx->dfl_pwq)
- goto out_free;
+ if (!(wq->flags & WQ_PERCPU)) {
+ ctx->dfl_pwq = alloc_unbound_pwq(wq, new_attrs);
+ if (!ctx->dfl_pwq)
+ goto out_free;
+ }

for_each_possible_cpu(cpu) {
if (new_attrs->ordered) {
@@ -5573,7 +5576,8 @@ static void apply_wqattrs_commit(struct apply_wqattrs_ctx *ctx)
for_each_possible_cpu(cpu)
ctx->pwq_tbl[cpu] = install_unbound_pwq(ctx->wq, cpu,
ctx->pwq_tbl[cpu]);
- ctx->dfl_pwq = install_unbound_pwq(ctx->wq, -1, ctx->dfl_pwq);
+ if (ctx->dfl_pwq)
+ ctx->dfl_pwq = install_unbound_pwq(ctx->wq, -1, ctx->dfl_pwq);

/* update node_nr_active->max, which only unbound workqueues have */
if (ctx->wq->flags & WQ_UNBOUND)

--
2.53.0-Meta