* [PATCH v2 0/4] replace old wq(s), add WQ_PERCPU to alloc_workqueue
@ 2025-11-03 15:57 Marco Crivellari
2025-11-03 15:57 ` [PATCH v2 1/4] drm/amdgpu: replace use of system_unbound_wq with system_dfl_wq Marco Crivellari
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Marco Crivellari @ 2025-11-03 15:57 UTC (permalink / raw)
To: linux-kernel, amd-gfx, dri-devel
Cc: Tejun Heo, Lai Jiangshan, Frederic Weisbecker,
Sebastian Andrzej Siewior, Marco Crivellari, Michal Hocko,
Alex Deucher, Christian Konig, David Airlie, Simona Vetter,
Philip Yang
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 these specific workloads have no benefits from a per-cpu wq,
both have been replaced with system_dfl_wq.
2) [P 3] WQ_PERCPU added to alloc_workqueue (amdfk)
This change make sure alloc_workqueue in amd/amdfkd is unbound,
explicitly adding WQ_UNBOUND to the alloc_workqueue() user.
3) [P 4] 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!
---
Changes in v2:
- system_wq replaced with system_dfl_wq instead of system_percpu_wq, because
a per-cpu workload is not strictly needed.
- use WQ_UNBOUND instead of WQ_PERCPU, because this workload will benefit
from unbound work.
- commits log integrated with commits about recent Workqueue API changes.
- work rebased on v6.18-rc4
Marco Crivellari (4):
drm/amdgpu: replace use of system_unbound_wq with system_dfl_wq
drm/amdgpu: replace use of system_wq with system_dfl_wq
amd/amdkfd: add WQ_UNBOUND to alloc_workqueue users
drm/radeon: add WQ_PERCPU to alloc_workqueue users
drivers/gpu/drm/amd/amdgpu/aldebaran.c | 2 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 6 +++---
drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c | 2 +-
drivers/gpu/drm/amd/amdkfd/kfd_process.c | 3 ++-
drivers/gpu/drm/radeon/radeon_display.c | 3 ++-
5 files changed, 9 insertions(+), 7 deletions(-)
--
2.51.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 1/4] drm/amdgpu: replace use of system_unbound_wq with system_dfl_wq
2025-11-03 15:57 [PATCH v2 0/4] replace old wq(s), add WQ_PERCPU to alloc_workqueue Marco Crivellari
@ 2025-11-03 15:57 ` Marco Crivellari
2025-11-03 15:57 ` [PATCH v2 2/4] drm/amdgpu: replace use of system_wq " Marco Crivellari
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Marco Crivellari @ 2025-11-03 15:57 UTC (permalink / raw)
To: linux-kernel, amd-gfx, dri-devel
Cc: Tejun Heo, Lai Jiangshan, Frederic Weisbecker,
Sebastian Andrzej Siewior, Marco Crivellari, Michal Hocko,
Alex Deucher, Christian Konig, David Airlie, Simona Vetter,
Philip Yang
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.
The above change introduced in the Workqueue API has been introduced by:
commit 128ea9f6ccfb ("workqueue: Add system_percpu_wq and system_dfl_wq")
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/gpu/drm/amd/amdgpu/aldebaran.c | 2 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/aldebaran.c b/drivers/gpu/drm/amd/amdgpu/aldebaran.c
index 9569dc16dd3d..7957e6c4c416 100644
--- a/drivers/gpu/drm/amd/amdgpu/aldebaran.c
+++ b/drivers/gpu/drm/amd/amdgpu/aldebaran.c
@@ -175,7 +175,7 @@ aldebaran_mode2_perform_reset(struct amdgpu_reset_control *reset_ctl,
list_for_each_entry(tmp_adev, reset_device_list, reset_list) {
/* For XGMI run all resets in parallel to speed up the process */
if (tmp_adev->gmc.xgmi.num_physical_nodes > 1) {
- if (!queue_work(system_unbound_wq,
+ if (!queue_work(system_dfl_wq,
&tmp_adev->reset_cntl->reset_work))
r = -EALREADY;
} else
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 3d032c4e2dce..041ee35684ed 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -6040,7 +6040,7 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
/* For XGMI run all resets in parallel to speed up the process */
if (tmp_adev->gmc.xgmi.num_physical_nodes > 1) {
- if (!queue_work(system_unbound_wq,
+ if (!queue_work(system_dfl_wq,
&tmp_adev->xgmi_reset_work))
r = -EALREADY;
} else
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c
index 28c4ad62f50e..9c4631608526 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c
@@ -116,7 +116,7 @@ static int amdgpu_reset_xgmi_reset_on_init_perform_reset(
/* Mode1 reset needs to be triggered on all devices together */
list_for_each_entry(tmp_adev, reset_device_list, reset_list) {
/* For XGMI run all resets in parallel to speed up the process */
- if (!queue_work(system_unbound_wq, &tmp_adev->xgmi_reset_work))
+ if (!queue_work(system_dfl_wq, &tmp_adev->xgmi_reset_work))
r = -EALREADY;
if (r) {
dev_err(tmp_adev->dev,
--
2.51.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 2/4] drm/amdgpu: replace use of system_wq with system_dfl_wq
2025-11-03 15:57 [PATCH v2 0/4] replace old wq(s), add WQ_PERCPU to alloc_workqueue Marco Crivellari
2025-11-03 15:57 ` [PATCH v2 1/4] drm/amdgpu: replace use of system_unbound_wq with system_dfl_wq Marco Crivellari
@ 2025-11-03 15:57 ` Marco Crivellari
2025-11-03 15:57 ` [PATCH v2 3/4] amd/amdkfd: add WQ_UNBOUND to alloc_workqueue users Marco Crivellari
2025-11-03 15:57 ` [PATCH v2 4/4] drm/radeon: add WQ_PERCPU " Marco Crivellari
3 siblings, 0 replies; 5+ messages in thread
From: Marco Crivellari @ 2025-11-03 15:57 UTC (permalink / raw)
To: linux-kernel, amd-gfx, dri-devel
Cc: Tejun Heo, Lai Jiangshan, Frederic Weisbecker,
Sebastian Andrzej Siewior, Marco Crivellari, Michal Hocko,
Alex Deucher, Christian Konig, David Airlie, Simona Vetter,
Philip Yang
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 is the per-cpu workqueue, replaced by system_percpu_wq. This
specific workload does not benefit from a per-cpu workqueue, so use the
new unbound workqueue instead (system_dfl_wq).
The above change introduced in the Workqueue API has been introduced by:
commit 128ea9f6ccfb ("workqueue: Add system_percpu_wq and system_dfl_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/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 041ee35684ed..fc61802444b2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -4805,7 +4805,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
}
/* must succeed. */
amdgpu_ras_resume(adev);
- queue_delayed_work(system_wq, &adev->delayed_init_work,
+ queue_delayed_work(system_dfl_wq, &adev->delayed_init_work,
msecs_to_jiffies(AMDGPU_RESUME_MS));
}
@@ -5335,7 +5335,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool notify_clients)
if (r)
goto exit;
- queue_delayed_work(system_wq, &adev->delayed_init_work,
+ queue_delayed_work(system_dfl_wq, &adev->delayed_init_work,
msecs_to_jiffies(AMDGPU_RESUME_MS));
exit:
if (amdgpu_sriov_vf(adev)) {
--
2.51.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 3/4] amd/amdkfd: add WQ_UNBOUND to alloc_workqueue users
2025-11-03 15:57 [PATCH v2 0/4] replace old wq(s), add WQ_PERCPU to alloc_workqueue Marco Crivellari
2025-11-03 15:57 ` [PATCH v2 1/4] drm/amdgpu: replace use of system_unbound_wq with system_dfl_wq Marco Crivellari
2025-11-03 15:57 ` [PATCH v2 2/4] drm/amdgpu: replace use of system_wq " Marco Crivellari
@ 2025-11-03 15:57 ` Marco Crivellari
2025-11-03 15:57 ` [PATCH v2 4/4] drm/radeon: add WQ_PERCPU " Marco Crivellari
3 siblings, 0 replies; 5+ messages in thread
From: Marco Crivellari @ 2025-11-03 15:57 UTC (permalink / raw)
To: linux-kernel, amd-gfx, dri-devel
Cc: Tejun Heo, Lai Jiangshan, Frederic Weisbecker,
Sebastian Andrzej Siewior, Marco Crivellari, Michal Hocko,
Alex Deucher, Christian Konig, David Airlie, Simona Vetter,
Philip Yang
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.
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.
Because of that, add WQ_UNBOUND to alloc_workqueue users to make sure
they are unbound.
The above change introduced in the Workqueue API has been introduced by:
commit 930c2ea566af ("workqueue: Add new WQ_PERCPU flag")
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/gpu/drm/amd/amdkfd/kfd_process.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
index ddfe30c13e9d..a41ebf257756 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
@@ -690,7 +690,8 @@ void kfd_procfs_del_queue(struct queue *q)
int kfd_process_create_wq(void)
{
if (!kfd_process_wq)
- kfd_process_wq = alloc_workqueue("kfd_process_wq", 0, 0);
+ kfd_process_wq = alloc_workqueue("kfd_process_wq", WQ_UNBOUND,
+ 0);
if (!kfd_restore_wq)
kfd_restore_wq = alloc_ordered_workqueue("kfd_restore_wq",
WQ_FREEZABLE);
--
2.51.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 4/4] drm/radeon: add WQ_PERCPU to alloc_workqueue users
2025-11-03 15:57 [PATCH v2 0/4] replace old wq(s), add WQ_PERCPU to alloc_workqueue Marco Crivellari
` (2 preceding siblings ...)
2025-11-03 15:57 ` [PATCH v2 3/4] amd/amdkfd: add WQ_UNBOUND to alloc_workqueue users Marco Crivellari
@ 2025-11-03 15:57 ` Marco Crivellari
3 siblings, 0 replies; 5+ messages in thread
From: Marco Crivellari @ 2025-11-03 15:57 UTC (permalink / raw)
To: linux-kernel, amd-gfx, dri-devel
Cc: Tejun Heo, Lai Jiangshan, Frederic Weisbecker,
Sebastian Andrzej Siewior, Marco Crivellari, Michal Hocko,
Alex Deucher, Christian Konig, David Airlie, Simona Vetter,
Philip Yang
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.
The above change introduced in the Workqueue API has been introduced by:
commit 930c2ea566af ("workqueue: Add new WQ_PERCPU flag")
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/gpu/drm/radeon/radeon_display.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 351b9dfcdad8..3c8aa5274c51 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -687,7 +687,8 @@ static void radeon_crtc_init(struct drm_device *dev, int index)
if (radeon_crtc == NULL)
return;
- radeon_crtc->flip_queue = alloc_workqueue("radeon-crtc", WQ_HIGHPRI, 0);
+ radeon_crtc->flip_queue = alloc_workqueue("radeon-crtc",
+ WQ_HIGHPRI | WQ_PERCPU, 0);
if (!radeon_crtc->flip_queue) {
kfree(radeon_crtc);
return;
--
2.51.1
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-11-03 15:58 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-11-03 15:57 [PATCH v2 0/4] replace old wq(s), add WQ_PERCPU to alloc_workqueue Marco Crivellari
2025-11-03 15:57 ` [PATCH v2 1/4] drm/amdgpu: replace use of system_unbound_wq with system_dfl_wq Marco Crivellari
2025-11-03 15:57 ` [PATCH v2 2/4] drm/amdgpu: replace use of system_wq " Marco Crivellari
2025-11-03 15:57 ` [PATCH v2 3/4] amd/amdkfd: add WQ_UNBOUND to alloc_workqueue users Marco Crivellari
2025-11-03 15:57 ` [PATCH v2 4/4] drm/radeon: add WQ_PERCPU " Marco Crivellari
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®