From: Breno Leitao <leitao@debian.org>
To: Tejun Heo <tj@kernel.org>
Cc: Lai Jiangshan <jiangshanlai@gmail.com>,
Marco Crivellari <marco.crivellari@suse.com>,
linux-kernel@vger.kernel.org, kernel-team@meta.com
Subject: Re: [PATCH wq/for-7.5 v4 2/2] workqueue: Keep the limits of both max_active domains current
Date: Fri, 6 Nov 2026 07:10:56 -0800 [thread overview]
Message-ID: <au3smjfpG3_ic2Me@gmail.com> (raw)
In-Reply-To: <56db993fd60efc4892e1cf1e38ba48e1@kernel.org>
Hello Tejun,
On Thu, Oct 29, 2026 at 09:07:56AM -1000, Tejun Heo wrote:
> On Thu, Oct 29, 2026 at 05:33:46AM -0700, Breno Leitao wrote:
> > The planned PERCPU affinity scope will let a workqueue switch backends
> > through its attributes, and a switch should land on a sensible limit.
> > Derive the other domain whenever the limits of the backend in use are
> > set.
>
> I think the two domains should be separated completely at the interface,
> each with a fixed meaning regardless of the backend in use, as discussed in
> the RFC thread. Otherwise, it gets too confusing. On the sysfs side, the
> existing max_active would become compat only, with max_active_percpu and
> max_active_total as the main interfaces. The kernel API would match:
> workqueue_set_max_active_percpu() and workqueue_set_max_active_total(),
> with the conversion to the other domain done in those setters.
>
> This patch only makes sense as a way to get there, and it's difficult to
> tell whether it's in line with that without the actual conversion.
Agree, I tried to separate them make it easier to review, but, it was
not ideal. I will pause this for now, and come back with the actual
coversion.
> > +static int wq_user_max_active(struct workqueue_struct *wq)
> > +{
> > + if (wq->flags & WQ_UNBOUND)
> > + return READ_ONCE(wq->saved_max_active);
> > +
> > + return READ_ONCE(wq->saved_percpu_max_active);
> > +}
>
> Maybe write it as "if () return X; else return Y;"? Neither branch is the
> special case. The same goes for wq_nr_effective_cpus() and wherever the
> choice between the two domains ends up.
Ack. I was following netdev's approch of having `if (foo) return bar; return
baz`.
>
> > - if (!from_cancel && (wq->saved_max_active == 1 || wq->rescuer))
> > + if (!from_cancel && (wq_user_max_active(wq) == 1 || wq->rescuer))
>
> I wonder whether this condition is right. It should trigger when the
> effective max_active is 1, whether the workqueue is in percpu or unbound
> mode, but this only looks at the domain the workqueue was created in. Once a
> workqueue can switch, the limit in force may be the derived one, and that
> can reach 1 even for a workqueue created with a higher max_active, e.g.
> after min_active is lowered.
>
> Maybe this means there should be further restrictions on how low max_active
> can be pushed. For example, a workqueue created with max_active > 1
> shouldn't be driven down to 1 in either domain, however it gets adjusted, so
> that whether a workqueue can end up at 1 is decided by the max_active it was
> created with. One way could be a floor of 2 in the setters and the
> derivation for workqueues created with max_active > 1, while one created
> with max_active 1 can still go back to 1, e.g. after being raised. That's
> just one option though.
Sure. Should the floor cover min_active as well?
> > +static int wq_nr_online_cpus(const struct cpumask *mask)
> > +{
> > + return max(cpumask_weight_and(mask, cpu_online_mask), 1);
> > +}
> > ...
> > +static int wq_scale_to_percpu(int max_active, int min_active, int nr_cpus)
> > +{
> > + return max(DIV_ROUND_UP(max_active, nr_cpus), min_active);
> > +}
>
> I'm not sure single-use helpers without any comment are an improvement. They
> seem to obscure more than they help. Maybe open-code them with comments
> explaining why? That would include wq_nr_online_cpus(),
> wq_nr_effective_cpus(), wq_scale_to_unbound(), wq_scale_to_percpu() and
> wq_init_bh_max_active().
Ack.
> > +/*
> > + * Derive the saved limits of the max_active domain @wq's backend doesn't use
> > + * from those of the one it does, with the current number of usable CPUs, and
> > + * publish both.
> > + */
> > +static void wq_rescale_max_active(struct workqueue_struct *wq)
>
> Would it make sense to make the rescale a part of wq_adjust_max_active() and
> use that everywhere, on init, any config change, freeze and so on? With the
> separate setters, the workqueue could remember which domain was set last,
> and the derivation would always go from that one with the current CPU count,
> so calling it again couldn't ratchet the limits. BH would stay out, and
> hotplug could keep using the saved values.
Yes, that is simpler, and it fixes the ratchet I raised on v3.
wq_rescale_max_active() goes away. The workqueue records which domain
was set last, at creation and in each setter, and wq_adjust_max_active()
derives the other one from it with the current CPU count before
publishing both.
BH stays out, and hotplug only calls wq_update_node_max_active(), so it
keeps using the saved values.
Thanks for the review,
--breno
next prev parent reply other threads:[~2026-11-06 15:11 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-29 12:33 [PATCH wq/for-7.5 v4 0/2] workqueue: Keep max_active and percpu_max_active in sync Breno Leitao
2026-10-29 12:33 ` [PATCH wq/for-7.5 v4 1/2] workqueue: Move the initial max_active setup into a helper Breno Leitao
2026-10-29 12:33 ` [PATCH wq/for-7.5 v4 2/2] workqueue: Keep the limits of both max_active domains current Breno Leitao
2026-10-29 19:07 ` Tejun Heo
2026-11-06 15:10 ` Breno Leitao [this message]
2026-11-06 17:42 ` Tejun Heo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=au3smjfpG3_ic2Me@gmail.com \
--to=leitao@debian.org \
--cc=jiangshanlai@gmail.com \
--cc=kernel-team@meta.com \
--cc=linux-kernel@vger.kernel.org \
--cc=marco.crivellari@suse.com \
--cc=tj@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.