* [PATCH 1/5] ACPI: scan: replace use of system_unbound_wq with system_dfl_wq
2025-10-30 15:47 [PATCH 0/5] replace old wq(s), added WQ_PERCPU to alloc_workqueue Marco Crivellari
@ 2025-10-30 15:47 ` Marco Crivellari
2025-10-30 15:47 ` [PATCH 2/5] ACPI: OSL: replace use of system_wq with system_percpu_wq Marco Crivellari
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Marco Crivellari @ 2025-10-30 15:47 UTC (permalink / raw)
To: linux-kernel, linux-acpi
Cc: Tejun Heo, Lai Jiangshan, Frederic Weisbecker,
Sebastian Andrzej Siewior, Marco Crivellari, Michal Hocko,
Rafael J . Wysocki, Len Brown
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 consistency cannot be addressed without refactoring the API.
system_unbound_wq should be the default workqueue so as not to enforce
locality constraints for random work whenever it's not required.
Adding system_dfl_wq to encourage its use when unbound work should be used.
The old system_unbound_wq will be kept for a few release cycles.
Suggested-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Marco Crivellari <marco.crivellari@suse.com>
---
drivers/acpi/scan.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index ef16d58b2949..e0c0b5a50d26 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -2397,7 +2397,7 @@ static bool acpi_scan_clear_dep_queue(struct acpi_device *adev)
* initial enumeration of devices is complete, put it into the unbound
* workqueue.
*/
- queue_work(system_unbound_wq, &cdw->work);
+ queue_work(system_dfl_wq, &cdw->work);
return true;
}
--
2.51.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 2/5] ACPI: OSL: replace use of system_wq with system_percpu_wq
2025-10-30 15:47 [PATCH 0/5] replace old wq(s), added WQ_PERCPU to alloc_workqueue Marco Crivellari
2025-10-30 15:47 ` [PATCH 1/5] ACPI: scan: replace use of system_unbound_wq with system_dfl_wq Marco Crivellari
@ 2025-10-30 15:47 ` Marco Crivellari
2025-10-30 15:47 ` [PATCH 3/5] ACPI: EC: WQ_PERCPU added to alloc_workqueue users Marco Crivellari
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Marco Crivellari @ 2025-10-30 15:47 UTC (permalink / raw)
To: linux-kernel, linux-acpi
Cc: Tejun Heo, Lai Jiangshan, Frederic Weisbecker,
Sebastian Andrzej Siewior, Marco Crivellari, Michal Hocko,
Rafael J . Wysocki, Len Brown
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 consistency cannot be addressed without refactoring the API.
system_wq should be the per-cpu workqueue, yet in this name nothing makes
that clear, so replace system_wq with system_percpu_wq.
The old wq (system_wq) will be kept for a few release cycles.
Suggested-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Marco Crivellari <marco.crivellari@suse.com>
---
drivers/acpi/osl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 5ff343096ece..a79a5d47bdb8 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -398,7 +398,7 @@ static void acpi_os_drop_map_ref(struct acpi_ioremap *map)
list_del_rcu(&map->list);
INIT_RCU_WORK(&map->track.rwork, acpi_os_map_remove);
- queue_rcu_work(system_wq, &map->track.rwork);
+ queue_rcu_work(system_percpu_wq, &map->track.rwork);
}
/**
--
2.51.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 3/5] ACPI: EC: WQ_PERCPU added to alloc_workqueue users
2025-10-30 15:47 [PATCH 0/5] replace old wq(s), added WQ_PERCPU to alloc_workqueue Marco Crivellari
2025-10-30 15:47 ` [PATCH 1/5] ACPI: scan: replace use of system_unbound_wq with system_dfl_wq Marco Crivellari
2025-10-30 15:47 ` [PATCH 2/5] ACPI: OSL: replace use of system_wq with system_percpu_wq Marco Crivellari
@ 2025-10-30 15:47 ` Marco Crivellari
2025-10-30 15:47 ` [PATCH 4/5] ACPI: OSL: " Marco Crivellari
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Marco Crivellari @ 2025-10-30 15:47 UTC (permalink / raw)
To: linux-kernel, linux-acpi
Cc: Tejun Heo, Lai Jiangshan, Frederic Weisbecker,
Sebastian Andrzej Siewior, Marco Crivellari, Michal Hocko,
Rafael J . Wysocki, Len Brown
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 adds a new WQ_PERCPU flag to explicitly request
alloc_workqueue() to be per-cpu when WQ_UNBOUND has not been specified.
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.
Once migration is complete, WQ_UNBOUND can be removed and unbound will
become the implicit default.
Suggested-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Marco Crivellari <marco.crivellari@suse.com>
---
drivers/acpi/ec.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 7855bbf752b1..59b3d50ff01e 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -2294,7 +2294,8 @@ static int acpi_ec_init_workqueues(void)
ec_wq = alloc_ordered_workqueue("kec", 0);
if (!ec_query_wq)
- ec_query_wq = alloc_workqueue("kec_query", 0, ec_max_queries);
+ ec_query_wq = alloc_workqueue("kec_query", WQ_PERCPU,
+ ec_max_queries);
if (!ec_wq || !ec_query_wq) {
acpi_ec_destroy_workqueues();
--
2.51.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 4/5] ACPI: OSL: WQ_PERCPU added to alloc_workqueue users
2025-10-30 15:47 [PATCH 0/5] replace old wq(s), added WQ_PERCPU to alloc_workqueue Marco Crivellari
` (2 preceding siblings ...)
2025-10-30 15:47 ` [PATCH 3/5] ACPI: EC: WQ_PERCPU added to alloc_workqueue users Marco Crivellari
@ 2025-10-30 15:47 ` Marco Crivellari
2025-10-30 15:47 ` [PATCH 5/5] ACPI: thermal: " Marco Crivellari
2025-11-03 17:47 ` [PATCH 0/5] replace old wq(s), added WQ_PERCPU to alloc_workqueue Rafael J. Wysocki
5 siblings, 0 replies; 8+ messages in thread
From: Marco Crivellari @ 2025-10-30 15:47 UTC (permalink / raw)
To: linux-kernel, linux-acpi
Cc: Tejun Heo, Lai Jiangshan, Frederic Weisbecker,
Sebastian Andrzej Siewior, Marco Crivellari, Michal Hocko,
Rafael J . Wysocki, Len Brown
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 adds a new WQ_PERCPU flag to explicitly request
alloc_workqueue() to be per-cpu when WQ_UNBOUND has not been specified.
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.
Once migration is complete, WQ_UNBOUND can be removed and unbound will
become the implicit default.
Suggested-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Marco Crivellari <marco.crivellari@suse.com>
---
drivers/acpi/osl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index a79a5d47bdb8..05393a7315fe 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -1694,8 +1694,8 @@ acpi_status __init acpi_os_initialize(void)
acpi_status __init acpi_os_initialize1(void)
{
- kacpid_wq = alloc_workqueue("kacpid", 0, 1);
- kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 0);
+ kacpid_wq = alloc_workqueue("kacpid", WQ_PERCPU, 1);
+ kacpi_notify_wq = alloc_workqueue("kacpi_notify", WQ_PERCPU, 0);
kacpi_hotplug_wq = alloc_ordered_workqueue("kacpi_hotplug", 0);
BUG_ON(!kacpid_wq);
BUG_ON(!kacpi_notify_wq);
--
2.51.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 5/5] ACPI: thermal: WQ_PERCPU added to alloc_workqueue users
2025-10-30 15:47 [PATCH 0/5] replace old wq(s), added WQ_PERCPU to alloc_workqueue Marco Crivellari
` (3 preceding siblings ...)
2025-10-30 15:47 ` [PATCH 4/5] ACPI: OSL: " Marco Crivellari
@ 2025-10-30 15:47 ` Marco Crivellari
2025-11-03 17:47 ` [PATCH 0/5] replace old wq(s), added WQ_PERCPU to alloc_workqueue Rafael J. Wysocki
5 siblings, 0 replies; 8+ messages in thread
From: Marco Crivellari @ 2025-10-30 15:47 UTC (permalink / raw)
To: linux-kernel, linux-acpi
Cc: Tejun Heo, Lai Jiangshan, Frederic Weisbecker,
Sebastian Andrzej Siewior, Marco Crivellari, Michal Hocko,
Rafael J . Wysocki, Len Brown, Zhang Rui
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 adds a new WQ_PERCPU flag to explicitly request
alloc_workqueue() to be per-cpu when WQ_UNBOUND has not been specified.
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.
Once migration is complete, WQ_UNBOUND can be removed and unbound will
become the implicit default.
Suggested-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Marco Crivellari <marco.crivellari@suse.com>
CC: Zhang Rui <rui.zhang@intel.com>
---
drivers/acpi/thermal.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 8537395b417b..a511f9ea0267 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -1060,7 +1060,8 @@ static int __init acpi_thermal_init(void)
}
acpi_thermal_pm_queue = alloc_workqueue("acpi_thermal_pm",
- WQ_HIGHPRI | WQ_MEM_RECLAIM, 0);
+ WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_PERCPU,
+ 0);
if (!acpi_thermal_pm_queue)
return -ENODEV;
--
2.51.0
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH 0/5] replace old wq(s), added WQ_PERCPU to alloc_workqueue
2025-10-30 15:47 [PATCH 0/5] replace old wq(s), added WQ_PERCPU to alloc_workqueue Marco Crivellari
` (4 preceding siblings ...)
2025-10-30 15:47 ` [PATCH 5/5] ACPI: thermal: " Marco Crivellari
@ 2025-11-03 17:47 ` Rafael J. Wysocki
2025-11-04 8:58 ` Marco Crivellari
5 siblings, 1 reply; 8+ messages in thread
From: Rafael J. Wysocki @ 2025-11-03 17:47 UTC (permalink / raw)
To: Marco Crivellari
Cc: linux-kernel, linux-acpi, Tejun Heo, Lai Jiangshan,
Frederic Weisbecker, Sebastian Andrzej Siewior, Michal Hocko,
Rafael J . Wysocki, Len Brown
On Thu, Oct 30, 2025 at 4:47 PM Marco Crivellari
<marco.crivellari@suse.com> wrote:
>
> Hi,
>
> === 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 consistency cannot be addressed without refactoring the API.
>
> === Recent changes to the WQ API ===
>
> The following, address the recent changes in the Workqueue API:
>
> - commit 128ea9f6ccfb ("workqueue: Add system_percpu_wq and system_dfl_wq")
> - commit 930c2ea566af ("workqueue: Add new WQ_PERCPU flag")
>
> The old workqueues will be removed in a future release cycle.
>
> === Introduced Changes by this series ===
>
> 1) [P 1-2] Replace uses of system_wq and system_unbound_wq
>
> system_wq is a per-CPU workqueue, but his name is not clear.
> system_unbound_wq is to be used when locality is not required.
>
> Because of that, system_wq has been replaced with system_percpu_wq, and
> system_unbound_wq has been replaced with system_dfl_wq.
>
> 2) [P 3-4-5] WQ_PERCPU added to alloc_workqueue()
>
> This change adds a new WQ_PERCPU flag to explicitly request
> alloc_workqueue() to be per-cpu when WQ_UNBOUND has not been specified.
>
>
> Thanks!
>
> Marco Crivellari (5):
> ACPI: scan: replace use of system_unbound_wq with system_dfl_wq
> ACPI: OSL: replace use of system_wq with system_percpu_wq
> ACPI: EC: WQ_PERCPU added to alloc_workqueue users
> ACPI: OSL: WQ_PERCPU added to alloc_workqueue users
> ACPI: thermal: WQ_PERCPU added to alloc_workqueue users
>
> drivers/acpi/ec.c | 3 ++-
> drivers/acpi/osl.c | 6 +++---
> drivers/acpi/scan.c | 2 +-
> drivers/acpi/thermal.c | 3 ++-
> 4 files changed, 8 insertions(+), 6 deletions(-)
>
> --
All applied as 6.19 material with minor tweaks in some subjects.
Thanks!
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH 0/5] replace old wq(s), added WQ_PERCPU to alloc_workqueue
2025-11-03 17:47 ` [PATCH 0/5] replace old wq(s), added WQ_PERCPU to alloc_workqueue Rafael J. Wysocki
@ 2025-11-04 8:58 ` Marco Crivellari
0 siblings, 0 replies; 8+ messages in thread
From: Marco Crivellari @ 2025-11-04 8:58 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: linux-kernel, linux-acpi, Tejun Heo, Lai Jiangshan,
Frederic Weisbecker, Sebastian Andrzej Siewior, Michal Hocko,
Len Brown
On Mon, Nov 3, 2025 at 6:47 PM Rafael J. Wysocki <rafael@kernel.org> wrote:
>[...]
> All applied as 6.19 material with minor tweaks in some subjects.
>
> Thanks!
Many thanks Rafael!
--
Marco Crivellari
L3 Support Engineer, Technology & Product
^ permalink raw reply [flat|nested] 8+ messages in thread