From 2581b2b6d20abec5c9072b3cbaa9bdeaba131d7b Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Wed, 19 Aug 2026 07:37:37 -0700 Subject: workqueue: make the default pwq optional 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 Signed-off-by: Tejun Heo --- kernel/workqueue.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'kernel/workqueue.c') diff --git a/kernel/workqueue.c b/kernel/workqueue.c index f4d8cf0b6d51..10c40fe23e97 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -5522,15 +5522,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) { @@ -5582,7 +5585,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) -- cgit v1.2.3