PM: QoS: Introduce boot parameter pm_qos_resume_latency_us
Subsystems (5)
PATCH v5 1/1 PM: QoS: Introduce boot parameter pm_qos_resume_latency_us
Hi Rafael, Danilo, Pavel, Len,
Users currently lack a mechanism to define granular, per-CPU PM QoS resume latency constraints during the early boot phase.
While the idle=poll boot parameter exists, it enforces a global override, forcing all CPUs in the system to "poll". This global approach is not suitable for asymmetric workloads where strict latency guarantees are required only on specific critical CPUs, while housekeeping or non-critical CPUs should be allowed to enter deeper idle states to save energy.
Additionally, the existing sysfs interface (/sys/devices/system/cpu/cpuN/power/pm_qos_resume_latency_us) becomes available only after userspace initialisation. This is too late to prevent deep C-state entry during the early kernel boot phase, which may be required for debugging early boot hangs related to C-state transitions or for workloads requiring strict latency guarantees immediately upon system start.
This patch introduces the pm_qos_resume_latency_us kernel boot parameter, which allows users to specify distinct resume latency constraints for specific CPU ranges.
Syntax: pm_qos_resume_latency_us=range:value;range:value...
This boot parameter mirrors the sysfs interface behaviour: the special string "n/a" imposes a 0us latency constraint (polling), while the integer 0 removes the constraint entirely.
For example:
"pm_qos_resume_latency_us=0:n/a;1-15:20"
Forces CPU 0 to poll on idle; constrains CPUs 1-15 to not enter a sleep state that takes longer than 20 us to wake up. All other CPUs will have the default (no resume latency) applied.
Implementation Details:
- The parameter string is captured via __setup() and parsed in an early_initcall() to ensure suitable memory allocators are available.
- Constraints are stored in a read-only linked list.
- The constraints are queried and applied in register_cpu(). This ensures the latency requirement is active immediately upon CPU registration, effectively acting as a "birth" constraint before the cpuidle governor takes over.
- The parsing logic enforces a "First Match Wins" policy: if a CPU falls into multiple specified ranges, the latency value from the first matching entry is used.
- The constraints persist across CPU hotplug events.
---
Changes since v4 [1]:
- Modified the parsing logic so the boot parameter perfectly mirrors the existing sysfs interface. Passing the integer 0 now explicitly removes the constraint (i.e., maps to PM_QOS_RESUME_LATENCY_NO_CONSTRAINT), and the special string "n/a" safely imposes a 0us latency constraint (polling on idle)
- Changed the outer tuple delimiter from a comma (",") to a semicolon (";"). This prevents strsep() from breaking standard, non-contiguous CPU lists (e.g., "0,2:n/a;4-7:20")
- Moved the cpumask_or() coverage update to the end of the parsing loop
- Updated documentation to reflect the new semicolon delimiter and updated semantic behavior in Documentation/admin-guide/kernel-parameters.txt
Changes since v3 [2]:
- Moved pm_qos_get_boot_cpu_latency_limit() declaration out of the CONFIG_PM #ifdef block, as qos.c is compiled regardless
Changes since v2 [3]:
- Add pr_fmt() to standardise log prefixes (Zhongqiu Han)
- Drop <asm/setup.h> by duplicating the command line with kstrdup() (Zhongqiu Han)
- Fix init_pm_qos_resume_latency_us_setup() error path to return -ENOMEM (Zhongqiu Han)
Changes since v1 [4]:
- Removed boot_option_idle_override == IDLE_POLL check
- Decoupled implementation from CONFIG_CPU_IDLE
- Added kernel-parameters.txt documentation
- Renamed internal setup functions for consistency
[1]: https://lore.kernel.org/lkml/[email protected]/
[2]: https://lore.kernel.org/lkml/[email protected]/
[3]: https://lore.kernel.org/lkml/[email protected]/
[4]: https://lore.kernel.org/lkml/[email protected]/
.../admin-guide/kernel-parameters.txt | 22 +++ drivers/base/cpu.c | 5 +- include/linux/pm_qos.h | 1 + kernel/power/qos.c | 153 ++++++++++++++++++ 4 files changed, 179 insertions(+), 2 deletions(-)
Documentation/admin-guide/kernel-parameters.txt +22 -0
@@ -2238,6 +2238,28 @@ Kernel parameters icn= [HW,ISDN] Format: <io>[,<membase>[,<icn_id>[,<icn_id2>]]] + pm_qos_resume_latency_us= [KNL,EARLY] + Format: <cpu-list>:<value>[;<cpu-list>:<value>...] + + Establish per-CPU resume latency constraints. These constraints + are applied immediately upon CPU registration and persist + across CPU hotplug events. + + For example: + "pm_qos_resume_latency_us=0:n/a;1-15:20" + + This restricts CPU 0 to a 0us resume latency (effectively + forcing polling) and limits CPUs 1-15 to C-states with a + maximum exit latency of 20us. All other CPUs remain + unconstrained by this parameter. + + This boot parameter mirrors the sysfs interface behaviour. + The special string "n/a" imposes a 0us latency constraint + (polling), while the integer 0 removes the constraint. + + NOTE: The parsing logic enforces a "First Match Wins" policy. + If a CPU is included in multiple specified ranges, the latency + value from the first matching entry takes precedence. idle= [X86,EARLY] Format: idle=poll, idle=halt, idle=nomwait
drivers/base/cpu.c +3 -2
@@ -416,6 +416,7 @@ EXPORT_SYMBOL_GPL(cpu_subsys);int register_cpu (struct cpu *cpu,int num) {int error; +s32 resume_latency; cpu->node_id =cpu_to_node (num);memset (&cpu->dev,0x00 ,sizeof (struct device ));
@@ -436,8 +437,8 @@ int register_cpu(struct cpu *cpu, int num)per_cpu (cpu_sys_devices, num) = &cpu->dev;register_cpu_under_node (num,cpu_to_node (num)); -dev_pm_qos_expose_latency_limit (&cpu->dev, -PM_QOS_RESUME_LATENCY_NO_CONSTRAINT ); + resume_latency =pm_qos_get_boot_cpu_latency_limit (num); +dev_pm_qos_expose_latency_limit (&cpu->dev, resume_latency);set_cpu_enabled (num, true);return 0 ;
include/linux/pm_qos.h +1 -0
@@ -142,6 +142,7 @@ int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node,bool pm_qos_update_flags (struct pm_qos_flags *pqf,struct pm_qos_flags_request *req,enum pm_qos_req_action action,s32 val); +s32 pm_qos_get_boot_cpu_latency_limit (unsigned int cpu);#ifdef CONFIG_CPU_IDLE s32 cpu_latency_qos_limit (void );
kernel/power/qos.c +153 -0
171 lines not on this page · raw message
Signature · 1 line
2.51.0
Quoted 9 lines · Aaron Tomlin
This patch introduces the
pm_qos_resume_latency_uskernel boot parameter, which allows users to specify distinct resume latency constraints for specific CPU ranges.Syntax: pm_qos_resume_latency_us=range:value;range:value...
This boot parameter mirrors the sysfs interface behaviour: the special string "n/a" imposes a 0us latency constraint (polling), while the integer 0 removes the constraint entirely.
Hi Greg, Rafael, Danilo, Pavel, Len,
It has been over a month since I submitted this, so I just wanted to gently ping this thread.
As a quick reminder, this parameter is highly beneficial for deployments that prefer to establish strict latency constraints early in the boot process, eliminating the need to rely on custom user-space tooling later on.
Patch link: https://lore.kernel.org/lkml/[email protected]/
Please let me know if you have any conceptual concerns with this approach, if any further adjustments are required, or if you simply need me to rebase and resend this against the latest power management tree.
Thank you for your time.
Kind regards
Signature · 1 line
Aaron Tomlin
Rafael J. Wysocki
maintainerQuoted 22 lines · Aaron Tomlin
Quoted 9 lines · Aaron Tomlin
This patch introduces the
pm_qos_resume_latency_uskernel boot parameter, which allows users to specify distinct resume latency constraints for specific CPU ranges.Syntax: pm_qos_resume_latency_us=range:value;range:value...
This boot parameter mirrors the sysfs interface behaviour: the special string "n/a" imposes a 0us latency constraint (polling), while the integer 0 removes the constraint entirely.
Hi Greg, Rafael, Danilo, Pavel, Len,
It has been over a month since I submitted this, so I just wanted to gently ping this thread.
As a quick reminder, this parameter is highly beneficial for deployments that prefer to establish strict latency constraints early in the boot process, eliminating the need to rely on custom user-space tooling later on.
Quoted 4 lines
Patch link: https://lore.kernel.org/lkml/[email protected]/
Please let me know if you have any conceptual concerns with this approach, if any further adjustments are required,
IMV it would be better to call the new command line arg something like "cpu_idle_exit_latency_us" to make it clear what it is about.
Also, generally speaking, it should be part of cpuidle rather than the generic QoS code that also applies to devices other than CPUs.
Quoted 1 line
or if you simply need me to rebase and resend this against the latest power management tree.
And that too.
Thanks!
Quoted 10 lines · Rafael J. Wysocki
IMV it would be better to call the new command line arg something like "
cpu_idle_exit_latency_us" to make it clear what it is about.Also, generally speaking, it should be part of cpuidle rather than the generic QoS code that also applies to devices other than CPUs.
Quoted 2 lines
or if you simply need me to rebase and resend this against the latest power management tree.
And that too.
Hi Rafael,
Thank you for your review and the constructive feedback.
I certainly appreciate your reasoning concerning the naming convention and its current CPU-specific scope.
However, before I prepare the next iteration, I thought it prudent to briefly outline my original architectural reasoning for housing it within the generic PM QoS code, simply to ascertain whether you remain of the view that cpuidle is the most appropriate home.
My primary motivation for retaining it within the generic PM QoS framework was to maintain strict symmetry with the existing sysfs interface.
The parameter is designed to align precisely with /sys/devices/system/cpu/cpuN/power/pm_qos_resume_latency_us. That sysfs attribute is exposed and managed by the generic device PM QoS code, quite independently of cpuidle. Furthermore, the boot constraint itself is applied via dev_pm_qos_expose_latency_limit(&cpu->dev, ...), which is fundamentally a core QoS API.
Should we move the boot parameter parsing into cpuidle, the consequence is that the cpuidle subsystem becomes responsible for parsing a boot string, only to immediately pass that data back into the generic PM QoS framework during CPU registration. Keeping the implementation within qos.c ensures that the parsing logic and the underlying data structures remain cohesively in the same subsystem. Crucially, it also preserves the flexibility to extend this syntax to non-CPU devices in the future without necessitating further refactoring.
I look forward to hearing your preference.
Kind regards,
Signature · 1 line
Aaron Tomlin
Quoted 31 lines · Aaron Tomlin
Hi Rafael,
Thank you for your review and the constructive feedback.
I certainly appreciate your reasoning concerning the naming convention and its current CPU-specific scope.
However, before I prepare the next iteration, I thought it prudent to briefly outline my original architectural reasoning for housing it within the generic PM QoS code, simply to ascertain whether you remain of the view that cpuidle is the most appropriate home.
My primary motivation for retaining it within the generic PM QoS framework was to maintain strict symmetry with the existing sysfs interface.
The parameter is designed to align precisely with
/sys/devices/system/cpu/cpuN/power/pm_qos_resume_latency_us. That sysfs attribute is exposed and managed by the generic device PM QoS code, quite independently of cpuidle. Furthermore, the boot constraint itself is applied viadev_pm_qos_expose_latency_limit(&cpu->dev, ...), which is fundamentally a core QoS API.Should we move the boot parameter parsing into cpuidle, the consequence is that the cpuidle subsystem becomes responsible for parsing a boot string, only to immediately pass that data back into the generic PM QoS framework during CPU registration. Keeping the implementation within
qos.censures that the parsing logic and the underlying data structures remain cohesively in the same subsystem. Crucially, it also preserves the flexibility to extend this syntax to non-CPU devices in the future without necessitating further refactoring.
Quoted 1 line
I look forward to hearing your preference.
Hi Rafael,
I am writing to politely enquire whether you have had an opportunity to consider my reasoning concerning the generic PM QoS framework.
There is absolutely no urgency on my part; however, I am standing by to rebase and prepare v6 as soon as we reach a consensus on the most appropriate home for the parsing logic. Please do let me know how you would prefer to proceed.
Kind regards,
Signature · 1 line
Aaron Tomlin
Quoted 36 lines · Aaron Tomlin
Quoted 31 lines · Aaron Tomlin
Hi Rafael,
Thank you for your review and the constructive feedback.
I certainly appreciate your reasoning concerning the naming convention and its current CPU-specific scope.
However, before I prepare the next iteration, I thought it prudent to briefly outline my original architectural reasoning for housing it within the generic PM QoS code, simply to ascertain whether you remain of the view that cpuidle is the most appropriate home.
My primary motivation for retaining it within the generic PM QoS framework was to maintain strict symmetry with the existing sysfs interface.
The parameter is designed to align precisely with
/sys/devices/system/cpu/cpuN/power/pm_qos_resume_latency_us. That sysfs attribute is exposed and managed by the generic device PM QoS code, quite independently of cpuidle. Furthermore, the boot constraint itself is applied viadev_pm_qos_expose_latency_limit(&cpu->dev, ...), which is fundamentally a core QoS API.Should we move the boot parameter parsing into cpuidle, the consequence is that the cpuidle subsystem becomes responsible for parsing a boot string, only to immediately pass that data back into the generic PM QoS framework during CPU registration. Keeping the implementation within
qos.censures that the parsing logic and the underlying data structures remain cohesively in the same subsystem. Crucially, it also preserves the flexibility to extend this syntax to non-CPU devices in the future without necessitating further refactoring.Quoted 1 line
I look forward to hearing your preference.
Hi Rafael,
Quoted 7 lines
I am writing to politely enquire whether you have had an opportunity to consider my reasoning concerning the generic PM QoS framework.
There is absolutely no urgency on my part; however, I am standing by to rebase and prepare v6 as soon as we reach a consensus on the most appropriate home for the parsing logic. Please do let me know how you would prefer to proceed.
Hi Rafael,
Please excuse the second gentle ping on this thread.
I appreciate how busy things can get, but I wanted to briefly check in to see whether you have had an opportunity to consider the appropriate home for the boot parameter parsing logic.
My primary motivation for retaining it within the generic PM QoS framework was to maintain strict symmetry with the existing sysfs interface.
Original response: https://lore.kernel.org/lkml/3uztb63u72mniljqb2cd4q7cbma2hvns27gn2j2xfm4q4ouuu6@zqyc2wjt55rp/
I am entirely happy to proceed with whichever approach you see fit—please just let me know your preference and I will get v6 prepared and submitted.
Kind reards,
Signature · 1 line
Aaron Tomlin