mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Breno Leitao <leitao@debian.org>
To: Tejun Heo <tj@kernel.org>, Lai Jiangshan <jiangshanlai@gmail.com>
Cc: linux-kernel@vger.kernel.org, marco.crivellari@suse.com,
	 Breno Leitao <leitao@debian.org>,
	kernel-team@meta.com
Subject: [PATCH wq/for-7.5 v4 0/2] workqueue: Keep max_active and percpu_max_active in sync
Date: Thu, 29 Oct 2026 05:33:44 -0700	[thread overview]
Message-ID: <20261029-wq_final-v4-0-2985ea9f24fd@debian.org> (raw)

Commit 27db9dd7f84f3a ("workqueue: Give percpu workqueues their own
max_active") gave the percpu backend a limit of its own, so a workqueue
now carries both percpu_max_active and max_active.

__alloc_workqueue() only ever sets the pair matching the backend the
workqueue is created on, so the other stays at zero for its lifetime.

Nothing reads "the other scope" max_active today, so this is groundwork
rather than a fix.

Two patches. The first moves the initial limit setup out of
__alloc_workqueue() into wq_init_max_active().

The second sets both domains rather than one, according to Tejun's
recommendation:

  U = unbound max_active, the system-wide target
  L = unbound min_active, the floor on each node
  P = percpu_max_active, the limit on each CPU
  N = online CPUs in the effective unbound mask, at least 1

  Setting P:
    U = min(P * N, WQ_MAX_ACTIVE)
    L = P

  Setting U:
    L = min(L, U)
    P = max(DIV_ROUND_UP(U, N), L)

  Setting L:
    L = clamp(L, 0, U)
    P = max(DIV_ROUND_UP(U, N), L)

It rederives the other domain when the cpumask changes and once CPU
topology is known, as workqueues created before smp_init() count only
the boot CPU.

This shouldn't change the behaviour of workqueue for now, but keeps the
groundwork correct for the PERCPU affinity scope work it's meant to
enable.

Signed-off-by: Breno Leitao <leitao@debian.org>
---
Changes in v4:
- Folded the topology rescale (v3 3/3) into patch 2 (Tejun)
- Added wq_rescale_max_active(): it derives the other domain from the
  backend's own saved limits and publishes both through
  wq_adjust_max_active(). The setters, apply_wqattrs_commit() and
  workqueue_init_topology() call it, so the topology pass no longer
  passes a derived limit back in, resets min_active or writes the live
  limits directly (Tejun)
- Rederive in apply_wqattrs_commit() so N follows cpumask changes, and
  set only the backend's own limits in wq_init_max_active() (Tejun)
- Test WQ_UNBOUND in wq_nr_effective_cpus() instead of installed_pwq()
  (Tejun)
- Pair the READ_ONCE() in wq_user_max_active() with WRITE_ONCE() (Tejun)
- Reworded the wq_adjust_max_active() comment as a contract (Tejun)
- Patch 2 changelog: spelled out the conversions, explained the
  wq_user_max_active() readers and what is not resampled, dropped the
  CM/RCU wording (Tejun)
- Dropped the PS from patch 1's changelog (Tejun)
- Rebased on wq/for-7.5
- Link to v3: https://patch.msgid.link/20261009-wq_final-v3-0-eb0b095b9de3@debian.org

Changes in v3:
- Dropped the silly percpu_concurrency_managed attribute patch.
- Fixed N to come from the workqueue's own unbound_effective_cpumask()
- Added a patch rederiving both domains once workqueue_init_topology()
  knows the real CPU count.
- Handled BH in one place: wq_init_max_active() sets the limits of a BH
  workqueue through wq_init_bh_max_active() and returns, instead of
  giving BH its own branch further down (Tejun)
- Set min_active to percpu_max_active when deriving from a percpu limit
  instead of min(percpu_max_active, max_active), as max_active can never
  be lower (Tejun)
- Changelog of patch 2 now refers to the new PERCPU affinity scope
  rather than WQ_AFFN_CPU (Tejun)
- Link to v2: https://patch.msgid.link/20260925-wq_final-v2-0-860ee052169e@debian.org

Changes in v2:
- Cut the series down to the three patches that change nothing
  observable. The runtime scaling, the affinity scopes, the backend
  rework, the concurrency management attribute and the sysfs files are
  all held back.
- Set both max_active domains instead of holding them equal, deriving
  one from the other rather than duplicating the value (Tejun)
- Link to v1:
  https://patch.msgid.link/20260918-wq_final-v1-0-5c43c08a26bc@debian.org

---
Breno Leitao (2):
      workqueue: Move the initial max_active setup into a helper
      workqueue: Keep the limits of both max_active domains current

 kernel/workqueue.c | 186 ++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 141 insertions(+), 45 deletions(-)
---
base-commit: e92304919f8104ef1452a6389fc54311e857b953
base-tree: git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git for-7.5
change-id: 20260914-wq_final-bcfbcd3b0f79

Best regards,
--  
Breno Leitao <leitao@debian.org>


             reply	other threads:[~2026-10-29 12:36 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-29 12:33 Breno Leitao [this message]
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

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=20261029-wq_final-v4-0-2985ea9f24fd@debian.org \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®