* [PATCH 0/1] wifi: libertas: add WQ_PERCPU to alloc_workqueue users
@ 2025-09-22 10:24 Marco Crivellari
2025-09-22 10:24 ` [PATCH 1/1] wifi: libertas: WQ_PERCPU added " Marco Crivellari
0 siblings, 1 reply; 4+ messages in thread
From: Marco Crivellari @ 2025-09-22 10:24 UTC (permalink / raw)
To: linux-kernel, linux-wireless
Cc: Tejun Heo, Lai Jiangshan, Frederic Weisbecker,
Sebastian Andrzej Siewior, Marco Crivellari, Michal Hocko,
Johannes Berg, Francesco Dolcini, Brian Norris, Sascha Hauer,
Kalle Valo, Dr . David Alan Gilbert, Jeff Chen, Stefan Kerkmann
Hi!
Below is a summary of a discussion about the Workqueue API and cpu isolation
considerations. Details and more information are available here:
"workqueue: Always use wq_select_unbound_cpu() for WORK_CPU_UNBOUND."
https://lore.kernel.org/all/20250221112003.1dSuoGyc@linutronix.de/
=== Current situation: problems ===
Let's consider a nohz_full system with isolated CPUs: wq_unbound_cpumask is
set to the housekeeping CPUs, for !WQ_UNBOUND the local CPU is selected.
This leads to different scenarios if a work item is scheduled on an isolated
CPU where "delay" value is 0 or greater then 0:
schedule_delayed_work(, 0);
This will be handled by __queue_work() that will queue the work item on the
current local (isolated) CPU, while:
schedule_delayed_work(, 1);
Will move the timer on an housekeeping CPU, and schedule the work there.
Currently if a user enqueue a work item using schedule_delayed_work() the
used wq is "system_wq" (per-cpu wq) while queue_delayed_work() use
WORK_CPU_UNBOUND (used when a cpu is not specified). The same applies to
schedule_work() that is using system_wq and queue_work(), that makes use
again of WORK_CPU_UNBOUND.
This lack of consistentcy cannot be addressed without refactoring the API.
=== Plan and future plans ===
This patchset is the first stone on a refactoring needed in order to
address the points aforementioned; it will have a positive impact also
on the cpu isolation, in the long term, moving away percpu workqueue in
favor to an unbound model.
These are the main steps:
1) API refactoring (that this patch is introducing)
- Make more clear and uniform the system wq names, both per-cpu and
unbound. This to avoid any possible confusion on what should be
used.
- Introduction of WQ_PERCPU: this flag is the complement of WQ_UNBOUND,
introduced in this patchset and used on all the callers that are not
currently using WQ_UNBOUND.
WQ_UNBOUND will be removed in a future release cycle.
Most users don't need to be per-cpu, because they don't have
locality requirements, because of that, a next future step will be
make "unbound" the default behavior.
2) Check who really needs to be per-cpu
- Remove the WQ_PERCPU flag when is not strictly required.
3) Add a new API (prefer local cpu)
- There are users that don't require a local execution, like mentioned
above; despite that, local execution yeld to performance gain.
This new API will prefer the local execution, without requiring it.
=== Introduced Changes by this series ===
1) [P 1] add WQ_PERCPU to alloc_workqueue() users
Every alloc_workqueue() caller should use one among WQ_PERCPU or
WQ_UNBOUND.
WQ_UNBOUND will be removed in a next release cycle.
Thanks!
Marco Crivellari (1):
wifi: libertas: WQ_PERCPU added to alloc_workqueue users
drivers/net/wireless/marvell/libertas/if_sdio.c | 3 ++-
drivers/net/wireless/marvell/libertas/if_spi.c | 3 ++-
drivers/net/wireless/marvell/libertas_tf/main.c | 2 +-
3 files changed, 5 insertions(+), 3 deletions(-)
--
2.51.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/1] wifi: libertas: WQ_PERCPU added to alloc_workqueue users
2025-09-22 10:24 [PATCH 0/1] wifi: libertas: add WQ_PERCPU to alloc_workqueue users Marco Crivellari
@ 2025-09-22 10:24 ` Marco Crivellari
2025-09-22 11:33 ` Johannes Berg
0 siblings, 1 reply; 4+ messages in thread
From: Marco Crivellari @ 2025-09-22 10:24 UTC (permalink / raw)
To: linux-kernel, linux-wireless
Cc: Tejun Heo, Lai Jiangshan, Frederic Weisbecker,
Sebastian Andrzej Siewior, Marco Crivellari, Michal Hocko,
Johannes Berg, Francesco Dolcini, Brian Norris, Sascha Hauer,
Kalle Valo, Dr . David Alan Gilbert, Jeff Chen, Stefan Kerkmann
Currently if a user enqueue a work item using schedule_delayed_work() the
used wq is "system_wq" (per-cpu wq) while queue_delayed_work() use
WORK_CPU_UNBOUND (used when a cpu is not specified). The same applies to
schedule_work() that is using system_wq and queue_work(), that makes use
again of WORK_CPU_UNBOUND.
This lack of consistentcy cannot be addressed without refactoring the API.
alloc_workqueue() treats all queues as per-CPU by default, while unbound
workqueues must opt-in via WQ_UNBOUND.
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.
This change add a new WQ_PERCPU flag, to explicitly request the use of
the per-CPU behavior. Both flags coexist for one release cycle to allow
callers to transition their calls.
Once migration is complete, WQ_UNBOUND can be removed and unbound will
become the implicit default.
With the introduction of the WQ_PERCPU flag (equivalent to !WQ_UNBOUND),
any alloc_workqueue() caller that doesn’t explicitly specify WQ_UNBOUND
must now use WQ_PERCPU.
All existing users have been updated accordingly.
Suggested-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Marco Crivellari <marco.crivellari@suse.com>
---
drivers/net/wireless/marvell/libertas/if_sdio.c | 3 ++-
drivers/net/wireless/marvell/libertas/if_spi.c | 3 ++-
drivers/net/wireless/marvell/libertas_tf/main.c | 2 +-
3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/marvell/libertas/if_sdio.c b/drivers/net/wireless/marvell/libertas/if_sdio.c
index 524034699972..1e29e80cad61 100644
--- a/drivers/net/wireless/marvell/libertas/if_sdio.c
+++ b/drivers/net/wireless/marvell/libertas/if_sdio.c
@@ -1181,7 +1181,8 @@ static int if_sdio_probe(struct sdio_func *func,
spin_lock_init(&card->lock);
INIT_LIST_HEAD(&card->packets);
- card->workqueue = alloc_workqueue("libertas_sdio", WQ_MEM_RECLAIM, 0);
+ card->workqueue = alloc_workqueue("libertas_sdio",
+ WQ_MEM_RECLAIM | WQ_PERCPU, 0);
if (unlikely(!card->workqueue)) {
ret = -ENOMEM;
goto err_queue;
diff --git a/drivers/net/wireless/marvell/libertas/if_spi.c b/drivers/net/wireless/marvell/libertas/if_spi.c
index b722a6587fd3..699bae8971f8 100644
--- a/drivers/net/wireless/marvell/libertas/if_spi.c
+++ b/drivers/net/wireless/marvell/libertas/if_spi.c
@@ -1153,7 +1153,8 @@ static int if_spi_probe(struct spi_device *spi)
priv->fw_ready = 1;
/* Initialize interrupt handling stuff. */
- card->workqueue = alloc_workqueue("libertas_spi", WQ_MEM_RECLAIM, 0);
+ card->workqueue = alloc_workqueue("libertas_spi",
+ WQ_MEM_RECLAIM | WQ_PERCPU, 0);
if (!card->workqueue) {
err = -ENOMEM;
goto remove_card;
diff --git a/drivers/net/wireless/marvell/libertas_tf/main.c b/drivers/net/wireless/marvell/libertas_tf/main.c
index d1067874428f..c51091e7c6c6 100644
--- a/drivers/net/wireless/marvell/libertas_tf/main.c
+++ b/drivers/net/wireless/marvell/libertas_tf/main.c
@@ -708,7 +708,7 @@ EXPORT_SYMBOL_GPL(lbtf_bcn_sent);
static int __init lbtf_init_module(void)
{
lbtf_deb_enter(LBTF_DEB_MAIN);
- lbtf_wq = alloc_workqueue("libertastf", WQ_MEM_RECLAIM, 0);
+ lbtf_wq = alloc_workqueue("libertastf", WQ_MEM_RECLAIM | WQ_PERCPU, 0);
if (lbtf_wq == NULL) {
printk(KERN_ERR "libertastf: couldn't create workqueue\n");
return -ENOMEM;
--
2.51.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 1/1] wifi: libertas: WQ_PERCPU added to alloc_workqueue users
2025-09-22 10:24 ` [PATCH 1/1] wifi: libertas: WQ_PERCPU added " Marco Crivellari
@ 2025-09-22 11:33 ` Johannes Berg
2025-09-22 13:32 ` Marco Crivellari
0 siblings, 1 reply; 4+ messages in thread
From: Johannes Berg @ 2025-09-22 11:33 UTC (permalink / raw)
To: Marco Crivellari, linux-kernel, linux-wireless
Cc: Tejun Heo, Lai Jiangshan, Frederic Weisbecker,
Sebastian Andrzej Siewior, Michal Hocko, Francesco Dolcini,
Brian Norris, Sascha Hauer, Kalle Valo, Dr . David Alan Gilbert,
Jeff Chen, Stefan Kerkmann
On Mon, 2025-09-22 at 12:24 +0200, Marco Crivellari wrote:
>
> With the introduction of the WQ_PERCPU flag (equivalent to !WQ_UNBOUND),
> any alloc_workqueue() caller that doesn’t explicitly specify WQ_UNBOUND
> must now use WQ_PERCPU.
Which I guess forces a decision, and should be kept for a few releases,
but ... is "keep what it did" really the right decision in all places?
It seems to me that for instance for libertas here, there really is no
reason to be CPU bound?
johannes
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 1/1] wifi: libertas: WQ_PERCPU added to alloc_workqueue users
2025-09-22 11:33 ` Johannes Berg
@ 2025-09-22 13:32 ` Marco Crivellari
0 siblings, 0 replies; 4+ messages in thread
From: Marco Crivellari @ 2025-09-22 13:32 UTC (permalink / raw)
To: Johannes Berg
Cc: linux-kernel, linux-wireless, Tejun Heo, Lai Jiangshan,
Frederic Weisbecker, Sebastian Andrzej Siewior, Michal Hocko,
Francesco Dolcini, Brian Norris, Sascha Hauer, Kalle Valo,
Dr . David Alan Gilbert, Jeff Chen, Stefan Kerkmann
On Mon, Sep 22, 2025 at 1:33 PM Johannes Berg <johannes@sipsolutions.net> wrote:
> On Mon, 2025-09-22 at 12:24 +0200, Marco Crivellari wrote:
> >
> > With the introduction of the WQ_PERCPU flag (equivalent to !WQ_UNBOUND),
> > any alloc_workqueue() caller that doesn’t explicitly specify WQ_UNBOUND
> > must now use WQ_PERCPU.
>
> Which I guess forces a decision, and should be kept for a few releases,
> but ... is "keep what it did" really the right decision in all places?
> It seems to me that for instance for libertas here, there really is no
> reason to be CPU bound?
Hello Johannes,
This change has been massively introduced only to make explicit that one
of the two flags must be used (preserving the old behavior), where WQ_UNBOUND
was not present..
Going for each subsystem and checking who really needs to be per-cpu would
have been a future step.
I've already sent a v2 for a few other subsystems changing the old behavior.
I haven't seen per-cpu work, so removing the WQ_PERCPU flag and using
explicitly WQ_UNBOUND instead, is not a problem, also for libertas.
Thank you!
--
Marco Crivellari
L3 Support Engineer, Technology & Product
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-09-22 13:33 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-22 10:24 [PATCH 0/1] wifi: libertas: add WQ_PERCPU to alloc_workqueue users Marco Crivellari
2025-09-22 10:24 ` [PATCH 1/1] wifi: libertas: WQ_PERCPU added " Marco Crivellari
2025-09-22 11:33 ` Johannes Berg
2025-09-22 13:32 ` Marco Crivellari
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox