mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Marco Crivellari <marco.crivellari@suse.com>
To: linux-kernel@vger.kernel.org
Cc: Tejun Heo <tj@kernel.org>, Lai Jiangshan <jiangshanlai@gmail.com>,
	Frederic Weisbecker <frederic@kernel.org>,
	Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
	Marco Crivellari <marco.crivellari@suse.com>,
	Michal Hocko <mhocko@suse.com>, Breno Leitao <leitao@debian.org>
Subject: [PATCH v5 1/2] workqueue: Make alloc_workqueue() unbound by default
Date: Mon,  2 Nov 2026 12:00:46 +0100	[thread overview]
Message-ID: <20261102110047.115375-2-marco.crivellari@suse.com> (raw)
In-Reply-To: <20261102110047.115375-1-marco.crivellari@suse.com>

Currently alloc_workqueue() ensures that one among WQ_PERCPU or WQ_UNBOUND
is present. Now every user has one among these two flags and if nothing
is specified the default is WQ_PERCPU.

This default is suboptimal: most workloads benefit from unbound queues,
allowing the scheduler to place worker threads where they're needed and
reducing noise when CPUs are isolated.

In order to achieve the future goal of removing WQ_UNBOUND from the code,
start changing the default behavior making alloc_workqueue() act this way:

  - if WQ_PERCPU and WQ_UNBOUND are present: remove WQ_PERCPU (as before)
  - if neither are present: add WQ_UNBOUND

BH workqueues (WQ_BH) are always per-CPU and can't be unbound, so
WQ_PERCPU is now unconditionally forced for them before the above
defaulting logic runs.

The WARN_ONCE() when neither flag is present has been removed: from now
on, every alloc_workqueue() user without WQ_PERCPU will be considered
unbound.

The defaulting now happens before the workqueue is allocated, since
unbound workqueues need the node_nr_active[] array. Doing it before the
WQ_POWER_EFFICIENT override also makes sure that callers passing both
WQ_PERCPU and WQ_UNBOUND get the warning regardless of
wq_power_efficient.

Update the WQ_POWER_EFFICIENT comment accordingly.

Link: https://lore.kernel.org/all/20250221112003.1dSuoGyc@linutronix.de/
Suggested-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Marco Crivellari <marco.crivellari@suse.com>
Reviewed-by: Breno Leitao <leitao@debian.org>
---
 include/linux/workqueue.h |  4 ++--
 kernel/workqueue.c        | 32 ++++++++++++++++----------------
 2 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index c8a36423cb34..da18debf424d 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -392,8 +392,8 @@ enum wq_flags {
 	 * turn may lead to more scheduling choices which are sub-optimal
 	 * in terms of power consumption.
 	 *
-	 * Workqueues marked with WQ_POWER_EFFICIENT are per-cpu by default
-	 * but become unbound if workqueue.power_efficient kernel param is
+	 * Workqueues marked with WQ_POWER_EFFICIENT and WQ_PERCPU become
+	 * unbound if workqueue.power_efficient kernel param is
 	 * specified.  Per-cpu workqueues which are identified to
 	 * contribute significantly to power-consumption are identified and
 	 * marked with this flag and enabling the power_efficient mode
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index c1cb328bce3c..747c48582ceb 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -5892,6 +5892,7 @@ static struct workqueue_struct *__alloc_workqueue(const char *fmt,
 						  unsigned int flags,
 						  int max_active, va_list args)
 {
+	bool wq_dropped_percpu = false;
 	struct workqueue_struct *wq;
 	size_t wq_size;
 	int name_len;
@@ -5901,6 +5902,18 @@ static struct workqueue_struct *__alloc_workqueue(const char *fmt,
 			return NULL;
 		if (WARN_ON_ONCE(max_active))
 			return NULL;
+		flags |= WQ_PERCPU;
+	}
+
+	/*
+	 * Do this before computing wq_size and before WQ_POWER_EFFICIENT
+	 * can drop WQ_PERCPU.
+	 */
+	if (!(flags & (WQ_UNBOUND | WQ_PERCPU))) {
+		flags |= WQ_UNBOUND;
+	} else if (unlikely((flags & WQ_PERCPU) && (flags & WQ_UNBOUND))) {
+		flags &= ~WQ_PERCPU;
+		wq_dropped_percpu = true;
 	}
 
 	/* see the comment above the definition of WQ_POWER_EFFICIENT */
@@ -5927,22 +5940,9 @@ static struct workqueue_struct *__alloc_workqueue(const char *fmt,
 		pr_warn_once("workqueue: name exceeds WQ_NAME_LEN. Truncating to: %s\n",
 			     wq->name);
 
-	/*
-	 * One among WQ_PERCPU and WQ_UNBOUND must be set, but not both.
-	 * - If neither is set, default to WQ_PERCPU
-	 * - If both are set, default to WQ_UNBOUND
-	 *
-	 * This code can be removed after workqueue are unbound by default
-	 */
-	if (unlikely(!(flags & (WQ_UNBOUND | WQ_PERCPU)))) {
-		WARN_ONCE(1, "workqueue: %s is using neither WQ_PERCPU or WQ_UNBOUND. "
-			  "Setting WQ_PERCPU.\n", wq->name);
-		flags |= WQ_PERCPU;
-	} else if (unlikely((flags & WQ_PERCPU) && (flags & WQ_UNBOUND))) {
-		WARN_ONCE(1, "workqueue: %s uses both WQ_PERCPU and WQ_UNBOUND. "
-			  "Dropped WQ_PERCPU, keeping WQ_UNBOUND.\n", wq->name);
-		flags &= ~WQ_PERCPU;
-	}
+	WARN_ONCE(wq_dropped_percpu,
+		  "workqueue: %s uses both WQ_PERCPU and WQ_UNBOUND. "
+		  "Dropped WQ_PERCPU, keeping WQ_UNBOUND.\n", wq->name);
 
 	if (flags & WQ_BH) {
 		/*
-- 
2.56.0


  reply	other threads:[~2026-11-02 11:00 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-02 11:00 [PATCH v5 0/2] workqueue: Make WQ_UNBOUND the default behavior Marco Crivellari
2026-11-02 11:00 ` Marco Crivellari [this message]
2026-11-02 11:00 ` [PATCH v5 2/2] workqueue: doc: Update WQ_UNBOUND and WQ_BH documentation Marco Crivellari

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=20261102110047.115375-2-marco.crivellari@suse.com \
    --to=marco.crivellari@suse.com \
    --cc=bigeasy@linutronix.de \
    --cc=frederic@kernel.org \
    --cc=jiangshanlai@gmail.com \
    --cc=leitao@debian.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mhocko@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®