Skip to content

Commit 7f06746

Browse files
committed
pm: device_runtime: Allow to use a dedicated wq
Device runtime is using the system workqueue to do operations that are mostly blockers (suspend a device). This should not happen. This commit adds an option to use dedicated queue for the device runtime async operations. The test for this API was assuming that the system workqueue priority (which is cooperative) so we need to change the test priority to be lower than the device runtime workqueue priority. Signed-off-by: Flavio Ceolin <[email protected]>
1 parent 6887b58 commit 7f06746

File tree

5 files changed

+86
-2
lines changed

5 files changed

+86
-2
lines changed

subsys/pm/Kconfig

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,51 @@ config PM_DEVICE_RUNTIME
121121
enabled, devices can be suspended or resumed based on the device
122122
usage even while the CPU or system is running.
123123

124+
if PM_DEVICE_RUNTIME
125+
126+
config PM_DEVICE_DRIVER_NEEDS_DEDICATED_WQ
127+
bool
128+
129+
choice PM_DEVICE_RUNTIME_WQ
130+
prompt "Work queue to be used by pm device runtime async"
131+
default PM_DEVICE_RUNTIME_USE_DEDICATED_WQ if PM_DEVICE_DRIVER_NEEDS_DEDICATED_WQ
132+
default PM_DEVICE_RUNTIME_USE_SYSTEM_WQ
133+
134+
config PM_DEVICE_RUNTIME_USE_SYSTEM_WQ
135+
bool "Use the system workqueue"
136+
help
137+
When this option is enabled the power management subsystem will
138+
use the system worqueue instead of defining its own queue.
139+
140+
config PM_DEVICE_RUNTIME_USE_DEDICATED_WQ
141+
bool "Use a dedicated workqueue"
142+
help
143+
When this option is enabled the power management subsystem will
144+
use a dedicated worqueue instead of the system work queue.
145+
146+
if PM_DEVICE_RUNTIME_USE_DEDICATED_WQ
147+
config PM_DEVICE_RUNTIME_DEDICATED_WQ_STACK_SIZE
148+
int "Stack size for pm runtime async workqueue"
149+
default 1024
150+
help
151+
Defines the size of the stack on the workqueue used for
152+
async operations.
153+
154+
config PM_DEVICE_RUNTIME_DEDICATED_WQ_PRIO
155+
int "PM device runtime workqueue priority. Should be pre-emptible."
156+
default SYSTEM_WORKQUEUE_PRIORITY if PM_DEVICE_RUNTIME_USE_SYSTEM_WQ
157+
default 0
158+
159+
config PM_DEVICE_RUNTIME_DEDICATED_WQ_INIT_PRIO
160+
int "PM device runtime workqueue init priority"
161+
default 50
162+
help
163+
Init priority level to setup the device runtime workqueue.
164+
endif #PM_DEVICE_RUNTIME_USE_DEDICATED_WQ
165+
endchoice
166+
167+
endif # PM_DEVICE_RUNTIME
168+
124169
config PM_DEVICE_SHELL
125170
bool "Device Power Management shell"
126171
depends on SHELL

subsys/pm/device_runtime.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/*
22
* Copyright (c) 2018 Intel Corporation.
33
* Copyright (c) 2021 Nordic Semiconductor ASA.
4+
* Copyright (c) 2025 HubbleNetwork.
45
*
56
* SPDX-License-Identifier: Apache-2.0
67
*/
@@ -19,6 +20,11 @@ LOG_MODULE_DECLARE(pm_device, CONFIG_PM_DEVICE_LOG_LEVEL);
1920
#define PM_DOMAIN(_pm) NULL
2021
#endif
2122

23+
#ifdef CONFIG_PM_DEVICE_RUNTIME_USE_DEDICATED_WQ
24+
K_THREAD_STACK_DEFINE(pm_device_runtime_stack, CONFIG_PM_DEVICE_RUNTIME_DEDICATED_WQ_STACK_SIZE);
25+
static struct k_work_q pm_device_runtime_wq;
26+
#endif /* CONFIG_PM_DEVICE_RUNTIME_USE_DEDICATED_WQ */
27+
2228
#define EVENT_STATE_ACTIVE BIT(PM_DEVICE_STATE_ACTIVE)
2329
#define EVENT_STATE_SUSPENDED BIT(PM_DEVICE_STATE_SUSPENDED)
2430

