Skip to content

Commit 2d0a7ec

Browse files
committed
pm: device_runtime: Use its own queue
Device runtime is using the system workqueue to do operations that are mostly blockers (suspend a device). This should not happen. This commit defines a 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 766122f commit 2d0a7ec

File tree

4 files changed

+42
-2
lines changed

4 files changed

+42
-2
lines changed

subsys/pm/Kconfig

+20
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,26 @@ config PM_DEVICE_RUNTIME
101101
enabled, devices can be suspended or resumed based on the device
102102
usage even while the CPU or system is running.
103103

104+
if PM_DEVICE_RUNTIME
105+
config PM_DEVICE_RUNTIME_WQ_STACK_SIZE
106+
int "Stack size for pm runtime async workqueue"
107+
default 1024
108+
help
109+
Defines the size of the stack on the workqueue used for
110+
async operations.
111+
112+
config PM_DEVICE_RUNTIME_WQ_PRIO
113+
int "PM device runtime workqueue priority. Should be pre-emptible."
114+
default 0
115+
range 0 NUM_PREEMPT_PRIORITIES
116+
117+
config PM_DEVICE_RUNTIME_WQ_INIT_PRIO
118+
int "PM device runtime workqueue init priority"
119+
default 50
120+
help
121+
Init priority level to setup the device runtime workqueue.
122+
endif # PM_DEVICE_RUNTIME
123+
104124
config PM_DEVICE_SHELL
105125
bool "Device Power Management shell"
106126
depends on SHELL

subsys/pm/device_runtime.c

+20-1
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,9 @@ LOG_MODULE_DECLARE(pm_device, CONFIG_PM_DEVICE_LOG_LEVEL);
1920
#define PM_DOMAIN(_pm) NULL
2021
#endif
2122

23+
K_THREAD_STACK_DEFINE(pm_device_runtime_stack, CONFIG_PM_DEVICE_RUNTIME_WQ_STACK_SIZE);
24+
static struct k_work_q pm_device_runtime_wq;
25+
2226
#define EVENT_STATE_ACTIVE BIT(PM_DEVICE_STATE_ACTIVE)
2327
#define EVENT_STATE_SUSPENDED BIT(PM_DEVICE_STATE_SUSPENDED)
2428

@@ -79,7 +83,7 @@ static int runtime_suspend(const struct device *dev, bool async,
7983
if (async) {
8084
/* queue suspend */
8185
pm->base.state = PM_DEVICE_STATE_SUSPENDING;
82-
(void)k_work_schedule(&pm->work, delay);
86+
(void)k_work_schedule_for_queue(&pm_device_runtime_wq, &pm->work, delay);
8387
} else {
8488
/* suspend now */
8589
ret = pm->base.action_cb(pm->dev, PM_DEVICE_ACTION_SUSPEND);
@@ -569,3 +573,18 @@ int pm_device_runtime_usage(const struct device *dev)
569573

570574
return dev->pm_base->usage;
571575
}
576+
577+
static int pm_device_runtime_wq_init(void)
578+
{
579+
const struct k_work_queue_config cfg = {.name = "PM DEVICE RUNTIME WQ"};
580+
581+
k_work_queue_init(&pm_device_runtime_wq);
582+
583+
k_work_queue_start(&pm_device_runtime_wq, pm_device_runtime_stack,
584+
K_THREAD_STACK_SIZEOF(pm_device_runtime_stack),
585+
CONFIG_PM_DEVICE_RUNTIME_WQ_PRIO, &cfg);
586+
587+
return 0;
588+
}
589+
590+
SYS_INIT(pm_device_runtime_wq_init, POST_KERNEL, CONFIG_PM_DEVICE_RUNTIME_WQ_INIT_PRIO);

tests/subsys/pm/device_runtime_api/prj.conf

+1
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

+1-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ ZTEST(device_runtime_api, test_api)
200200
*/
201201
k_thread_create(&get_runner_td, get_runner_stack,
202202
K_THREAD_STACK_SIZEOF(get_runner_stack), get_runner,
203-
NULL, NULL, NULL, CONFIG_SYSTEM_WORKQUEUE_PRIORITY, 0,
203+
NULL, NULL, NULL, CONFIG_PM_DEVICE_RUNTIME_WQ_PRIO, 0,
204204
K_NO_WAIT);
205205
k_yield();
206206

0 commit comments

Comments
 (0)