From 5a7ea52b6faec6f8877e49645a80349b2d970f0a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 11 Feb 2020 23:58:17 +0100 Subject: PM: QoS: Drop pm_qos_update_request_timeout() The pm_qos_update_request_timeout() function is not called from anywhere, so drop it along with the work member in struct pm_qos_request needed by it. Also drop the useless pm_qos_update_request_timeout trace event that is only triggered by that function (so it never triggers at all) and update the trace events documentation accordingly. Signed-off-by: Rafael J. Wysocki Reviewed-by: Ulf Hansson Reviewed-by: Amit Kucheria Tested-by: Amit Kucheria --- Documentation/trace/events-power.rst | 2 -- 1 file changed, 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/trace/events-power.rst b/Documentation/trace/events-power.rst index 2ef318962e29..eec7453a168e 100644 --- a/Documentation/trace/events-power.rst +++ b/Documentation/trace/events-power.rst @@ -78,11 +78,9 @@ target/flags update. pm_qos_add_request "pm_qos_class=%s value=%d" pm_qos_update_request "pm_qos_class=%s value=%d" pm_qos_remove_request "pm_qos_class=%s value=%d" - pm_qos_update_request_timeout "pm_qos_class=%s value=%d, timeout_us=%ld" The first parameter gives the QoS class name (e.g. "CPU_DMA_LATENCY"). The second parameter is value to be added/updated/removed. -The third parameter is timeout value in usec. :: pm_qos_update_target "action=%s prev_value=%d curr_value=%d" -- cgit v1.2.3 From 333eed7d20069e2d80446f5fdf9ac3868b55e7b9 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 12 Feb 2020 00:06:17 +0100 Subject: PM: QoS: Simplify definitions of CPU latency QoS trace events Modify the definitions of the CPU latency QoS trace events to take one argument (since PM_QOS_CPU_DMA_LATENCY is always passed as the pm_qos_class argument to them) and update the documentation of them accordingly (while at it, make it explicitly mention CPU latency QoS and relocate it after the device PM QoS trace events documentation). The names and output format of the trace events do not change to preserve user space compatibility. No intentional functional impact. Signed-off-by: Rafael J. Wysocki Reviewed-by: Ulf Hansson Reviewed-by: Amit Kucheria Tested-by: Amit Kucheria --- Documentation/trace/events-power.rst | 19 ++++++++++--------- include/trace/events/power.h | 35 +++++++++++++++++------------------ kernel/power/qos.c | 16 ++++++++-------- 3 files changed, 35 insertions(+), 35 deletions(-) (limited to 'Documentation') diff --git a/Documentation/trace/events-power.rst b/Documentation/trace/events-power.rst index eec7453a168e..f45bf11fa88d 100644 --- a/Documentation/trace/events-power.rst +++ b/Documentation/trace/events-power.rst @@ -73,14 +73,6 @@ The second parameter is the power domain target state. ================ The PM QoS events are used for QoS add/update/remove request and for target/flags update. -:: - - pm_qos_add_request "pm_qos_class=%s value=%d" - pm_qos_update_request "pm_qos_class=%s value=%d" - pm_qos_remove_request "pm_qos_class=%s value=%d" - -The first parameter gives the QoS class name (e.g. "CPU_DMA_LATENCY"). -The second parameter is value to be added/updated/removed. :: pm_qos_update_target "action=%s prev_value=%d curr_value=%d" @@ -90,7 +82,7 @@ The first parameter gives the QoS action name (e.g. "ADD_REQ"). The second parameter is the previous QoS value. The third parameter is the current QoS value to update. -And, there are also events used for device PM QoS add/update/remove request. +There are also events used for device PM QoS add/update/remove request. :: dev_pm_qos_add_request "device=%s type=%s new_value=%d" @@ -101,3 +93,12 @@ The first parameter gives the device name which tries to add/update/remove QoS requests. The second parameter gives the request type (e.g. "DEV_PM_QOS_RESUME_LATENCY"). The third parameter is value to be added/updated/removed. + +And, there are events used for CPU latency QoS add/update/remove request. +:: + + pm_qos_add_request "value=%d" + pm_qos_update_request "value=%d" + pm_qos_remove_request "value=%d" + +The parameter is the value to be added/updated/removed. diff --git a/include/trace/events/power.h b/include/trace/events/power.h index ecf39daabf16..af5018aa9517 100644 --- a/include/trace/events/power.h +++ b/include/trace/events/power.h @@ -359,51 +359,50 @@ DEFINE_EVENT(power_domain, power_domain_target, ); /* - * The pm qos events are used for pm qos update + * CPU latency QoS events used for global CPU latency QoS list updates */ -DECLARE_EVENT_CLASS(pm_qos_request, +DECLARE_EVENT_CLASS(cpu_latency_qos_request, - TP_PROTO(int pm_qos_class, s32 value), + TP_PROTO(s32 value), - TP_ARGS(pm_qos_class, value), + TP_ARGS(value), TP_STRUCT__entry( - __field( int, pm_qos_class ) __field( s32, value ) ), TP_fast_assign( - __entry->pm_qos_class = pm_qos_class; __entry->value = value; ), - TP_printk("pm_qos_class=%s value=%d", - __print_symbolic(__entry->pm_qos_class, - { PM_QOS_CPU_DMA_LATENCY, "CPU_DMA_LATENCY" }), + TP_printk("CPU_DMA_LATENCY value=%d", __entry->value) ); -DEFINE_EVENT(pm_qos_request, pm_qos_add_request, +DEFINE_EVENT(cpu_latency_qos_request, pm_qos_add_request, - TP_PROTO(int pm_qos_class, s32 value), + TP_PROTO(s32 value), - TP_ARGS(pm_qos_class, value) + TP_ARGS(value) ); -DEFINE_EVENT(pm_qos_request, pm_qos_update_request, +DEFINE_EVENT(cpu_latency_qos_request, pm_qos_update_request, - TP_PROTO(int pm_qos_class, s32 value), + TP_PROTO(s32 value), - TP_ARGS(pm_qos_class, value) + TP_ARGS(value) ); -DEFINE_EVENT(pm_qos_request, pm_qos_remove_request, +DEFINE_EVENT(cpu_latency_qos_request, pm_qos_remove_request, - TP_PROTO(int pm_qos_class, s32 value), + TP_PROTO(s32 value), - TP_ARGS(pm_qos_class, value) + TP_ARGS(value) ); +/* + * General PM QoS events used for updates of PM QoS request lists + */ DECLARE_EVENT_CLASS(pm_qos_update, TP_PROTO(enum pm_qos_req_action action, int prev_value, int curr_value), diff --git a/kernel/power/qos.c b/kernel/power/qos.c index a6bf53e9db17..afac7010e0f2 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c @@ -247,8 +247,8 @@ int pm_qos_request_active(struct pm_qos_request *req) } EXPORT_SYMBOL_GPL(pm_qos_request_active); -static void cpu_latency_qos_update(struct pm_qos_request *req, - enum pm_qos_req_action action, s32 value) +static void cpu_latency_qos_apply(struct pm_qos_request *req, + enum pm_qos_req_action action, s32 value) { int ret = pm_qos_update_target(req->qos, &req->node, action, value); if (ret > 0) @@ -278,10 +278,10 @@ void pm_qos_add_request(struct pm_qos_request *req, return; } - trace_pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY, value); + trace_pm_qos_add_request(value); req->qos = &cpu_latency_constraints; - cpu_latency_qos_update(req, PM_QOS_ADD_REQ, value); + cpu_latency_qos_apply(req, PM_QOS_ADD_REQ, value); } EXPORT_SYMBOL_GPL(pm_qos_add_request); @@ -305,12 +305,12 @@ void pm_qos_update_request(struct pm_qos_request *req, s32 new_value) return; } - trace_pm_qos_update_request(PM_QOS_CPU_DMA_LATENCY, new_value); + trace_pm_qos_update_request(new_value); if (new_value == req->node.prio) return; - cpu_latency_qos_update(req, PM_QOS_UPDATE_REQ, new_value); + cpu_latency_qos_apply(req, PM_QOS_UPDATE_REQ, new_value); } EXPORT_SYMBOL_GPL(pm_qos_update_request); @@ -333,9 +333,9 @@ void pm_qos_remove_request(struct pm_qos_request *req) return; } - trace_pm_qos_remove_request(PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); + trace_pm_qos_remove_request(PM_QOS_DEFAULT_VALUE); - cpu_latency_qos_update(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); + cpu_latency_qos_apply(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); memset(req, 0, sizeof(*req)); } EXPORT_SYMBOL_GPL(pm_qos_remove_request); -- cgit v1.2.3 From b8e6e27c626e60bb5708ce8c974b58c485c32ac7 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 12 Feb 2020 00:36:35 +0100 Subject: Documentation: PM: QoS: Update to reflect previous code changes Update the PM QoS documentation to reflect the previous code changes regarding the removal of PM QoS classes and the CPU latency QoS API rework. Signed-off-by: Rafael J. Wysocki Reviewed-by: Ulf Hansson Reviewed-by: Amit Kucheria Tested-by: Amit Kucheria --- Documentation/admin-guide/pm/cpuidle.rst | 73 +++++++++++++-------------- Documentation/power/pm_qos_interface.rst | 86 +++++++++++++++----------------- 2 files changed, 75 insertions(+), 84 deletions(-) (limited to 'Documentation') diff --git a/Documentation/admin-guide/pm/cpuidle.rst b/Documentation/admin-guide/pm/cpuidle.rst index 6a06dc473dd6..5605cc6f9560 100644 --- a/Documentation/admin-guide/pm/cpuidle.rst +++ b/Documentation/admin-guide/pm/cpuidle.rst @@ -583,20 +583,17 @@ Power Management Quality of Service for CPUs The power management quality of service (PM QoS) framework in the Linux kernel allows kernel code and user space processes to set constraints on various energy-efficiency features of the kernel to prevent performance from dropping -below a required level. The PM QoS constraints can be set globally, in -predefined categories referred to as PM QoS classes, or against individual -devices. +below a required level. CPU idle time management can be affected by PM QoS in two ways, through the -global constraint in the ``PM_QOS_CPU_DMA_LATENCY`` class and through the -resume latency constraints for individual CPUs. Kernel code (e.g. device -drivers) can set both of them with the help of special internal interfaces -provided by the PM QoS framework. User space can modify the former by opening -the :file:`cpu_dma_latency` special device file under :file:`/dev/` and writing -a binary value (interpreted as a signed 32-bit integer) to it. In turn, the -resume latency constraint for a CPU can be modified by user space by writing a -string (representing a signed 32-bit integer) to the -:file:`power/pm_qos_resume_latency_us` file under +global CPU latency limit and through the resume latency constraints for +individual CPUs. Kernel code (e.g. device drivers) can set both of them with +the help of special internal interfaces provided by the PM QoS framework. User +space can modify the former by opening the :file:`cpu_dma_latency` special +device file under :file:`/dev/` and writing a binary value (interpreted as a +signed 32-bit integer) to it. In turn, the resume latency constraint for a CPU +can be modified from user space by writing a string (representing a signed +32-bit integer) to the :file:`power/pm_qos_resume_latency_us` file under :file:`/sys/devices/system/cpu/cpu/` in ``sysfs``, where the CPU number ```` is allocated at the system initialization time. Negative values will be rejected in both cases and, also in both cases, the written integer @@ -605,32 +602,34 @@ number will be interpreted as a requested PM QoS constraint in microseconds. The requested value is not automatically applied as a new constraint, however, as it may be less restrictive (greater in this particular case) than another constraint previously requested by someone else. For this reason, the PM QoS -framework maintains a list of requests that have been made so far in each -global class and for each device, aggregates them and applies the effective -(minimum in this particular case) value as the new constraint. +framework maintains a list of requests that have been made so far for the +global CPU latency limit and for each individual CPU, aggregates them and +applies the effective (minimum in this particular case) value as the new +constraint. In fact, opening the :file:`cpu_dma_latency` special device file causes a new -PM QoS request to be created and added to the priority list of requests in the -``PM_QOS_CPU_DMA_LATENCY`` class and the file descriptor coming from the -"open" operation represents that request. If that file descriptor is then -used for writing, the number written to it will be associated with the PM QoS -request represented by it as a new requested constraint value. Next, the -priority list mechanism will be used to determine the new effective value of -the entire list of requests and that effective value will be set as a new -constraint. Thus setting a new requested constraint value will only change the -real constraint if the effective "list" value is affected by it. In particular, -for the ``PM_QOS_CPU_DMA_LATENCY`` class it only affects the real constraint if -it is the minimum of the requested constraints in the list. The process holding -a file descriptor obtained by opening the :file:`cpu_dma_latency` special device -file controls the PM QoS request associated with that file descriptor, but it -controls this particular PM QoS request only. +PM QoS request to be created and added to a global priority list of CPU latency +limit requests and the file descriptor coming from the "open" operation +represents that request. If that file descriptor is then used for writing, the +number written to it will be associated with the PM QoS request represented by +it as a new requested limit value. Next, the priority list mechanism will be +used to determine the new effective value of the entire list of requests and +that effective value will be set as a new CPU latency limit. Thus requesting a +new limit value will only change the real limit if the effective "list" value is +affected by it, which is the case if it is the minimum of the requested values +in the list. + +The process holding a file descriptor obtained by opening the +:file:`cpu_dma_latency` special device file controls the PM QoS request +associated with that file descriptor, but it controls this particular PM QoS +request only. Closing the :file:`cpu_dma_latency` special device file or, more precisely, the file descriptor obtained while opening it, causes the PM QoS request associated -with that file descriptor to be removed from the ``PM_QOS_CPU_DMA_LATENCY`` -class priority list and destroyed. If that happens, the priority list mechanism -will be used, again, to determine the new effective value for the whole list -and that value will become the new real constraint. +with that file descriptor to be removed from the global priority list of CPU +latency limit requests and destroyed. If that happens, the priority list +mechanism will be used again, to determine the new effective value for the whole +list and that value will become the new limit. In turn, for each CPU there is one resume latency PM QoS request associated with the :file:`power/pm_qos_resume_latency_us` file under @@ -647,10 +646,10 @@ CPU in question every time the list of requests is updated this way or another (there may be other requests coming from kernel code in that list). CPU idle time governors are expected to regard the minimum of the global -effective ``PM_QOS_CPU_DMA_LATENCY`` class constraint and the effective -resume latency constraint for the given CPU as the upper limit for the exit -latency of the idle states they can select for that CPU. They should never -select any idle states with exit latency beyond that limit. +(effective) CPU latency limit and the effective resume latency constraint for +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. Idle States Control Via Kernel Command Line diff --git a/Documentation/power/pm_qos_interface.rst b/Documentation/power/pm_qos_interface.rst index 0d62d506caf0..064f668fbdab 100644 --- a/Documentation/power/pm_qos_interface.rst +++ b/Documentation/power/pm_qos_interface.rst @@ -7,86 +7,78 @@ performance expectations by drivers, subsystems and user space applications on one of the parameters. Two different PM QoS frameworks are available: -1. PM QoS classes for cpu_dma_latency +1. CPU latency QoS. 2. The per-device PM QoS framework provides the API to manage the per-device latency constraints and PM QoS flags. -Each parameters have defined units: - - * latency: usec - * timeout: usec - * throughput: kbs (kilo bit / sec) - * memory bandwidth: mbs (mega bit / sec) +The latency unit used in the PM QoS framework is the microsecond (usec). 1. PM QoS framework =================== -The infrastructure exposes multiple misc device nodes one per implemented -parameter. The set of parameters implement is defined by pm_qos_power_init() -and pm_qos_params.h. This is done because having the available parameters -being runtime configurable or changeable from a driver was seen as too easy to -abuse. - -For each parameter a list of performance requests is maintained along with -an aggregated target value. The aggregated target value is updated with -changes to the request list or elements of the list. Typically the -aggregated target value is simply the max or min of the request values held -in the parameter list elements. +A global list of CPU latency QoS requests is maintained along with an aggregated +(effective) target value. The aggregated target value is updated with changes +to the request list or elements of the list. For CPU latency QoS, the +aggregated target value is simply the min of the request values held in the list +elements. + Note: the aggregated target value is implemented as an atomic variable so that reading the aggregated value does not require any locking mechanism. +From kernel space the use of this interface is simple: -From kernel mode the use of this interface is simple: - -void pm_qos_add_request(handle, param_class, target_value): - Will insert an element into the list for that identified PM QoS class with the - target value. Upon change to this list the new target is recomputed and any - registered notifiers are called only if the target value is now different. - Clients of pm_qos need to save the returned handle for future use in other - pm_qos API functions. +void cpu_latency_qos_add_request(handle, target_value): + Will insert an element into the CPU latency QoS list with the target value. + Upon change to this list the new target is recomputed and any registered + notifiers are called only if the target value is now different. + Clients of PM QoS need to save the returned handle for future use in other + PM QoS API functions. -void pm_qos_update_request(handle, new_target_value): +void cpu_latency_qos_update_request(handle, new_target_value): Will update the list element pointed to by the handle with the new target value and recompute the new aggregated target, calling the notification tree if the target is changed. -void pm_qos_remove_request(handle): +void cpu_latency_qos_remove_request(handle): Will remove the element. After removal it will update the aggregate target and call the notification tree if the target was changed as a result of removing the request. -int pm_qos_request(param_class): - Returns the aggregated value for a given PM QoS class. +int cpu_latency_qos_limit(): + Returns the aggregated value for the CPU latency QoS. + +int cpu_latency_qos_request_active(handle): + Returns if the request is still active, i.e. it has not been removed from the + CPU latency QoS list. -int pm_qos_request_active(handle): - Returns if the request is still active, i.e. it has not been removed from a - PM QoS class constraints list. +int cpu_latency_qos_add_notifier(notifier): + Adds a notification callback function to the CPU latency QoS. The callback is + called when the aggregated value for the CPU latency QoS is changed. -int pm_qos_add_notifier(param_class, notifier): - Adds a notification callback function to the PM QoS class. The callback is - called when the aggregated value for the PM QoS class is changed. +int cpu_latency_qos_remove_notifier(notifier): + Removes the notification callback function from the CPU latency QoS. -int pm_qos_remove_notifier(int param_class, notifier): - Removes the notification callback function for the PM QoS class. +From user space: -From user mode: +The infrastructure exposes one device node, /dev/cpu_dma_latency, for the CPU +latency QoS. -Only processes can register a pm_qos request. To provide for automatic +Only processes can register a PM QoS request. To provide for automatic cleanup of a process, the interface requires the process to register its -parameter requests in the following way: +parameter requests as follows. -To register the default pm_qos target for the specific parameter, the process -must open /dev/cpu_dma_latency +To register the default PM QoS target for the CPU latency QoS, the process must +open /dev/cpu_dma_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 the user mode program could write a hex -string for the value using 10 char long format e.g. "0x12345678". This -translates to a pm_qos_update_request call. +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. To remove the user mode request for a target value simply close the device node. -- cgit v1.2.3 From 3c87402771f2bc38ee92eb506bb58e4fc4a5b8b9 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 16 Feb 2020 20:54:21 -0800 Subject: Documentation: power: fix pm_qos_interface.rst format warning Fix Sphinx warnings by indenting the bullet list (and making it unnumbered). Documentation/power/pm_qos_interface.rst:12: WARNING: Unexpected indentation. Signed-off-by: Randy Dunlap Signed-off-by: Rafael J. Wysocki --- Documentation/power/pm_qos_interface.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/power/pm_qos_interface.rst b/Documentation/power/pm_qos_interface.rst index 064f668fbdab..69b0fe3e2542 100644 --- a/Documentation/power/pm_qos_interface.rst +++ b/Documentation/power/pm_qos_interface.rst @@ -7,8 +7,8 @@ performance expectations by drivers, subsystems and user space applications on one of the parameters. Two different PM QoS frameworks are available: -1. CPU latency QoS. -2. The per-device PM QoS framework provides the API to manage the + * CPU latency QoS. + * The per-device PM QoS framework provides the API to manage the per-device latency constraints and PM QoS flags. The latency unit used in the PM QoS framework is the microsecond (usec). -- cgit v1.2.3