@@ -79,7 +85,11 @@ static int runtime_suspend(const struct device *dev, bool async,
7985
if (async) {
8086
/* queue suspend */
8187
pm->base.state = PM_DEVICE_STATE_SUSPENDING;
88+
#ifdef CONFIG_PM_DEVICE_RUNTIME_USE_SYSTEM_WQ
8289
(void)k_work_schedule(&pm->work, delay);
90+
#else
91+
(void)k_work_schedule_for_queue(&pm_device_runtime_wq, &pm->work, delay);
92+
#endif /* CONFIG_PM_DEVICE_RUNTIME_USE_SYSTEM_WQ */
8393
} else {
8494
/* suspend now */
8595
ret = pm->base.action_cb(pm->dev, PM_DEVICE_ACTION_SUSPEND);
@@ -569,3 +579,23 @@ int pm_device_runtime_usage(const struct device *dev)
569579

570580
return dev->pm_base->usage;
571581
}
582+
583+
#ifdef CONFIG_PM_DEVICE_RUNTIME_USE_DEDICATED_WQ
584+
585+
static int pm_device_runtime_wq_init(void)
586+
{
587+
const struct k_work_queue_config cfg = {.name = "PM DEVICE RUNTIME WQ"};
588+
589+
k_work_queue_init(&pm_device_runtime_wq);
590+
591+
k_work_queue_start(&pm_device_runtime_wq, pm_device_runtime_stack,
592+
K_THREAD_STACK_SIZEOF(pm_device_runtime_stack),
593+
CONFIG_PM_DEVICE_RUNTIME_DEDICATED_WQ_PRIO, &cfg);
594+
595+
return 0;
596+
}
597+
598+
SYS_INIT(pm_device_runtime_wq_init, POST_KERNEL,
599+
CONFIG_PM_DEVICE_RUNTIME_DEDICATED_WQ_INIT_PRIO);
600+
601+
#endif /* CONFIG_PM_DEVICE_RUNTIME_USE_DEDICATED_WQ */

tests/subsys/pm/device_runtime_api/prj.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ CONFIG_PM=y
33
CONFIG_PM_DEVICE=y
44
CONFIG_PM_DEVICE_RUNTIME=y
55
CONFIG_MP_MAX_NUM_CPUS=1
6+
CONFIG_ZTEST_THREAD_PRIORITY=3

tests/subsys/pm/device_runtime_api/src/main.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <zephyr/pm/device_runtime.h>
1010

1111
#include "test_driver.h"
12+
#include "zephyr/sys/util_macro.h"
1213

1314
static const struct device *test_dev;
1415
static struct k_thread get_runner_td;
@@ -200,8 +201,10 @@ ZTEST(device_runtime_api, test_api)
200201
*/
201202
k_thread_create(&get_runner_td, get_runner_stack,
202203
K_THREAD_STACK_SIZEOF(get_runner_stack), get_runner,
203-
NULL, NULL, NULL, CONFIG_SYSTEM_WORKQUEUE_PRIORITY, 0,
204-
K_NO_WAIT);
204+
NULL, NULL, NULL,
205+
COND_CODE_1(CONFIG_PM_DEVICE_RUNTIME_USE_DEDICATED_WQ,
206+
(CONFIG_PM_DEVICE_RUNTIME_DEDICATED_WQ_PRIO),
207+
(CONFIG_SYSTEM_WORKQUEUE_PRIORITY)), 0, K_NO_WAIT);
205208
k_yield();
206209

207210
/* let driver suspend to finish and wait until get_runner finishes

tests/subsys/pm/device_runtime_api/testcase.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,8 @@ tests:
1010
- native_sim
1111
extra_configs:
1212
- CONFIG_TEST_PM_DEVICE_ISR_SAFE=y
13+
pm.device_runtime.async_dedicated_wq.api:
14+
platform_allow:
15+
- native_sim
16+
extra_configs:
17+
- CONFIG_PM_DEVICE_RUNTIME_USE_DEDICATED_WQ=y

0 commit comments

Comments
 (0)