* [PATCH v3 1/6] PM: QoS: Introduce a CPU system wakeup QoS limit
2025-11-21 10:03 [PATCH v3 0/6] PM: QoS: Introduce a CPU system wakeup QoS limit for s2idle Ulf Hansson
@ 2025-11-21 10:03 ` Ulf Hansson
2025-11-25 4:56 ` Dhruva Gole
2025-11-21 10:03 ` [PATCH v3 2/6] pmdomain: Respect the CPU system wakeup QoS limit for s2idle Ulf Hansson
` (6 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Ulf Hansson @ 2025-11-21 10:03 UTC (permalink / raw)
To: Rafael J . Wysocki, linux-pm
Cc: Vincent Guittot, Peter Zijlstra, Kevin Hilman, Pavel Machek,
Len Brown, Daniel Lezcano, Maulik Shah, Prasad Sodagudi,
Dhruva Gole, Deepti Jaggi, Ulf Hansson, linux-kernel
Some platforms supports multiple low power states for CPUs that can be used
when entering system-wide suspend. Currently we are always selecting the
deepest possible state for the CPUs, which can break the system wakeup
latency constraint that may be required for a use case.
Let's take the first step towards addressing this problem, by introducing
an interface for user space, that allows us to specify the CPU system
wakeup QoS limit. Subsequent changes will start taking into account the new
QoS limit.
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
Changes in v3:
- Add Kconfig for the new interface (Rafael).
- Updated commit message.
Changes in v2:
- Renamings to reflect the QoS are limited to CPUs.
- Move code inside "CONFIG_CPU_IDLE".
---
include/linux/pm_qos.h | 9 ++++
kernel/power/Kconfig | 4 ++
kernel/power/qos.c | 106 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 119 insertions(+)
diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h
index 4a69d4af3ff8..6cea4455f867 100644
--- a/include/linux/pm_qos.h
+++ b/include/linux/pm_qos.h
@@ -162,6 +162,15 @@ static inline void cpu_latency_qos_update_request(struct pm_qos_request *req,
static inline void cpu_latency_qos_remove_request(struct pm_qos_request *req) {}
#endif
+#ifdef CONFIG_PM_QOS_CPU_SYSTEM_WAKEUP
+s32 cpu_wakeup_latency_qos_limit(void);
+#else
+static inline s32 cpu_wakeup_latency_qos_limit(void)
+{
+ return PM_QOS_RESUME_LATENCY_NO_CONSTRAINT;
+}
+#endif
+
#ifdef CONFIG_PM
enum pm_qos_flags_status __dev_pm_qos_flags(struct device *dev, s32 mask);
enum pm_qos_flags_status dev_pm_qos_flags(struct device *dev, s32 mask);
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 54a623680019..839e2dbb889e 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -202,6 +202,10 @@ config PM_WAKELOCKS_GC
depends on PM_WAKELOCKS
default y
+config PM_QOS_CPU_SYSTEM_WAKEUP
+ bool "User space interface for CPU system wakeup QoS"
+ depends on CPU_IDLE
+
config PM
bool "Device power management core functionality"
help
diff --git a/kernel/power/qos.c b/kernel/power/qos.c
index 4244b069442e..f7d8064e9adc 100644
--- a/kernel/power/qos.c
+++ b/kernel/power/qos.c
@@ -415,6 +415,105 @@ static struct miscdevice cpu_latency_qos_miscdev = {
.fops = &cpu_latency_qos_fops,
};
+#ifdef CONFIG_PM_QOS_CPU_SYSTEM_WAKEUP
+/* The CPU system wakeup latency QoS. */
+static struct pm_qos_constraints cpu_wakeup_latency_constraints = {
+ .list = PLIST_HEAD_INIT(cpu_wakeup_latency_constraints.list),
+ .target_value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT,
+ .default_value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT,
+ .no_constraint_value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT,
+ .type = PM_QOS_MIN,
+};
+
+/**
+ * cpu_wakeup_latency_qos_limit - Current CPU system wakeup latency QoS limit.
+ *
+ * Returns the current CPU system wakeup latency QoS limit that may have been
+ * requested by user space.
+ */
+s32 cpu_wakeup_latency_qos_limit(void)
+{
+ return pm_qos_read_value(&cpu_wakeup_latency_constraints);
+}
+
+static int cpu_wakeup_latency_qos_open(struct inode *inode, struct file *filp)
+{
+ struct pm_qos_request *req;
+
+ req = kzalloc(sizeof(*req), GFP_KERNEL);
+ if (!req)
+ return -ENOMEM;
+
+ req->qos = &cpu_wakeup_latency_constraints;
+ pm_qos_update_target(req->qos, &req->node, PM_QOS_ADD_REQ,
+ PM_QOS_RESUME_LATENCY_NO_CONSTRAINT);
+ filp->private_data = req;
+
+ return 0;
+}
+
+static int cpu_wakeup_latency_qos_release(struct inode *inode,
+ struct file *filp)
+{
+ struct pm_qos_request *req = filp->private_data;
+
+ filp->private_data = NULL;
+ pm_qos_update_target(req->qos, &req->node, PM_QOS_REMOVE_REQ,
+ PM_QOS_RESUME_LATENCY_NO_CONSTRAINT);
+ kfree(req);
+
+ return 0;
+}
+
+static ssize_t cpu_wakeup_latency_qos_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ s32 value = pm_qos_read_value(&cpu_wakeup_latency_constraints);
+
+ return simple_read_from_buffer(buf, count, f_pos, &value, sizeof(s32));
+}
+
+static ssize_t cpu_wakeup_latency_qos_write(struct file *filp,
+ const char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ struct pm_qos_request *req = filp->private_data;
+ s32 value;
+
+ if (count == sizeof(s32)) {
+ if (copy_from_user(&value, buf, sizeof(s32)))
+ return -EFAULT;
+ } else {
+ int ret;
+
+ ret = kstrtos32_from_user(buf, count, 16, &value);
+ if (ret)
+ return ret;
+ }
+
+ if (value < 0)
+ return -EINVAL;
+
+ pm_qos_update_target(req->qos, &req->node, PM_QOS_UPDATE_REQ, value);
+
+ return count;
+}
+
+static const struct file_operations cpu_wakeup_latency_qos_fops = {
+ .open = cpu_wakeup_latency_qos_open,
+ .release = cpu_wakeup_latency_qos_release,
+ .read = cpu_wakeup_latency_qos_read,
+ .write = cpu_wakeup_latency_qos_write,
+ .llseek = noop_llseek,
+};
+
+static struct miscdevice cpu_wakeup_latency_qos_miscdev = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "cpu_wakeup_latency",
+ .fops = &cpu_wakeup_latency_qos_fops,
+};
+#endif /* CONFIG_PM_QOS_CPU_SYSTEM_WAKEUP */
+
static int __init cpu_latency_qos_init(void)
{
int ret;
@@ -424,6 +523,13 @@ static int __init cpu_latency_qos_init(void)
pr_err("%s: %s setup failed\n", __func__,
cpu_latency_qos_miscdev.name);
+#ifdef CONFIG_PM_QOS_CPU_SYSTEM_WAKEUP
+ ret = misc_register(&cpu_wakeup_latency_qos_miscdev);
+ if (ret < 0)
+ pr_err("%s: %s setup failed\n", __func__,
+ cpu_wakeup_latency_qos_miscdev.name);
+#endif
+
return ret;
}
late_initcall(cpu_latency_qos_init);
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH v3 1/6] PM: QoS: Introduce a CPU system wakeup QoS limit
2025-11-21 10:03 ` [PATCH v3 1/6] PM: QoS: Introduce a CPU system wakeup QoS limit Ulf Hansson
@ 2025-11-25 4:56 ` Dhruva Gole
0 siblings, 0 replies; 16+ messages in thread
From: Dhruva Gole @ 2025-11-25 4:56 UTC (permalink / raw)
To: Ulf Hansson
Cc: Rafael J . Wysocki, linux-pm, Vincent Guittot, Peter Zijlstra,
Kevin Hilman, Pavel Machek, Len Brown, Daniel Lezcano,
Maulik Shah, Prasad Sodagudi, Deepti Jaggi, linux-kernel
On Nov 21, 2025 at 11:03:07 +0100, Ulf Hansson wrote:
> Some platforms supports multiple low power states for CPUs that can be used
> when entering system-wide suspend. Currently we are always selecting the
> deepest possible state for the CPUs, which can break the system wakeup
> latency constraint that may be required for a use case.
>
> Let's take the first step towards addressing this problem, by introducing
> an interface for user space, that allows us to specify the CPU system
> wakeup QoS limit. Subsequent changes will start taking into account the new
> QoS limit.
>
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> ---
>
> Changes in v3:
> - Add Kconfig for the new interface (Rafael).
> - Updated commit message.
>
> Changes in v2:
> - Renamings to reflect the QoS are limited to CPUs.
> - Move code inside "CONFIG_CPU_IDLE".
> ---
> include/linux/pm_qos.h | 9 ++++
> kernel/power/Kconfig | 4 ++
> kernel/power/qos.c | 106 +++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 119 insertions(+)
>
> diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h
> index 4a69d4af3ff8..6cea4455f867 100644
> --- a/include/linux/pm_qos.h
> +++ b/include/linux/pm_qos.h
> @@ -162,6 +162,15 @@ static inline void cpu_latency_qos_update_request(struct pm_qos_request *req,
> static inline void cpu_latency_qos_remove_request(struct pm_qos_request *req) {}
> #endif
>
> +#ifdef CONFIG_PM_QOS_CPU_SYSTEM_WAKEUP
> +s32 cpu_wakeup_latency_qos_limit(void);
> +#else
> +static inline s32 cpu_wakeup_latency_qos_limit(void)
> +{
> + return PM_QOS_RESUME_LATENCY_NO_CONSTRAINT;
> +}
> +#endif
> +
> #ifdef CONFIG_PM
> enum pm_qos_flags_status __dev_pm_qos_flags(struct device *dev, s32 mask);
> enum pm_qos_flags_status dev_pm_qos_flags(struct device *dev, s32 mask);
> diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
> index 54a623680019..839e2dbb889e 100644
> --- a/kernel/power/Kconfig
> +++ b/kernel/power/Kconfig
> @@ -202,6 +202,10 @@ config PM_WAKELOCKS_GC
> depends on PM_WAKELOCKS
> default y
>
> +config PM_QOS_CPU_SYSTEM_WAKEUP
> + bool "User space interface for CPU system wakeup QoS"
> + depends on CPU_IDLE
> +
I see that checkpatch complains here with a warning:
please write a help paragraph that fully describes the config symbol with at least 4 lines
I somewhat agree too, since it's a new and pretty important feature that
we're putting behind this config best to add some help around it.
With that,
Reviewed-by: Dhruva Gole <d-gole@ti.com>
> config PM
> bool "Device power management core functionality"
> help
> diff --git a/kernel/power/qos.c b/kernel/power/qos.c
> index 4244b069442e..f7d8064e9adc 100644
> --- a/kernel/power/qos.c
> +++ b/kernel/power/qos.c
> @@ -415,6 +415,105 @@ static struct miscdevice cpu_latency_qos_miscdev = {
> .fops = &cpu_latency_qos_fops,
> };
>
> +#ifdef CONFIG_PM_QOS_CPU_SYSTEM_WAKEUP
> +/* The CPU system wakeup latency QoS. */
> +static struct pm_qos_constraints cpu_wakeup_latency_constraints = {
> + .list = PLIST_HEAD_INIT(cpu_wakeup_latency_constraints.list),
> + .target_value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT,
> + .default_value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT,
> + .no_constraint_value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT,
> + .type = PM_QOS_MIN,
> +};
> +
> +/**
> + * cpu_wakeup_latency_qos_limit - Current CPU system wakeup latency QoS limit.
> + *
> + * Returns the current CPU system wakeup latency QoS limit that may have been
> + * requested by user space.
> + */
> +s32 cpu_wakeup_latency_qos_limit(void)
> +{
> + return pm_qos_read_value(&cpu_wakeup_latency_constraints);
> +}
> +
> +static int cpu_wakeup_latency_qos_open(struct inode *inode, struct file *filp)
> +{
> + struct pm_qos_request *req;
> +
> + req = kzalloc(sizeof(*req), GFP_KERNEL);
> + if (!req)
> + return -ENOMEM;
> +
> + req->qos = &cpu_wakeup_latency_constraints;
> + pm_qos_update_target(req->qos, &req->node, PM_QOS_ADD_REQ,
> + PM_QOS_RESUME_LATENCY_NO_CONSTRAINT);
> + filp->private_data = req;
> +
> + return 0;
> +}
> +
> +static int cpu_wakeup_latency_qos_release(struct inode *inode,
> + struct file *filp)
> +{
> + struct pm_qos_request *req = filp->private_data;
> +
> + filp->private_data = NULL;
> + pm_qos_update_target(req->qos, &req->node, PM_QOS_REMOVE_REQ,
> + PM_QOS_RESUME_LATENCY_NO_CONSTRAINT);
> + kfree(req);
> +
> + return 0;
> +}
> +
> +static ssize_t cpu_wakeup_latency_qos_read(struct file *filp, char __user *buf,
> + size_t count, loff_t *f_pos)
> +{
> + s32 value = pm_qos_read_value(&cpu_wakeup_latency_constraints);
> +
> + return simple_read_from_buffer(buf, count, f_pos, &value, sizeof(s32));
> +}
> +
> +static ssize_t cpu_wakeup_latency_qos_write(struct file *filp,
> + const char __user *buf,
> + size_t count, loff_t *f_pos)
> +{
> + struct pm_qos_request *req = filp->private_data;
> + s32 value;
> +
> + if (count == sizeof(s32)) {
> + if (copy_from_user(&value, buf, sizeof(s32)))
> + return -EFAULT;
> + } else {
> + int ret;
> +
> + ret = kstrtos32_from_user(buf, count, 16, &value);
> + if (ret)
> + return ret;
> + }
> +
> + if (value < 0)
> + return -EINVAL;
> +
> + pm_qos_update_target(req->qos, &req->node, PM_QOS_UPDATE_REQ, value);
> +
> + return count;
> +}
> +
> +static const struct file_operations cpu_wakeup_latency_qos_fops = {
> + .open = cpu_wakeup_latency_qos_open,
> + .release = cpu_wakeup_latency_qos_release,
> + .read = cpu_wakeup_latency_qos_read,
> + .write = cpu_wakeup_latency_qos_write,
> + .llseek = noop_llseek,
> +};
> +
> +static struct miscdevice cpu_wakeup_latency_qos_miscdev = {
> + .minor = MISC_DYNAMIC_MINOR,
> + .name = "cpu_wakeup_latency",
> + .fops = &cpu_wakeup_latency_qos_fops,
> +};
> +#endif /* CONFIG_PM_QOS_CPU_SYSTEM_WAKEUP */
> +
> static int __init cpu_latency_qos_init(void)
> {
> int ret;
> @@ -424,6 +523,13 @@ static int __init cpu_latency_qos_init(void)
> pr_err("%s: %s setup failed\n", __func__,
> cpu_latency_qos_miscdev.name);
>
> +#ifdef CONFIG_PM_QOS_CPU_SYSTEM_WAKEUP
> + ret = misc_register(&cpu_wakeup_latency_qos_miscdev);
> + if (ret < 0)
> + pr_err("%s: %s setup failed\n", __func__,
> + cpu_wakeup_latency_qos_miscdev.name);
> +#endif
> +
--
Best regards,
Dhruva Gole
Texas Instruments Incorporated
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v3 2/6] pmdomain: Respect the CPU system wakeup QoS limit for s2idle
2025-11-21 10:03 [PATCH v3 0/6] PM: QoS: Introduce a CPU system wakeup QoS limit for s2idle Ulf Hansson
2025-11-21 10:03 ` [PATCH v3 1/6] PM: QoS: Introduce a CPU system wakeup QoS limit Ulf Hansson
@ 2025-11-21 10:03 ` Ulf Hansson
2025-11-25 5:27 ` Dhruva Gole
2025-11-21 10:03 ` [PATCH v3 3/6] pmdomain: Respect the CPU system wakeup QoS limit for cpuidle Ulf Hansson
` (5 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Ulf Hansson @ 2025-11-21 10:03 UTC (permalink / raw)
To: Rafael J . Wysocki, linux-pm
Cc: Vincent Guittot, Peter Zijlstra, Kevin Hilman, Pavel Machek,
Len Brown, Daniel Lezcano, Maulik Shah, Prasad Sodagudi,
Dhruva Gole, Deepti Jaggi, Ulf Hansson, linux-kernel
A CPU system wakeup QoS limit may have been requested by user space. To
avoid breaking this constraint when entering a low power state during
s2idle through genpd, let's extend the corresponding genpd governor for
CPUs. More precisely, during s2idle let the genpd governor select a
suitable domain idle state, by taking into account the QoS limit.
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
Changes in v3:
- Updated the commit message.
Changes in v2:
- Limite the change to the genpd governor for CPUs.
---
drivers/pmdomain/core.c | 10 ++++++++--
drivers/pmdomain/governor.c | 27 +++++++++++++++++++++++++++
include/linux/pm_domain.h | 1 +
3 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index 61c2277c9ce3..4fd546ef0448 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -1425,8 +1425,14 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock,
return;
}
- /* Choose the deepest state when suspending */
- genpd->state_idx = genpd->state_count - 1;
+ if (genpd->gov && genpd->gov->system_power_down_ok) {
+ if (!genpd->gov->system_power_down_ok(&genpd->domain))
+ return;
+ } else {
+ /* Default to the deepest state. */
+ genpd->state_idx = genpd->state_count - 1;
+ }
+
if (_genpd_power_off(genpd, false)) {
genpd->states[genpd->state_idx].rejected++;
return;
diff --git a/drivers/pmdomain/governor.c b/drivers/pmdomain/governor.c
index 39359811a930..bd1b9d66d4a5 100644
--- a/drivers/pmdomain/governor.c
+++ b/drivers/pmdomain/governor.c
@@ -415,9 +415,36 @@ static bool cpu_power_down_ok(struct dev_pm_domain *pd)
return false;
}
+static bool cpu_system_power_down_ok(struct dev_pm_domain *pd)
+{
+ s64 constraint_ns = cpu_wakeup_latency_qos_limit() * NSEC_PER_USEC;
+ struct generic_pm_domain *genpd = pd_to_genpd(pd);
+ int state_idx = genpd->state_count - 1;
+
+ if (!(genpd->flags & GENPD_FLAG_CPU_DOMAIN)) {
+ genpd->state_idx = state_idx;
+ return true;
+ }
+
+ /* Find the deepest state for the latency constraint. */
+ while (state_idx >= 0) {
+ s64 latency_ns = genpd->states[state_idx].power_off_latency_ns +
+ genpd->states[state_idx].power_on_latency_ns;
+
+ if (latency_ns <= constraint_ns) {
+ genpd->state_idx = state_idx;
+ return true;
+ }
+ state_idx--;
+ }
+
+ return false;
+}
+
struct dev_power_governor pm_domain_cpu_gov = {
.suspend_ok = default_suspend_ok,
.power_down_ok = cpu_power_down_ok,
+ .system_power_down_ok = cpu_system_power_down_ok,
};
#endif
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index f67a2cb7d781..93ba0143ca47 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -153,6 +153,7 @@ enum genpd_sync_state {
};
struct dev_power_governor {
+ bool (*system_power_down_ok)(struct dev_pm_domain *domain);
bool (*power_down_ok)(struct dev_pm_domain *domain);
bool (*suspend_ok)(struct device *dev);
};
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH v3 2/6] pmdomain: Respect the CPU system wakeup QoS limit for s2idle
2025-11-21 10:03 ` [PATCH v3 2/6] pmdomain: Respect the CPU system wakeup QoS limit for s2idle Ulf Hansson
@ 2025-11-25 5:27 ` Dhruva Gole
0 siblings, 0 replies; 16+ messages in thread
From: Dhruva Gole @ 2025-11-25 5:27 UTC (permalink / raw)
To: Ulf Hansson
Cc: Rafael J . Wysocki, linux-pm, Vincent Guittot, Peter Zijlstra,
Kevin Hilman, Pavel Machek, Len Brown, Daniel Lezcano,
Maulik Shah, Prasad Sodagudi, Deepti Jaggi, linux-kernel
On Nov 21, 2025 at 11:03:08 +0100, Ulf Hansson wrote:
> A CPU system wakeup QoS limit may have been requested by user space. To
> avoid breaking this constraint when entering a low power state during
> s2idle through genpd, let's extend the corresponding genpd governor for
> CPUs. More precisely, during s2idle let the genpd governor select a
> suitable domain idle state, by taking into account the QoS limit.
>
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Dhruva Gole <d-gole@ti.com>
--
Best regards,
Dhruva Gole
Texas Instruments Incorporated
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v3 3/6] pmdomain: Respect the CPU system wakeup QoS limit for cpuidle
2025-11-21 10:03 [PATCH v3 0/6] PM: QoS: Introduce a CPU system wakeup QoS limit for s2idle Ulf Hansson
2025-11-21 10:03 ` [PATCH v3 1/6] PM: QoS: Introduce a CPU system wakeup QoS limit Ulf Hansson
2025-11-21 10:03 ` [PATCH v3 2/6] pmdomain: Respect the CPU system wakeup QoS limit for s2idle Ulf Hansson
@ 2025-11-21 10:03 ` Ulf Hansson
2025-11-25 5:28 ` Dhruva Gole
2025-11-21 10:03 ` [PATCH v3 4/6] sched: idle: Respect the CPU system wakeup QoS limit for s2idle Ulf Hansson
` (4 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Ulf Hansson @ 2025-11-21 10:03 UTC (permalink / raw)
To: Rafael J . Wysocki, linux-pm
Cc: Vincent Guittot, Peter Zijlstra, Kevin Hilman, Pavel Machek,
Len Brown, Daniel Lezcano, Maulik Shah, Prasad Sodagudi,
Dhruva Gole, Deepti Jaggi, Ulf Hansson, linux-kernel
The CPU system wakeup QoS limit must be respected for the regular cpuidle
state selection. Therefore, let's extend the genpd governor for CPUs to
take the constraint into account when it selects a domain idle state for
the corresponding PM domain.
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
Changes in v3:
- New patch.
---
drivers/pmdomain/governor.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/pmdomain/governor.c b/drivers/pmdomain/governor.c
index bd1b9d66d4a5..05e68680f34b 100644
--- a/drivers/pmdomain/governor.c
+++ b/drivers/pmdomain/governor.c
@@ -351,7 +351,7 @@ static bool cpu_power_down_ok(struct dev_pm_domain *pd)
ktime_t domain_wakeup, next_hrtimer;
ktime_t now = ktime_get();
struct device *cpu_dev;
- s64 cpu_constraint, global_constraint;
+ s64 cpu_constraint, global_constraint, wakeup_constraint;
s64 idle_duration_ns;
int cpu, i;
@@ -362,7 +362,11 @@ static bool cpu_power_down_ok(struct dev_pm_domain *pd)
if (!(genpd->flags & GENPD_FLAG_CPU_DOMAIN))
return true;
+ wakeup_constraint = cpu_wakeup_latency_qos_limit();
global_constraint = cpu_latency_qos_limit();
+ if (global_constraint > wakeup_constraint)
+ global_constraint = wakeup_constraint;
+
/*
* Find the next wakeup for any of the online CPUs within the PM domain
* and its subdomains. Note, we only need the genpd->cpus, as it already
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH v3 3/6] pmdomain: Respect the CPU system wakeup QoS limit for cpuidle
2025-11-21 10:03 ` [PATCH v3 3/6] pmdomain: Respect the CPU system wakeup QoS limit for cpuidle Ulf Hansson
@ 2025-11-25 5:28 ` Dhruva Gole
0 siblings, 0 replies; 16+ messages in thread
From: Dhruva Gole @ 2025-11-25 5:28 UTC (permalink / raw)
To: Ulf Hansson
Cc: Rafael J . Wysocki, linux-pm, Vincent Guittot, Peter Zijlstra,
Kevin Hilman, Pavel Machek, Len Brown, Daniel Lezcano,
Maulik Shah, Prasad Sodagudi, Deepti Jaggi, linux-kernel
On Nov 21, 2025 at 11:03:09 +0100, Ulf Hansson wrote:
> The CPU system wakeup QoS limit must be respected for the regular cpuidle
> state selection. Therefore, let's extend the genpd governor for CPUs to
> take the constraint into account when it selects a domain idle state for
> the corresponding PM domain.
>
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> ---
>
> Changes in v3:
> - New patch.
>
> ---
> drivers/pmdomain/governor.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pmdomain/governor.c b/drivers/pmdomain/governor.c
> index bd1b9d66d4a5..05e68680f34b 100644
> --- a/drivers/pmdomain/governor.c
> +++ b/drivers/pmdomain/governor.c
> @@ -351,7 +351,7 @@ static bool cpu_power_down_ok(struct dev_pm_domain *pd)
> ktime_t domain_wakeup, next_hrtimer;
> ktime_t now = ktime_get();
> struct device *cpu_dev;
> - s64 cpu_constraint, global_constraint;
> + s64 cpu_constraint, global_constraint, wakeup_constraint;
> s64 idle_duration_ns;
> int cpu, i;
>
> @@ -362,7 +362,11 @@ static bool cpu_power_down_ok(struct dev_pm_domain *pd)
> if (!(genpd->flags & GENPD_FLAG_CPU_DOMAIN))
> return true;
>
> + wakeup_constraint = cpu_wakeup_latency_qos_limit();
> global_constraint = cpu_latency_qos_limit();
> + if (global_constraint > wakeup_constraint)
> + global_constraint = wakeup_constraint;
> +
Reviewed-by: Dhruva Gole <d-gole@ti.com>
--
Best regards,
Dhruva Gole
Texas Instruments Incorporated
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v3 4/6] sched: idle: Respect the CPU system wakeup QoS limit for s2idle
2025-11-21 10:03 [PATCH v3 0/6] PM: QoS: Introduce a CPU system wakeup QoS limit for s2idle Ulf Hansson
` (2 preceding siblings ...)
2025-11-21 10:03 ` [PATCH v3 3/6] pmdomain: Respect the CPU system wakeup QoS limit for cpuidle Ulf Hansson
@ 2025-11-21 10:03 ` Ulf Hansson
2025-11-25 5:39 ` Dhruva Gole
2025-11-21 10:03 ` [PATCH v3 5/6] cpuidle: Respect the CPU system wakeup QoS limit for cpuidle Ulf Hansson
` (3 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Ulf Hansson @ 2025-11-21 10:03 UTC (permalink / raw)
To: Rafael J . Wysocki, linux-pm
Cc: Vincent Guittot, Peter Zijlstra, Kevin Hilman, Pavel Machek,
Len Brown, Daniel Lezcano, Maulik Shah, Prasad Sodagudi,
Dhruva Gole, Deepti Jaggi, Ulf Hansson, linux-kernel
A CPU system wakeup QoS limit may have been requested by user space. To
avoid breaking this constraint when entering a low power state during
s2idle, let's start to take into account the QoS limit.
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
Changes in v3:
- Updated commit message and added ack from Peter.
Changes in v2:
- Rework the code to take into account the failure/error path, when we
don't find a s2idle specific state.
---
drivers/cpuidle/cpuidle.c | 12 +++++++-----
include/linux/cpuidle.h | 6 ++++--
kernel/sched/idle.c | 12 +++++++-----
3 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 56132e843c99..c7876e9e024f 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -184,20 +184,22 @@ static noinstr void enter_s2idle_proper(struct cpuidle_driver *drv,
* cpuidle_enter_s2idle - Enter an idle state suitable for suspend-to-idle.
* @drv: cpuidle driver for the given CPU.
* @dev: cpuidle device for the given CPU.
+ * @latency_limit_ns: Idle state exit latency limit
*
* If there are states with the ->enter_s2idle callback, find the deepest of
* them and enter it with frozen tick.
*/
-int cpuidle_enter_s2idle(struct cpuidle_driver *drv, struct cpuidle_device *dev)
+int cpuidle_enter_s2idle(struct cpuidle_driver *drv, struct cpuidle_device *dev,
+ u64 latency_limit_ns)
{
int index;
/*
- * Find the deepest state with ->enter_s2idle present, which guarantees
- * that interrupts won't be enabled when it exits and allows the tick to
- * be frozen safely.
+ * Find the deepest state with ->enter_s2idle present that meets the
+ * specified latency limit, which guarantees that interrupts won't be
+ * enabled when it exits and allows the tick to be frozen safely.
*/
- index = find_deepest_state(drv, dev, U64_MAX, 0, true);
+ index = find_deepest_state(drv, dev, latency_limit_ns, 0, true);
if (index > 0) {
enter_s2idle_proper(drv, dev, index);
local_irq_enable();
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index a9ee4fe55dcf..4073690504a7 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -248,7 +248,8 @@ extern int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
struct cpuidle_device *dev,
u64 latency_limit_ns);
extern int cpuidle_enter_s2idle(struct cpuidle_driver *drv,
- struct cpuidle_device *dev);
+ struct cpuidle_device *dev,
+ u64 latency_limit_ns);
extern void cpuidle_use_deepest_state(u64 latency_limit_ns);
#else
static inline int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
@@ -256,7 +257,8 @@ static inline int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
u64 latency_limit_ns)
{return -ENODEV; }
static inline int cpuidle_enter_s2idle(struct cpuidle_driver *drv,
- struct cpuidle_device *dev)
+ struct cpuidle_device *dev,
+ u64 latency_limit_ns)
{return -ENODEV; }
static inline void cpuidle_use_deepest_state(u64 latency_limit_ns)
{
diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c
index c39b089d4f09..c1c3d0166610 100644
--- a/kernel/sched/idle.c
+++ b/kernel/sched/idle.c
@@ -131,12 +131,13 @@ void __cpuidle default_idle_call(void)
}
static int call_cpuidle_s2idle(struct cpuidle_driver *drv,
- struct cpuidle_device *dev)
+ struct cpuidle_device *dev,
+ u64 max_latency_ns)
{
if (current_clr_polling_and_test())
return -EBUSY;
- return cpuidle_enter_s2idle(drv, dev);
+ return cpuidle_enter_s2idle(drv, dev, max_latency_ns);
}
static int call_cpuidle(struct cpuidle_driver *drv, struct cpuidle_device *dev,
@@ -205,12 +206,13 @@ static void cpuidle_idle_call(void)
u64 max_latency_ns;
if (idle_should_enter_s2idle()) {
+ max_latency_ns = cpu_wakeup_latency_qos_limit() *
+ NSEC_PER_USEC;
- entered_state = call_cpuidle_s2idle(drv, dev);
+ entered_state = call_cpuidle_s2idle(drv, dev,
+ max_latency_ns);
if (entered_state > 0)
goto exit_idle;
-
- max_latency_ns = U64_MAX;
} else {
max_latency_ns = dev->forced_idle_latency_limit_ns;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH v3 4/6] sched: idle: Respect the CPU system wakeup QoS limit for s2idle
2025-11-21 10:03 ` [PATCH v3 4/6] sched: idle: Respect the CPU system wakeup QoS limit for s2idle Ulf Hansson
@ 2025-11-25 5:39 ` Dhruva Gole
0 siblings, 0 replies; 16+ messages in thread
From: Dhruva Gole @ 2025-11-25 5:39 UTC (permalink / raw)
To: Ulf Hansson
Cc: Rafael J . Wysocki, linux-pm, Vincent Guittot, Peter Zijlstra,
Kevin Hilman, Pavel Machek, Len Brown, Daniel Lezcano,
Maulik Shah, Prasad Sodagudi, Deepti Jaggi, linux-kernel
On Nov 21, 2025 at 11:03:10 +0100, Ulf Hansson wrote:
> A CPU system wakeup QoS limit may have been requested by user space. To
> avoid breaking this constraint when entering a low power state during
> s2idle, let's start to take into account the QoS limit.
>
> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> ---
>
> Changes in v3:
> - Updated commit message and added ack from Peter.
>
> Changes in v2:
> - Rework the code to take into account the failure/error path, when we
> don't find a s2idle specific state.
Reviewed-by: Dhruva Gole <d-gole@ti.com>
>
> ---
> drivers/cpuidle/cpuidle.c | 12 +++++++-----
> include/linux/cpuidle.h | 6 ++++--
> kernel/sched/idle.c | 12 +++++++-----
> 3 files changed, 18 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
> index 56132e843c99..c7876e9e024f 100644
> --- a/drivers/cpuidle/cpuidle.c
> +++ b/drivers/cpuidle/cpuidle.c
> @@ -184,20 +184,22 @@ static noinstr void enter_s2idle_proper(struct cpuidle_driver *drv,
> * cpuidle_enter_s2idle - Enter an idle state suitable for suspend-to-idle.
> * @drv: cpuidle driver for the given CPU.
> * @dev: cpuidle device for the given CPU.
> + * @latency_limit_ns: Idle state exit latency limit
> *
> * If there are states with the ->enter_s2idle callback, find the deepest of
> * them and enter it with frozen tick.
> */
> -int cpuidle_enter_s2idle(struct cpuidle_driver *drv, struct cpuidle_device *dev)
> +int cpuidle_enter_s2idle(struct cpuidle_driver *drv, struct cpuidle_device *dev,
> + u64 latency_limit_ns)
> {
> int index;
>
> /*
> - * Find the deepest state with ->enter_s2idle present, which guarantees
> - * that interrupts won't be enabled when it exits and allows the tick to
> - * be frozen safely.
> + * Find the deepest state with ->enter_s2idle present that meets the
> + * specified latency limit, which guarantees that interrupts won't be
> + * enabled when it exits and allows the tick to be frozen safely.
> */
> - index = find_deepest_state(drv, dev, U64_MAX, 0, true);
> + index = find_deepest_state(drv, dev, latency_limit_ns, 0, true);
> if (index > 0) {
> enter_s2idle_proper(drv, dev, index);
> local_irq_enable();
> diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
> index a9ee4fe55dcf..4073690504a7 100644
> --- a/include/linux/cpuidle.h
> +++ b/include/linux/cpuidle.h
> @@ -248,7 +248,8 @@ extern int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
> struct cpuidle_device *dev,
> u64 latency_limit_ns);
> extern int cpuidle_enter_s2idle(struct cpuidle_driver *drv,
> - struct cpuidle_device *dev);
> + struct cpuidle_device *dev,
> + u64 latency_limit_ns);
> extern void cpuidle_use_deepest_state(u64 latency_limit_ns);
> #else
> static inline int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
> @@ -256,7 +257,8 @@ static inline int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
> u64 latency_limit_ns)
> {return -ENODEV; }
> static inline int cpuidle_enter_s2idle(struct cpuidle_driver *drv,
> - struct cpuidle_device *dev)
> + struct cpuidle_device *dev,
> + u64 latency_limit_ns)
> {return -ENODEV; }
> static inline void cpuidle_use_deepest_state(u64 latency_limit_ns)
> {
> diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c
> index c39b089d4f09..c1c3d0166610 100644
> --- a/kernel/sched/idle.c
> +++ b/kernel/sched/idle.c
> @@ -131,12 +131,13 @@ void __cpuidle default_idle_call(void)
> }
>
> static int call_cpuidle_s2idle(struct cpuidle_driver *drv,
> - struct cpuidle_device *dev)
> + struct cpuidle_device *dev,
> + u64 max_latency_ns)
> {
> if (current_clr_polling_and_test())
> return -EBUSY;
>
> - return cpuidle_enter_s2idle(drv, dev);
> + return cpuidle_enter_s2idle(drv, dev, max_latency_ns);
> }
>
> static int call_cpuidle(struct cpuidle_driver *drv, struct cpuidle_device *dev,
> @@ -205,12 +206,13 @@ static void cpuidle_idle_call(void)
> u64 max_latency_ns;
>
> if (idle_should_enter_s2idle()) {
> + max_latency_ns = cpu_wakeup_latency_qos_limit() *
> + NSEC_PER_USEC;
>
> - entered_state = call_cpuidle_s2idle(drv, dev);
> + entered_state = call_cpuidle_s2idle(drv, dev,
> + max_latency_ns);
> if (entered_state > 0)
> goto exit_idle;
> -
> - max_latency_ns = U64_MAX;
> } else {
> max_latency_ns = dev->forced_idle_latency_limit_ns;
> }
> --
> 2.43.0
>
--
Best regards,
Dhruva Gole
Texas Instruments Incorporated
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v3 5/6] cpuidle: Respect the CPU system wakeup QoS limit for cpuidle
2025-11-21 10:03 [PATCH v3 0/6] PM: QoS: Introduce a CPU system wakeup QoS limit for s2idle Ulf Hansson
` (3 preceding siblings ...)
2025-11-21 10:03 ` [PATCH v3 4/6] sched: idle: Respect the CPU system wakeup QoS limit for s2idle Ulf Hansson
@ 2025-11-21 10:03 ` Ulf Hansson
2025-11-25 5:41 ` Dhruva Gole
2025-11-21 10:03 ` [PATCH v3 6/6] Documentation: power/cpuidle: Document the CPU system wakeup latency QoS Ulf Hansson
` (2 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Ulf Hansson @ 2025-11-21 10:03 UTC (permalink / raw)
To: Rafael J . Wysocki, linux-pm
Cc: Vincent Guittot, Peter Zijlstra, Kevin Hilman, Pavel Machek,
Len Brown, Daniel Lezcano, Maulik Shah, Prasad Sodagudi,
Dhruva Gole, Deepti Jaggi, Ulf Hansson, linux-kernel
The CPU system wakeup QoS limit must be respected for the regular cpuidle
state selection. Therefore, let's extend the common governor helper
cpuidle_governor_latency_req(), to take the constraint into account.
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
Changes in v3:
- New patch.
---
drivers/cpuidle/governor.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/cpuidle/governor.c b/drivers/cpuidle/governor.c
index 0d0f9751ff8f..5d0e7f78c6c5 100644
--- a/drivers/cpuidle/governor.c
+++ b/drivers/cpuidle/governor.c
@@ -111,6 +111,10 @@ s64 cpuidle_governor_latency_req(unsigned int cpu)
struct device *device = get_cpu_device(cpu);
int device_req = dev_pm_qos_raw_resume_latency(device);
int global_req = cpu_latency_qos_limit();
+ int global_wake_req = cpu_wakeup_latency_qos_limit();
+
+ if (global_req > global_wake_req)
+ global_req = global_wake_req;
if (device_req > global_req)
device_req = global_req;
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH v3 5/6] cpuidle: Respect the CPU system wakeup QoS limit for cpuidle
2025-11-21 10:03 ` [PATCH v3 5/6] cpuidle: Respect the CPU system wakeup QoS limit for cpuidle Ulf Hansson
@ 2025-11-25 5:41 ` Dhruva Gole
0 siblings, 0 replies; 16+ messages in thread
From: Dhruva Gole @ 2025-11-25 5:41 UTC (permalink / raw)
To: Ulf Hansson
Cc: Rafael J . Wysocki, linux-pm, Vincent Guittot, Peter Zijlstra,
Kevin Hilman, Pavel Machek, Len Brown, Daniel Lezcano,
Maulik Shah, Prasad Sodagudi, Deepti Jaggi, linux-kernel
On Nov 21, 2025 at 11:03:11 +0100, Ulf Hansson wrote:
> The CPU system wakeup QoS limit must be respected for the regular cpuidle
> state selection. Therefore, let's extend the common governor helper
> cpuidle_governor_latency_req(), to take the constraint into account.
>
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> ---
Reviewed-by: Dhruva Gole <d-gole@ti.com>
>
> Changes in v3:
> - New patch.
>
> ---
> drivers/cpuidle/governor.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/cpuidle/governor.c b/drivers/cpuidle/governor.c
> index 0d0f9751ff8f..5d0e7f78c6c5 100644
> --- a/drivers/cpuidle/governor.c
> +++ b/drivers/cpuidle/governor.c
> @@ -111,6 +111,10 @@ s64 cpuidle_governor_latency_req(unsigned int cpu)
> struct device *device = get_cpu_device(cpu);
> int device_req = dev_pm_qos_raw_resume_latency(device);
> int global_req = cpu_latency_qos_limit();
> + int global_wake_req = cpu_wakeup_latency_qos_limit();
> +
> + if (global_req > global_wake_req)
> + global_req = global_wake_req;
>
> if (device_req > global_req)
> device_req = global_req;
> --
> 2.43.0
>
--
Best regards,
Dhruva Gole
Texas Instruments Incorporated
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v3 6/6] Documentation: power/cpuidle: Document the CPU system wakeup latency QoS
2025-11-21 10:03 [PATCH v3 0/6] PM: QoS: Introduce a CPU system wakeup QoS limit for s2idle Ulf Hansson
` (4 preceding siblings ...)
2025-11-21 10:03 ` [PATCH v3 5/6] cpuidle: Respect the CPU system wakeup QoS limit for cpuidle Ulf Hansson
@ 2025-11-21 10:03 ` Ulf Hansson
2025-11-24 18:36 ` Dhruva Gole
2025-11-24 18:27 ` [PATCH v3 0/6] PM: QoS: Introduce a CPU system wakeup QoS limit for s2idle Rafael J. Wysocki
2025-11-24 23:43 ` Kevin Hilman
7 siblings, 1 reply; 16+ messages in thread
From: Ulf Hansson @ 2025-11-21 10:03 UTC (permalink / raw)
To: Rafael J . Wysocki, linux-pm
Cc: Vincent Guittot, Peter Zijlstra, Kevin Hilman, Pavel Machek,
Len Brown, Daniel Lezcano, Maulik Shah, Prasad Sodagudi,
Dhruva Gole, Deepti Jaggi, Ulf Hansson, linux-kernel,
Jonathan Corbet
Let's document how the new CPU system wakeup latency QoS limit can be used
from user space, along with how the constraint is taken into account for
s2idle and cpuidle.
Cc: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
Changes in v3:
- Improved documentation.
- Updated commit message.
Changes in v2:
- New patch.
---
Documentation/admin-guide/pm/cpuidle.rst | 9 +++++++++
Documentation/power/pm_qos_interface.rst | 9 +++++----
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/Documentation/admin-guide/pm/cpuidle.rst b/Documentation/admin-guide/pm/cpuidle.rst
index 0c090b076224..c39ad6ab99d9 100644
--- a/Documentation/admin-guide/pm/cpuidle.rst
+++ b/Documentation/admin-guide/pm/cpuidle.rst
@@ -580,6 +580,15 @@ the given CPU as the upper limit for the exit latency of the idle states that
they are allowed to select for that CPU. They should never select any idle
states with exit latency beyond that limit.
+While the above CPU QoS constraints applies to CPU idle time management, user
+space may also request a CPU system wakeup latency QoS limit, via the
+`cpu_wakeup_latency` file. This QoS constraint is respected when selecting a
+suitable idle state for the CPUs, while entering the system-wide suspend-to-idle
+sleep state, but also to the regular CPU idle time management.
+
+Note that, the management of the `cpu_wakeup_latency` file works according to
+the 'cpu_dma_latency' file from user space point of view. Moreover, the unit
+is also microseconds.
Idle States Control Via Kernel Command Line
===========================================
diff --git a/Documentation/power/pm_qos_interface.rst b/Documentation/power/pm_qos_interface.rst
index 5019c79c7710..4c008e2202f0 100644
--- a/Documentation/power/pm_qos_interface.rst
+++ b/Documentation/power/pm_qos_interface.rst
@@ -55,7 +55,8 @@ int cpu_latency_qos_request_active(handle):
From user space:
-The infrastructure exposes one device node, /dev/cpu_dma_latency, for the CPU
+The infrastructure exposes two separate device nodes, /dev/cpu_dma_latency for
+the CPU latency QoS and /dev/cpu_wakeup_latency for the CPU system wakeup
latency QoS.
Only processes can register a PM QoS request. To provide for automatic
@@ -63,15 +64,15 @@ cleanup of a process, the interface requires the process to register its
parameter requests as follows.
To register the default PM QoS target for the CPU latency QoS, the process must
-open /dev/cpu_dma_latency.
+open /dev/cpu_dma_latency. To register a CPU system wakeup QoS limit, the
+process must open /dev/cpu_wakeup_latency.
As long as the device node is held open that process has a registered
request on the parameter.
To change the requested target value, the process needs to write an s32 value to
the open device node. Alternatively, it can write a hex string for the value
-using the 10 char long format e.g. "0x12345678". This translates to a
-cpu_latency_qos_update_request() call.
+using the 10 char long format e.g. "0x12345678".
To remove the user mode request for a target value simply close the device
node.
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH v3 6/6] Documentation: power/cpuidle: Document the CPU system wakeup latency QoS
2025-11-21 10:03 ` [PATCH v3 6/6] Documentation: power/cpuidle: Document the CPU system wakeup latency QoS Ulf Hansson
@ 2025-11-24 18:36 ` Dhruva Gole
0 siblings, 0 replies; 16+ messages in thread
From: Dhruva Gole @ 2025-11-24 18:36 UTC (permalink / raw)
To: Ulf Hansson
Cc: Rafael J . Wysocki, linux-pm, Vincent Guittot, Peter Zijlstra,
Kevin Hilman, Pavel Machek, Len Brown, Daniel Lezcano,
Maulik Shah, Prasad Sodagudi, Deepti Jaggi, linux-kernel,
Jonathan Corbet
On Nov 21, 2025 at 11:03:12 +0100, Ulf Hansson wrote:
> Let's document how the new CPU system wakeup latency QoS limit can be used
> from user space, along with how the constraint is taken into account for
> s2idle and cpuidle.
>
> Cc: Jonathan Corbet <corbet@lwn.net>
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> ---
>
> Changes in v3:
> - Improved documentation.
> - Updated commit message.
>
> Changes in v2:
> - New patch.
>
> ---
> Documentation/admin-guide/pm/cpuidle.rst | 9 +++++++++
> Documentation/power/pm_qos_interface.rst | 9 +++++----
> 2 files changed, 14 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/admin-guide/pm/cpuidle.rst b/Documentation/admin-guide/pm/cpuidle.rst
> index 0c090b076224..c39ad6ab99d9 100644
> --- a/Documentation/admin-guide/pm/cpuidle.rst
> +++ b/Documentation/admin-guide/pm/cpuidle.rst
> @@ -580,6 +580,15 @@ the given CPU as the upper limit for the exit latency of the idle states that
> they are allowed to select for that CPU. They should never select any idle
> states with exit latency beyond that limit.
>
> +While the above CPU QoS constraints applies to CPU idle time management, user
Nit: s/applies/apply
> +space may also request a CPU system wakeup latency QoS limit, via the
> +`cpu_wakeup_latency` file. This QoS constraint is respected when selecting a
> +suitable idle state for the CPUs, while entering the system-wide suspend-to-idle
> +sleep state, but also to the regular CPU idle time management.
> +
> +Note that, the management of the `cpu_wakeup_latency` file works according to
> +the 'cpu_dma_latency' file from user space point of view. Moreover, the unit
> +is also microseconds.
>
> Idle States Control Via Kernel Command Line
> ===========================================
> diff --git a/Documentation/power/pm_qos_interface.rst b/Documentation/power/pm_qos_interface.rst
> index 5019c79c7710..4c008e2202f0 100644
> --- a/Documentation/power/pm_qos_interface.rst
> +++ b/Documentation/power/pm_qos_interface.rst
> @@ -55,7 +55,8 @@ int cpu_latency_qos_request_active(handle):
>
> From user space:
>
> -The infrastructure exposes one device node, /dev/cpu_dma_latency, for the CPU
> +The infrastructure exposes two separate device nodes, /dev/cpu_dma_latency for
> +the CPU latency QoS and /dev/cpu_wakeup_latency for the CPU system wakeup
> latency QoS.
>
> Only processes can register a PM QoS request. To provide for automatic
> @@ -63,15 +64,15 @@ cleanup of a process, the interface requires the process to register its
> parameter requests as follows.
>
> To register the default PM QoS target for the CPU latency QoS, the process must
> -open /dev/cpu_dma_latency.
> +open /dev/cpu_dma_latency. To register a CPU system wakeup QoS limit, the
> +process must open /dev/cpu_wakeup_latency.
>
> As long as the device node is held open that process has a registered
> request on the parameter.
>
> To change the requested target value, the process needs to write an s32 value to
> the open device node. Alternatively, it can write a hex string for the value
> -using the 10 char long format e.g. "0x12345678". This translates to a
> -cpu_latency_qos_update_request() call.
> +using the 10 char long format e.g. "0x12345678".
LGTM,
Reviewed-by: Dhruva Gole <d-gole@ti.com>
--
Best regards,
Dhruva Gole
Texas Instruments Incorporated
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 0/6] PM: QoS: Introduce a CPU system wakeup QoS limit for s2idle
2025-11-21 10:03 [PATCH v3 0/6] PM: QoS: Introduce a CPU system wakeup QoS limit for s2idle Ulf Hansson
` (5 preceding siblings ...)
2025-11-21 10:03 ` [PATCH v3 6/6] Documentation: power/cpuidle: Document the CPU system wakeup latency QoS Ulf Hansson
@ 2025-11-24 18:27 ` Rafael J. Wysocki
2025-11-25 11:31 ` Ulf Hansson
2025-11-24 23:43 ` Kevin Hilman
7 siblings, 1 reply; 16+ messages in thread
From: Rafael J. Wysocki @ 2025-11-24 18:27 UTC (permalink / raw)
To: Ulf Hansson
Cc: Rafael J . Wysocki, linux-pm, Vincent Guittot, Peter Zijlstra,
Kevin Hilman, Pavel Machek, Len Brown, Daniel Lezcano,
Maulik Shah, Prasad Sodagudi, Dhruva Gole, Deepti Jaggi,
linux-kernel
On Fri, Nov 21, 2025 at 11:03 AM Ulf Hansson <ulf.hansson@linaro.org> wrote:
>
> Changes in v3:
> - Take new the new QoS limit into account for cpuidle too (Rafael).
> - Add a new Kconfig for the new QoS interface (Rafael)
> - Improved the documentation (Dhruva)
> - Clarified commit messages and added acks.
>
> Changes in v2:
> - Limit the new QoS to CPUs and make some corresponding renaming of the
> functions along with name of the device node for user space.
> - Make sure we deal with the failure/error path correctly when there are
> no state available for s2idle.
> - Add documentation.
>
> Some platforms supports multiple low power states for CPUs that can be used
> when entering system-wide suspend and s2idle in particular. Currently we are
> always selecting the deepest possible state for the CPUs, which can break the
> system wakeup latency constraint that may be required for a use case.
>
> Therefore, this series suggests to introduce a new interface for user space,
> allowing us to specify the CPU system wakeup QoS limit. The QoS limit is then
> taken into account when selecting a suitable low power state for s2idle/cpuidle.
>
> Kind regards
> Ulf Hansson
>
>
> Ulf Hansson (6):
> PM: QoS: Introduce a CPU system wakeup QoS limit
> pmdomain: Respect the CPU system wakeup QoS limit for s2idle
> pmdomain: Respect the CPU system wakeup QoS limit for cpuidle
> sched: idle: Respect the CPU system wakeup QoS limit for s2idle
> cpuidle: Respect the CPU system wakeup QoS limit for cpuidle
> Documentation: power/cpuidle: Document the CPU system wakeup latency
> QoS
>
> Documentation/admin-guide/pm/cpuidle.rst | 9 ++
> Documentation/power/pm_qos_interface.rst | 9 +-
> drivers/cpuidle/cpuidle.c | 12 +--
> drivers/cpuidle/governor.c | 4 +
> drivers/pmdomain/core.c | 10 ++-
> drivers/pmdomain/governor.c | 33 ++++++-
> include/linux/cpuidle.h | 6 +-
> include/linux/pm_domain.h | 1 +
> include/linux/pm_qos.h | 9 ++
> kernel/power/Kconfig | 4 +
> kernel/power/qos.c | 106 +++++++++++++++++++++++
> kernel/sched/idle.c | 12 +--
> 12 files changed, 196 insertions(+), 19 deletions(-)
>
> --
It looks good to me now.
Do you want me to pick it up or do you want to route it differently?
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH v3 0/6] PM: QoS: Introduce a CPU system wakeup QoS limit for s2idle
2025-11-24 18:27 ` [PATCH v3 0/6] PM: QoS: Introduce a CPU system wakeup QoS limit for s2idle Rafael J. Wysocki
@ 2025-11-25 11:31 ` Ulf Hansson
0 siblings, 0 replies; 16+ messages in thread
From: Ulf Hansson @ 2025-11-25 11:31 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: linux-pm, Vincent Guittot, Peter Zijlstra, Kevin Hilman,
Pavel Machek, Len Brown, Daniel Lezcano, Maulik Shah,
Prasad Sodagudi, Dhruva Gole, Deepti Jaggi, linux-kernel
On Mon, 24 Nov 2025 at 19:27, Rafael J. Wysocki <rafael@kernel.org> wrote:
>
> On Fri, Nov 21, 2025 at 11:03 AM Ulf Hansson <ulf.hansson@linaro.org> wrote:
> >
> > Changes in v3:
> > - Take new the new QoS limit into account for cpuidle too (Rafael).
> > - Add a new Kconfig for the new QoS interface (Rafael)
> > - Improved the documentation (Dhruva)
> > - Clarified commit messages and added acks.
> >
> > Changes in v2:
> > - Limit the new QoS to CPUs and make some corresponding renaming of the
> > functions along with name of the device node for user space.
> > - Make sure we deal with the failure/error path correctly when there are
> > no state available for s2idle.
> > - Add documentation.
> >
> > Some platforms supports multiple low power states for CPUs that can be used
> > when entering system-wide suspend and s2idle in particular. Currently we are
> > always selecting the deepest possible state for the CPUs, which can break the
> > system wakeup latency constraint that may be required for a use case.
> >
> > Therefore, this series suggests to introduce a new interface for user space,
> > allowing us to specify the CPU system wakeup QoS limit. The QoS limit is then
> > taken into account when selecting a suitable low power state for s2idle/cpuidle.
> >
> > Kind regards
> > Ulf Hansson
> >
> >
> > Ulf Hansson (6):
> > PM: QoS: Introduce a CPU system wakeup QoS limit
> > pmdomain: Respect the CPU system wakeup QoS limit for s2idle
> > pmdomain: Respect the CPU system wakeup QoS limit for cpuidle
> > sched: idle: Respect the CPU system wakeup QoS limit for s2idle
> > cpuidle: Respect the CPU system wakeup QoS limit for cpuidle
> > Documentation: power/cpuidle: Document the CPU system wakeup latency
> > QoS
> >
> > Documentation/admin-guide/pm/cpuidle.rst | 9 ++
> > Documentation/power/pm_qos_interface.rst | 9 +-
> > drivers/cpuidle/cpuidle.c | 12 +--
> > drivers/cpuidle/governor.c | 4 +
> > drivers/pmdomain/core.c | 10 ++-
> > drivers/pmdomain/governor.c | 33 ++++++-
> > include/linux/cpuidle.h | 6 +-
> > include/linux/pm_domain.h | 1 +
> > include/linux/pm_qos.h | 9 ++
> > kernel/power/Kconfig | 4 +
> > kernel/power/qos.c | 106 +++++++++++++++++++++++
> > kernel/sched/idle.c | 12 +--
> > 12 files changed, 196 insertions(+), 19 deletions(-)
> >
> > --
>
> It looks good to me now.
Thanks!
>
> Do you want me to pick it up or do you want to route it differently?
I think you can pick this up via your tree. As I have some changes
queued via my pmdomain tree for the genpd governor, I asked git to
merge our branches (with this series applied to your tree) and it
seems to be working fine.
To address Dhruva's minor comments I just posted a new version, please
queue it via your tree.
Kind regards
Uffe
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 0/6] PM: QoS: Introduce a CPU system wakeup QoS limit for s2idle
2025-11-21 10:03 [PATCH v3 0/6] PM: QoS: Introduce a CPU system wakeup QoS limit for s2idle Ulf Hansson
` (6 preceding siblings ...)
2025-11-24 18:27 ` [PATCH v3 0/6] PM: QoS: Introduce a CPU system wakeup QoS limit for s2idle Rafael J. Wysocki
@ 2025-11-24 23:43 ` Kevin Hilman
7 siblings, 0 replies; 16+ messages in thread
From: Kevin Hilman @ 2025-11-24 23:43 UTC (permalink / raw)
To: Ulf Hansson, Rafael J . Wysocki, linux-pm
Cc: Vincent Guittot, Peter Zijlstra, Pavel Machek, Len Brown,
Daniel Lezcano, Maulik Shah, Prasad Sodagudi, Dhruva Gole,
Deepti Jaggi, Ulf Hansson, linux-kernel
Ulf Hansson <ulf.hansson@linaro.org> writes:
> Changes in v3:
> - Take new the new QoS limit into account for cpuidle too (Rafael).
> - Add a new Kconfig for the new QoS interface (Rafael)
> - Improved the documentation (Dhruva)
> - Clarified commit messages and added acks.
>
> Changes in v2:
> - Limit the new QoS to CPUs and make some corresponding renaming of the
> functions along with name of the device node for user space.
> - Make sure we deal with the failure/error path correctly when there are
> no state available for s2idle.
> - Add documentation.
>
> Some platforms supports multiple low power states for CPUs that can be used
> when entering system-wide suspend and s2idle in particular. Currently we are
> always selecting the deepest possible state for the CPUs, which can break the
> system wakeup latency constraint that may be required for a use case.
>
> Therefore, this series suggests to introduce a new interface for user space,
> allowing us to specify the CPU system wakeup QoS limit. The QoS limit is then
> taken into account when selecting a suitable low power state for s2idle/cpuidle.
Reviewed-by: Kevin Hilman (TI) <khilman@baylibre.com>
Tested-by: Kevin Hilman (TI) <khilman@baylibre.com>
^ permalink raw reply [flat|nested] 16+ messages in thread