2023-10-06 17:52:32

by Rafael J. Wysocki

[permalink] [raw]
Subject: [PATCH v1 0/6] thermal: core: Pass trip pointers to governor .throttle() callbacks

Hi All,

While working on https://lore.kernel.org/linux-pm/4846448.GXAFRqVoOG@kreacher/
I started to change thermal governors so as to reduce the usage of trip
indices in them. At that time, I was concerned that they could not be
replaced with trip pointers overall, because they were needed in certain
situations (tracing, debug messages, userspace governor) and computing them
whenever they were needed would be extra overhead with relatively weak
justification. In the meantime, however, I realized that for a given trip
pointer, it is actually trivial to compute the corresponding index: it is
sufficient to subtract the start of the trips[] table in the thermal zone
containing the trip from that trip pointer for this purpose. Patch [1/6]
modifies thermal_zone_trip_id() in accordance with this observation.

Now that the cost of computing a trip index for a given trip pointer and
thermal zone is not a concern any more, the governors can be generally
switched over to using trip pointers for representing trips. One of the
things they need to do sometimes, though, is to iterate over trips in a
given thermal zone (the core needs to do that too, of course) and
for_each_thermal_trip() is somewhat inconvenient for this purpose, because
it requires callback functions to be defined and in some cases new data
types need to be introduced just in order to use it. For this reason,
patch [2/6] adds a macro for iterating over trip points in a given thermal
zone with the help of a trip pointer and changes for_each_thermal_trip() to
use that macro internally.

Patches [3-5/6] change individual governors to prepare them for using trip
pointers everywhere for representing trips, except for the trip argument of
the .throttle() callback and patch [6/6] finally changes the .throttle()
callback definition so that it takes a trip pointer as the argument
representing the trip.

Please refer to the individual patch changelogs for details.

Thanks!




2023-10-06 17:52:38

by Rafael J. Wysocki

[permalink] [raw]
Subject: [PATCH v1 4/6] thermal: gov_power_allocator: Use trip pointers instead of trip indices

From: Rafael J. Wysocki <[email protected]>

Modify the power allocator thermal governor to use trip pointers instead
of trip indices everywhere except for the power_allocator_throttle()
second argument that will be changed subsequently along with the
definition of the .throttle() governor callback.

The general functionality is not expected to be changed.

Signed-off-by: Rafael J. Wysocki <[email protected]>
---
drivers/thermal/gov_power_allocator.c | 123 +++++++++++++---------------------
1 file changed, 49 insertions(+), 74 deletions(-)

Index: linux-pm/drivers/thermal/gov_power_allocator.c
===================================================================
--- linux-pm.orig/drivers/thermal/gov_power_allocator.c
+++ linux-pm/drivers/thermal/gov_power_allocator.c
@@ -16,8 +16,6 @@

#include "thermal_core.h"

-#define INVALID_TRIP -1
-
#define FRAC_BITS 10
#define int_to_frac(x) ((x) << FRAC_BITS)
#define frac_to_int(x) ((x) >> FRAC_BITS)
@@ -55,23 +53,23 @@ static inline s64 div_frac(s64 x, s64 y)
* @err_integral: accumulated error in the PID controller.
* @prev_err: error in the previous iteration of the PID controller.
* Used to calculate the derivative term.
+ * @sustainable_power: Sustainable power (heat) that this thermal zone can
+ * dissipate
* @trip_switch_on: first passive trip point of the thermal zone. The
* governor switches on when this trip point is crossed.
* If the thermal zone only has one passive trip point,
- * @trip_switch_on should be INVALID_TRIP.
+ * @trip_switch_on should be NULL.
* @trip_max_desired_temperature: last passive trip point of the thermal
* zone. The temperature we are
* controlling for.
- * @sustainable_power: Sustainable power (heat) that this thermal zone can
- * dissipate
*/
struct power_allocator_params {
bool allocated_tzp;
s64 err_integral;
s32 prev_err;
- int trip_switch_on;
- int trip_max_desired_temperature;
u32 sustainable_power;
+ const struct thermal_trip *trip_switch_on;
+ const struct thermal_trip *trip_max_desired_temperature;
};

/**
@@ -90,14 +88,12 @@ static u32 estimate_sustainable_power(st
u32 sustainable_power = 0;
struct thermal_instance *instance;
struct power_allocator_params *params = tz->governor_data;
- const struct thermal_trip *trip_max_desired_temperature =
- &tz->trips[params->trip_max_desired_temperature];

list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
struct thermal_cooling_device *cdev = instance->cdev;
u32 min_power;

- if (instance->trip != trip_max_desired_temperature)
+ if (instance->trip != params->trip_max_desired_temperature)
continue;

if (!cdev_is_power_actor(cdev))
@@ -116,24 +112,23 @@ static u32 estimate_sustainable_power(st
* estimate_pid_constants() - Estimate the constants for the PID controller
* @tz: thermal zone for which to estimate the constants
* @sustainable_power: sustainable power for the thermal zone
- * @trip_switch_on: trip point number for the switch on temperature
+ * @trip_switch_on: trip point for the switch on temperature
* @control_temp: target temperature for the power allocator governor
*
* This function is used to update the estimation of the PID
* controller constants in struct thermal_zone_parameters.
*/
static void estimate_pid_constants(struct thermal_zone_device *tz,
- u32 sustainable_power, int trip_switch_on,
+ u32 sustainable_power,
+ const struct thermal_trip *trip_switch_on,
int control_temp)
{
- struct thermal_trip trip;
u32 temperature_threshold = control_temp;
int ret;
s32 k_i;

- ret = __thermal_zone_get_trip(tz, trip_switch_on, &trip);
- if (!ret)
- temperature_threshold -= trip.temperature;
+ if (trip_switch_on)
+ temperature_threshold -= trip_switch_on->temperature;

/*
* estimate_pid_constants() tries to find appropriate default
@@ -386,7 +381,7 @@ static int allocate_power(struct thermal
struct thermal_instance *instance;
struct power_allocator_params *params = tz->governor_data;
const struct thermal_trip *trip_max_desired_temperature =
- &tz->trips[params->trip_max_desired_temperature];
+ params->trip_max_desired_temperature;
u32 *req_power, *max_power, *granted_power, *extra_actor_power;
u32 *weighted_req_power;
u32 total_req_power, max_allocatable_power, total_weighted_req_power;
@@ -496,7 +491,7 @@ static int allocate_power(struct thermal
}

/**
- * get_governor_trips() - get the number of the two trip points that are key for this governor
+ * get_governor_trips() - get the two trip points that are key for this governor
* @tz: thermal zone to operate on
* @params: pointer to private data for this governor
*
@@ -513,46 +508,36 @@ static int allocate_power(struct thermal
static void get_governor_trips(struct thermal_zone_device *tz,
struct power_allocator_params *params)
{
- int i, last_active, last_passive;
- bool found_first_passive;
-
- found_first_passive = false;
- last_active = INVALID_TRIP;
- last_passive = INVALID_TRIP;
-
- for (i = 0; i < tz->num_trips; i++) {
- struct thermal_trip trip;
- int ret;
-
- ret = __thermal_zone_get_trip(tz, i, &trip);
- if (ret) {
- dev_warn(&tz->device,
- "Failed to get trip point %d type: %d\n", i,
- ret);
- continue;
- }
-
- if (trip.type == THERMAL_TRIP_PASSIVE) {
- if (!found_first_passive) {
- params->trip_switch_on = i;
- found_first_passive = true;
- } else {
- last_passive = i;
+ const struct thermal_trip *first_passive = NULL;
+ const struct thermal_trip *last_passive = NULL;
+ const struct thermal_trip *last_active = NULL;
+ const struct thermal_trip *trip;
+
+ for_each_trip(tz, trip) {
+ switch (trip->type) {
+ case THERMAL_TRIP_PASSIVE:
+ if (!first_passive) {
+ first_passive = trip;
+ break;
}
- } else if (trip.type == THERMAL_TRIP_ACTIVE) {
- last_active = i;
- } else {
+ last_passive = trip;
+ break;
+ case THERMAL_TRIP_ACTIVE:
+ last_active = trip;
+ break;
+ default:
break;
}
}

- if (last_passive != INVALID_TRIP) {
+ if (last_passive) {
+ params->trip_switch_on = first_passive;
params->trip_max_desired_temperature = last_passive;
- } else if (found_first_passive) {
- params->trip_max_desired_temperature = params->trip_switch_on;
- params->trip_switch_on = INVALID_TRIP;
+ } else if (first_passive) {
+ params->trip_switch_on = NULL;
+ params->trip_max_desired_temperature = first_passive;
} else {
- params->trip_switch_on = INVALID_TRIP;
+ params->trip_switch_on = NULL;
params->trip_max_desired_temperature = last_active;
}
}
@@ -567,14 +552,12 @@ static void allow_maximum_power(struct t
{
struct thermal_instance *instance;
struct power_allocator_params *params = tz->governor_data;
- const struct thermal_trip *trip_max_desired_temperature =
- &tz->trips[params->trip_max_desired_temperature];
u32 req_power;

list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
struct thermal_cooling_device *cdev = instance->cdev;

- if ((instance->trip != trip_max_desired_temperature) ||
+ if (instance->trip != params->trip_max_desired_temperature ||
(!cdev_is_power_actor(instance->cdev)))
continue;

@@ -636,7 +619,6 @@ static int power_allocator_bind(struct t
{
int ret;
struct power_allocator_params *params;
- struct thermal_trip trip;

ret = check_power_actors(tz);
if (ret)
@@ -662,12 +644,13 @@ static int power_allocator_bind(struct t
get_governor_trips(tz, params);

if (tz->num_trips > 0) {
- ret = __thermal_zone_get_trip(tz, params->trip_max_desired_temperature,
- &trip);
- if (!ret)
+ const struct thermal_trip *trip;
+
+ trip = params->trip_max_desired_temperature;
+ if (trip)
estimate_pid_constants(tz, tz->tzp->sustainable_power,
params->trip_switch_on,
- trip.temperature);
+ trip->temperature);
}

reset_pid_controller(params);
@@ -697,11 +680,10 @@ static void power_allocator_unbind(struc
tz->governor_data = NULL;
}

-static int power_allocator_throttle(struct thermal_zone_device *tz, int trip_id)
+static int power_allocator_throttle(struct thermal_zone_device *tz, int trip_index)
{
struct power_allocator_params *params = tz->governor_data;
- struct thermal_trip trip;
- int ret;
+ const struct thermal_trip *trip = &tz->trips[trip_index];
bool update;

lockdep_assert_held(&tz->lock);
@@ -710,12 +692,12 @@ static int power_allocator_throttle(stru
* We get called for every trip point but we only need to do
* our calculations once
*/
- if (trip_id != params->trip_max_desired_temperature)
+ if (trip != params->trip_max_desired_temperature)
return 0;

- ret = __thermal_zone_get_trip(tz, params->trip_switch_on, &trip);
- if (!ret && (tz->temperature < trip.temperature)) {
- update = (tz->last_temperature >= trip.temperature);
+ trip = params->trip_switch_on;
+ if (trip && tz->temperature < trip->temperature) {
+ update = tz->last_temperature >= trip->temperature;
tz->passive = 0;
reset_pid_controller(params);
allow_maximum_power(tz, update);
@@ -724,14 +706,7 @@ static int power_allocator_throttle(stru

tz->passive = 1;

- ret = __thermal_zone_get_trip(tz, params->trip_max_desired_temperature, &trip);
- if (ret) {
- dev_warn(&tz->device, "Failed to get the maximum desired temperature: %d\n",
- ret);
- return ret;
- }
-
- return allocate_power(tz, trip.temperature);
+ return allocate_power(tz, params->trip_max_desired_temperature->temperature);
}

static struct thermal_governor thermal_gov_power_allocator = {



2023-10-12 15:19:54

by Daniel Lezcano

[permalink] [raw]
Subject: Re: [PATCH v1 4/6] thermal: gov_power_allocator: Use trip pointers instead of trip indices

On 06/10/2023 19:47, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <[email protected]>
>
> Modify the power allocator thermal governor to use trip pointers instead
> of trip indices everywhere except for the power_allocator_throttle()
> second argument that will be changed subsequently along with the
> definition of the .throttle() governor callback.
>
> The general functionality is not expected to be changed.
>
> Signed-off-by: Rafael J. Wysocki <[email protected]>
> ---
> drivers/thermal/gov_power_allocator.c | 123 +++++++++++++---------------------
> 1 file changed, 49 insertions(+), 74 deletions(-)
>
> Index: linux-pm/drivers/thermal/gov_power_allocator.c
> ===================================================================
> --- linux-pm.orig/drivers/thermal/gov_power_allocator.c
> +++ linux-pm/drivers/thermal/gov_power_allocator.c
> @@ -16,8 +16,6 @@
>
> #include "thermal_core.h"
>
> -#define INVALID_TRIP -1
> -
> #define FRAC_BITS 10
> #define int_to_frac(x) ((x) << FRAC_BITS)
> #define frac_to_int(x) ((x) >> FRAC_BITS)
> @@ -55,23 +53,23 @@ static inline s64 div_frac(s64 x, s64 y)
> * @err_integral: accumulated error in the PID controller.
> * @prev_err: error in the previous iteration of the PID controller.
> * Used to calculate the derivative term.
> + * @sustainable_power: Sustainable power (heat) that this thermal zone can
> + * dissipate
> * @trip_switch_on: first passive trip point of the thermal zone. The
> * governor switches on when this trip point is crossed.
> * If the thermal zone only has one passive trip point,
> - * @trip_switch_on should be INVALID_TRIP.
> + * @trip_switch_on should be NULL.
> * @trip_max_desired_temperature: last passive trip point of the thermal
> * zone. The temperature we are
> * controlling for.
> - * @sustainable_power: Sustainable power (heat) that this thermal zone can
> - * dissipate
> */
> struct power_allocator_params {
> bool allocated_tzp;
> s64 err_integral;
> s32 prev_err;
> - int trip_switch_on;
> - int trip_max_desired_temperature;
> u32 sustainable_power;
> + const struct thermal_trip *trip_switch_on;
> + const struct thermal_trip *trip_max_desired_temperature;
> };
>
> /**
> @@ -90,14 +88,12 @@ static u32 estimate_sustainable_power(st
> u32 sustainable_power = 0;
> struct thermal_instance *instance;
> struct power_allocator_params *params = tz->governor_data;
> - const struct thermal_trip *trip_max_desired_temperature =
> - &tz->trips[params->trip_max_desired_temperature];
>
> list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
> struct thermal_cooling_device *cdev = instance->cdev;
> u32 min_power;
>
> - if (instance->trip != trip_max_desired_temperature)
> + if (instance->trip != params->trip_max_desired_temperature)
> continue;
>
> if (!cdev_is_power_actor(cdev))
> @@ -116,24 +112,23 @@ static u32 estimate_sustainable_power(st
> * estimate_pid_constants() - Estimate the constants for the PID controller
> * @tz: thermal zone for which to estimate the constants
> * @sustainable_power: sustainable power for the thermal zone
> - * @trip_switch_on: trip point number for the switch on temperature
> + * @trip_switch_on: trip point for the switch on temperature
> * @control_temp: target temperature for the power allocator governor
> *
> * This function is used to update the estimation of the PID
> * controller constants in struct thermal_zone_parameters.
> */
> static void estimate_pid_constants(struct thermal_zone_device *tz,
> - u32 sustainable_power, int trip_switch_on,
> + u32 sustainable_power,
> + const struct thermal_trip *trip_switch_on,
> int control_temp)
> {
> - struct thermal_trip trip;
> u32 temperature_threshold = control_temp;
> int ret;
> s32 k_i;
>
> - ret = __thermal_zone_get_trip(tz, trip_switch_on, &trip);
> - if (!ret)
> - temperature_threshold -= trip.temperature;
> + if (trip_switch_on)
> + temperature_threshold -= trip_switch_on->temperature;
>
> /*
> * estimate_pid_constants() tries to find appropriate default
> @@ -386,7 +381,7 @@ static int allocate_power(struct thermal
> struct thermal_instance *instance;
> struct power_allocator_params *params = tz->governor_data;
> const struct thermal_trip *trip_max_desired_temperature =
> - &tz->trips[params->trip_max_desired_temperature];
> + params->trip_max_desired_temperature;
> u32 *req_power, *max_power, *granted_power, *extra_actor_power;
> u32 *weighted_req_power;
> u32 total_req_power, max_allocatable_power, total_weighted_req_power;
> @@ -496,7 +491,7 @@ static int allocate_power(struct thermal
> }
>
> /**
> - * get_governor_trips() - get the number of the two trip points that are key for this governor
> + * get_governor_trips() - get the two trip points that are key for this governor
> * @tz: thermal zone to operate on
> * @params: pointer to private data for this governor
> *
> @@ -513,46 +508,36 @@ static int allocate_power(struct thermal
> static void get_governor_trips(struct thermal_zone_device *tz,
> struct power_allocator_params *params)
> {
> - int i, last_active, last_passive;
> - bool found_first_passive;
> -
> - found_first_passive = false;
> - last_active = INVALID_TRIP;
> - last_passive = INVALID_TRIP;
> -
> - for (i = 0; i < tz->num_trips; i++) {
> - struct thermal_trip trip;
> - int ret;
> -
> - ret = __thermal_zone_get_trip(tz, i, &trip);
> - if (ret) {
> - dev_warn(&tz->device,
> - "Failed to get trip point %d type: %d\n", i,
> - ret);
> - continue;
> - }
> -
> - if (trip.type == THERMAL_TRIP_PASSIVE) {
> - if (!found_first_passive) {
> - params->trip_switch_on = i;
> - found_first_passive = true;
> - } else {
> - last_passive = i;
> + const struct thermal_trip *first_passive = NULL;
> + const struct thermal_trip *last_passive = NULL;
> + const struct thermal_trip *last_active = NULL;
> + const struct thermal_trip *trip;
> +
> + for_each_trip(tz, trip) {
> + switch (trip->type) {
> + case THERMAL_TRIP_PASSIVE:
> + if (!first_passive) {
> + first_passive = trip;
> + break;
> }
> - } else if (trip.type == THERMAL_TRIP_ACTIVE) {
> - last_active = i;
> - } else {
> + last_passive = trip;
> + break;
> + case THERMAL_TRIP_ACTIVE:
> + last_active = trip;
> + break;
> + default:
> break;
> }
> }
>
> - if (last_passive != INVALID_TRIP) {
> + if (last_passive) {
> + params->trip_switch_on = first_passive;
> params->trip_max_desired_temperature = last_passive;
> - } else if (found_first_passive) {
> - params->trip_max_desired_temperature = params->trip_switch_on;
> - params->trip_switch_on = INVALID_TRIP;
> + } else if (first_passive) {
> + params->trip_switch_on = NULL;
> + params->trip_max_desired_temperature = first_passive;
> } else {
> - params->trip_switch_on = INVALID_TRIP;
> + params->trip_switch_on = NULL;
> params->trip_max_desired_temperature = last_active;
> }
> }
> @@ -567,14 +552,12 @@ static void allow_maximum_power(struct t
> {
> struct thermal_instance *instance;
> struct power_allocator_params *params = tz->governor_data;
> - const struct thermal_trip *trip_max_desired_temperature =
> - &tz->trips[params->trip_max_desired_temperature];
> u32 req_power;
>
> list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
> struct thermal_cooling_device *cdev = instance->cdev;
>
> - if ((instance->trip != trip_max_desired_temperature) ||
> + if (instance->trip != params->trip_max_desired_temperature ||
> (!cdev_is_power_actor(instance->cdev)))
> continue;
>
> @@ -636,7 +619,6 @@ static int power_allocator_bind(struct t
> {
> int ret;
> struct power_allocator_params *params;
> - struct thermal_trip trip;
>
> ret = check_power_actors(tz);
> if (ret)
> @@ -662,12 +644,13 @@ static int power_allocator_bind(struct t
> get_governor_trips(tz, params);
>
> if (tz->num_trips > 0) {

Maybe this test can go away because if (trip) is true below, then
logically (tz->num_trips > 0) ?

> - ret = __thermal_zone_get_trip(tz, params->trip_max_desired_temperature,
> - &trip);
> - if (!ret)
> + const struct thermal_trip *trip;
> +
> + trip = params->trip_max_desired_temperature;
> + if (trip)
> estimate_pid_constants(tz, tz->tzp->sustainable_power,
> params->trip_switch_on,
> - trip.temperature);
> + trip->temperature);
> }
>
> reset_pid_controller(params);
> @@ -697,11 +680,10 @@ static void power_allocator_unbind(struc
> tz->governor_data = NULL;
> }
>
> -static int power_allocator_throttle(struct thermal_zone_device *tz, int trip_id)
> +static int power_allocator_throttle(struct thermal_zone_device *tz, int trip_index)
> {
> struct power_allocator_params *params = tz->governor_data;
> - struct thermal_trip trip;
> - int ret;
> + const struct thermal_trip *trip = &tz->trips[trip_index];
> bool update;
>
> lockdep_assert_held(&tz->lock);
> @@ -710,12 +692,12 @@ static int power_allocator_throttle(stru
> * We get called for every trip point but we only need to do
> * our calculations once
> */
> - if (trip_id != params->trip_max_desired_temperature)
> + if (trip != params->trip_max_desired_temperature)
> return 0;
>
> - ret = __thermal_zone_get_trip(tz, params->trip_switch_on, &trip);
> - if (!ret && (tz->temperature < trip.temperature)) {
> - update = (tz->last_temperature >= trip.temperature);
> + trip = params->trip_switch_on;
> + if (trip && tz->temperature < trip->temperature) {
> + update = tz->last_temperature >= trip->temperature;
> tz->passive = 0;
> reset_pid_controller(params);
> allow_maximum_power(tz, update);
> @@ -724,14 +706,7 @@ static int power_allocator_throttle(stru
>
> tz->passive = 1;
>
> - ret = __thermal_zone_get_trip(tz, params->trip_max_desired_temperature, &trip);
> - if (ret) {
> - dev_warn(&tz->device, "Failed to get the maximum desired temperature: %d\n",
> - ret);
> - return ret;
> - }
> -
> - return allocate_power(tz, trip.temperature);
> + return allocate_power(tz, params->trip_max_desired_temperature->temperature);
> }
>
> static struct thermal_governor thermal_gov_power_allocator = {
>
>
>

--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

2023-10-12 16:36:56

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH v1 4/6] thermal: gov_power_allocator: Use trip pointers instead of trip indices

On Thu, Oct 12, 2023 at 5:19 PM Daniel Lezcano
<[email protected]> wrote:
>
> On 06/10/2023 19:47, Rafael J. Wysocki wrote:
> > From: Rafael J. Wysocki <[email protected]>
> >
> > Modify the power allocator thermal governor to use trip pointers instead
> > of trip indices everywhere except for the power_allocator_throttle()
> > second argument that will be changed subsequently along with the
> > definition of the .throttle() governor callback.
> >
> > The general functionality is not expected to be changed.
> >
> > Signed-off-by: Rafael J. Wysocki <[email protected]>
> > ---
> > drivers/thermal/gov_power_allocator.c | 123 +++++++++++++---------------------
> > 1 file changed, 49 insertions(+), 74 deletions(-)
> >
> > Index: linux-pm/drivers/thermal/gov_power_allocator.c
> > ===================================================================
> > --- linux-pm.orig/drivers/thermal/gov_power_allocator.c
> > +++ linux-pm/drivers/thermal/gov_power_allocator.c
> > @@ -16,8 +16,6 @@
> >
> > #include "thermal_core.h"
> >
> > -#define INVALID_TRIP -1
> > -
> > #define FRAC_BITS 10
> > #define int_to_frac(x) ((x) << FRAC_BITS)
> > #define frac_to_int(x) ((x) >> FRAC_BITS)
> > @@ -55,23 +53,23 @@ static inline s64 div_frac(s64 x, s64 y)
> > * @err_integral: accumulated error in the PID controller.
> > * @prev_err: error in the previous iteration of the PID controller.
> > * Used to calculate the derivative term.
> > + * @sustainable_power: Sustainable power (heat) that this thermal zone can
> > + * dissipate
> > * @trip_switch_on: first passive trip point of the thermal zone. The
> > * governor switches on when this trip point is crossed.
> > * If the thermal zone only has one passive trip point,
> > - * @trip_switch_on should be INVALID_TRIP.
> > + * @trip_switch_on should be NULL.
> > * @trip_max_desired_temperature: last passive trip point of the thermal
> > * zone. The temperature we are
> > * controlling for.
> > - * @sustainable_power: Sustainable power (heat) that this thermal zone can
> > - * dissipate
> > */
> > struct power_allocator_params {
> > bool allocated_tzp;
> > s64 err_integral;
> > s32 prev_err;
> > - int trip_switch_on;
> > - int trip_max_desired_temperature;
> > u32 sustainable_power;
> > + const struct thermal_trip *trip_switch_on;
> > + const struct thermal_trip *trip_max_desired_temperature;
> > };
> >
> > /**
> > @@ -90,14 +88,12 @@ static u32 estimate_sustainable_power(st
> > u32 sustainable_power = 0;
> > struct thermal_instance *instance;
> > struct power_allocator_params *params = tz->governor_data;
> > - const struct thermal_trip *trip_max_desired_temperature =
> > - &tz->trips[params->trip_max_desired_temperature];
> >
> > list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
> > struct thermal_cooling_device *cdev = instance->cdev;
> > u32 min_power;
> >
> > - if (instance->trip != trip_max_desired_temperature)
> > + if (instance->trip != params->trip_max_desired_temperature)
> > continue;
> >
> > if (!cdev_is_power_actor(cdev))
> > @@ -116,24 +112,23 @@ static u32 estimate_sustainable_power(st
> > * estimate_pid_constants() - Estimate the constants for the PID controller
> > * @tz: thermal zone for which to estimate the constants
> > * @sustainable_power: sustainable power for the thermal zone
> > - * @trip_switch_on: trip point number for the switch on temperature
> > + * @trip_switch_on: trip point for the switch on temperature
> > * @control_temp: target temperature for the power allocator governor
> > *
> > * This function is used to update the estimation of the PID
> > * controller constants in struct thermal_zone_parameters.
> > */
> > static void estimate_pid_constants(struct thermal_zone_device *tz,
> > - u32 sustainable_power, int trip_switch_on,
> > + u32 sustainable_power,
> > + const struct thermal_trip *trip_switch_on,
> > int control_temp)
> > {
> > - struct thermal_trip trip;
> > u32 temperature_threshold = control_temp;
> > int ret;
> > s32 k_i;
> >
> > - ret = __thermal_zone_get_trip(tz, trip_switch_on, &trip);
> > - if (!ret)
> > - temperature_threshold -= trip.temperature;
> > + if (trip_switch_on)
> > + temperature_threshold -= trip_switch_on->temperature;
> >
> > /*
> > * estimate_pid_constants() tries to find appropriate default
> > @@ -386,7 +381,7 @@ static int allocate_power(struct thermal
> > struct thermal_instance *instance;
> > struct power_allocator_params *params = tz->governor_data;
> > const struct thermal_trip *trip_max_desired_temperature =
> > - &tz->trips[params->trip_max_desired_temperature];
> > + params->trip_max_desired_temperature;
> > u32 *req_power, *max_power, *granted_power, *extra_actor_power;
> > u32 *weighted_req_power;
> > u32 total_req_power, max_allocatable_power, total_weighted_req_power;
> > @@ -496,7 +491,7 @@ static int allocate_power(struct thermal
> > }
> >
> > /**
> > - * get_governor_trips() - get the number of the two trip points that are key for this governor
> > + * get_governor_trips() - get the two trip points that are key for this governor
> > * @tz: thermal zone to operate on
> > * @params: pointer to private data for this governor
> > *
> > @@ -513,46 +508,36 @@ static int allocate_power(struct thermal
> > static void get_governor_trips(struct thermal_zone_device *tz,
> > struct power_allocator_params *params)
> > {
> > - int i, last_active, last_passive;
> > - bool found_first_passive;
> > -
> > - found_first_passive = false;
> > - last_active = INVALID_TRIP;
> > - last_passive = INVALID_TRIP;
> > -
> > - for (i = 0; i < tz->num_trips; i++) {
> > - struct thermal_trip trip;
> > - int ret;
> > -
> > - ret = __thermal_zone_get_trip(tz, i, &trip);
> > - if (ret) {
> > - dev_warn(&tz->device,
> > - "Failed to get trip point %d type: %d\n", i,
> > - ret);
> > - continue;
> > - }
> > -
> > - if (trip.type == THERMAL_TRIP_PASSIVE) {
> > - if (!found_first_passive) {
> > - params->trip_switch_on = i;
> > - found_first_passive = true;
> > - } else {
> > - last_passive = i;
> > + const struct thermal_trip *first_passive = NULL;
> > + const struct thermal_trip *last_passive = NULL;
> > + const struct thermal_trip *last_active = NULL;
> > + const struct thermal_trip *trip;
> > +
> > + for_each_trip(tz, trip) {
> > + switch (trip->type) {
> > + case THERMAL_TRIP_PASSIVE:
> > + if (!first_passive) {
> > + first_passive = trip;
> > + break;
> > }
> > - } else if (trip.type == THERMAL_TRIP_ACTIVE) {
> > - last_active = i;
> > - } else {
> > + last_passive = trip;
> > + break;
> > + case THERMAL_TRIP_ACTIVE:
> > + last_active = trip;
> > + break;
> > + default:
> > break;
> > }
> > }
> >
> > - if (last_passive != INVALID_TRIP) {
> > + if (last_passive) {
> > + params->trip_switch_on = first_passive;
> > params->trip_max_desired_temperature = last_passive;
> > - } else if (found_first_passive) {
> > - params->trip_max_desired_temperature = params->trip_switch_on;
> > - params->trip_switch_on = INVALID_TRIP;
> > + } else if (first_passive) {
> > + params->trip_switch_on = NULL;
> > + params->trip_max_desired_temperature = first_passive;
> > } else {
> > - params->trip_switch_on = INVALID_TRIP;
> > + params->trip_switch_on = NULL;
> > params->trip_max_desired_temperature = last_active;
> > }
> > }
> > @@ -567,14 +552,12 @@ static void allow_maximum_power(struct t
> > {
> > struct thermal_instance *instance;
> > struct power_allocator_params *params = tz->governor_data;
> > - const struct thermal_trip *trip_max_desired_temperature =
> > - &tz->trips[params->trip_max_desired_temperature];
> > u32 req_power;
> >
> > list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
> > struct thermal_cooling_device *cdev = instance->cdev;
> >
> > - if ((instance->trip != trip_max_desired_temperature) ||
> > + if (instance->trip != params->trip_max_desired_temperature ||
> > (!cdev_is_power_actor(instance->cdev)))
> > continue;
> >
> > @@ -636,7 +619,6 @@ static int power_allocator_bind(struct t
> > {
> > int ret;
> > struct power_allocator_params *params;
> > - struct thermal_trip trip;
> >
> > ret = check_power_actors(tz);
> > if (ret)
> > @@ -662,12 +644,13 @@ static int power_allocator_bind(struct t
> > get_governor_trips(tz, params);
> >
> > if (tz->num_trips > 0) {
>
> Maybe this test can go away because if (trip) is true below, then
> logically (tz->num_trips > 0) ?

Yes, it can go away.

> > - ret = __thermal_zone_get_trip(tz, params->trip_max_desired_temperature,
> > - &trip);
> > - if (!ret)
> > + const struct thermal_trip *trip;
> > +
> > + trip = params->trip_max_desired_temperature;
> > + if (trip)
> > estimate_pid_constants(tz, tz->tzp->sustainable_power,
> > params->trip_switch_on,
> > - trip.temperature);
> > + trip->temperature);
> > }
> >
> > reset_pid_controller(params);
> > @@ -697,11 +680,10 @@ static void power_allocator_unbind(struc
> > tz->governor_data = NULL;
> > }
> >
> > -static int power_allocator_throttle(struct thermal_zone_device *tz, int trip_id)
> > +static int power_allocator_throttle(struct thermal_zone_device *tz, int trip_index)
> > {
> > struct power_allocator_params *params = tz->governor_data;
> > - struct thermal_trip trip;
> > - int ret;
> > + const struct thermal_trip *trip = &tz->trips[trip_index];
> > bool update;
> >
> > lockdep_assert_held(&tz->lock);
> > @@ -710,12 +692,12 @@ static int power_allocator_throttle(stru
> > * We get called for every trip point but we only need to do
> > * our calculations once
> > */
> > - if (trip_id != params->trip_max_desired_temperature)
> > + if (trip != params->trip_max_desired_temperature)
> > return 0;
> >
> > - ret = __thermal_zone_get_trip(tz, params->trip_switch_on, &trip);
> > - if (!ret && (tz->temperature < trip.temperature)) {
> > - update = (tz->last_temperature >= trip.temperature);
> > + trip = params->trip_switch_on;
> > + if (trip && tz->temperature < trip->temperature) {
> > + update = tz->last_temperature >= trip->temperature;
> > tz->passive = 0;
> > reset_pid_controller(params);
> > allow_maximum_power(tz, update);
> > @@ -724,14 +706,7 @@ static int power_allocator_throttle(stru
> >
> > tz->passive = 1;
> >
> > - ret = __thermal_zone_get_trip(tz, params->trip_max_desired_temperature, &trip);
> > - if (ret) {
> > - dev_warn(&tz->device, "Failed to get the maximum desired temperature: %d\n",
> > - ret);
> > - return ret;
> > - }
> > -
> > - return allocate_power(tz, trip.temperature);
> > + return allocate_power(tz, params->trip_max_desired_temperature->temperature);
> > }
> >
> > static struct thermal_governor thermal_gov_power_allocator = {
> >
> >
> >
>
> --
> <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
>
> Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
> <http://twitter.com/#!/linaroorg> Twitter |
> <http://www.linaro.org/linaro-blog/> Blog
>

2023-10-13 08:12:39

by Lukasz Luba

[permalink] [raw]
Subject: Re: [PATCH v1 0/6] thermal: core: Pass trip pointers to governor .throttle() callbacks

Hi Rafael,


On 10/6/23 18:38, Rafael J. Wysocki wrote:
> Hi All,
>
> While working on https://lore.kernel.org/linux-pm/4846448.GXAFRqVoOG@kreacher/
> I started to change thermal governors so as to reduce the usage of trip
> indices in them. At that time, I was concerned that they could not be
> replaced with trip pointers overall, because they were needed in certain
> situations (tracing, debug messages, userspace governor) and computing them
> whenever they were needed would be extra overhead with relatively weak
> justification. In the meantime, however, I realized that for a given trip
> pointer, it is actually trivial to compute the corresponding index: it is
> sufficient to subtract the start of the trips[] table in the thermal zone
> containing the trip from that trip pointer for this purpose. Patch [1/6]
> modifies thermal_zone_trip_id() in accordance with this observation.
>
> Now that the cost of computing a trip index for a given trip pointer and
> thermal zone is not a concern any more, the governors can be generally
> switched over to using trip pointers for representing trips. One of the
> things they need to do sometimes, though, is to iterate over trips in a
> given thermal zone (the core needs to do that too, of course) and
> for_each_thermal_trip() is somewhat inconvenient for this purpose, because
> it requires callback functions to be defined and in some cases new data
> types need to be introduced just in order to use it. For this reason,
> patch [2/6] adds a macro for iterating over trip points in a given thermal
> zone with the help of a trip pointer and changes for_each_thermal_trip() to
> use that macro internally.
>
> Patches [3-5/6] change individual governors to prepare them for using trip
> pointers everywhere for representing trips, except for the trip argument of
> the .throttle() callback and patch [6/6] finally changes the .throttle()
> callback definition so that it takes a trip pointer as the argument
> representing the trip.
>
> Please refer to the individual patch changelogs for details.
>
> Thanks!
>
>
>

I have issues to apply this series, could you tell me the best
base branch from your tree?

I will give it a try on my boards and review.

Thanks,
Lukasz

2023-10-13 10:07:36

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH v1 0/6] thermal: core: Pass trip pointers to governor .throttle() callbacks

Hi Lukasz,

On Fri, Oct 13, 2023 at 10:12 AM Lukasz Luba <[email protected]> wrote:
>
> Hi Rafael,
>
>
> On 10/6/23 18:38, Rafael J. Wysocki wrote:
> > Hi All,
> >
> > While working on https://lore.kernel.org/linux-pm/4846448.GXAFRqVoOG@kreacher/
> > I started to change thermal governors so as to reduce the usage of trip
> > indices in them. At that time, I was concerned that they could not be
> > replaced with trip pointers overall, because they were needed in certain
> > situations (tracing, debug messages, userspace governor) and computing them
> > whenever they were needed would be extra overhead with relatively weak
> > justification. In the meantime, however, I realized that for a given trip
> > pointer, it is actually trivial to compute the corresponding index: it is
> > sufficient to subtract the start of the trips[] table in the thermal zone
> > containing the trip from that trip pointer for this purpose. Patch [1/6]
> > modifies thermal_zone_trip_id() in accordance with this observation.
> >
> > Now that the cost of computing a trip index for a given trip pointer and
> > thermal zone is not a concern any more, the governors can be generally
> > switched over to using trip pointers for representing trips. One of the
> > things they need to do sometimes, though, is to iterate over trips in a
> > given thermal zone (the core needs to do that too, of course) and
> > for_each_thermal_trip() is somewhat inconvenient for this purpose, because
> > it requires callback functions to be defined and in some cases new data
> > types need to be introduced just in order to use it. For this reason,
> > patch [2/6] adds a macro for iterating over trip points in a given thermal
> > zone with the help of a trip pointer and changes for_each_thermal_trip() to
> > use that macro internally.
> >
> > Patches [3-5/6] change individual governors to prepare them for using trip
> > pointers everywhere for representing trips, except for the trip argument of
> > the .throttle() callback and patch [6/6] finally changes the .throttle()
> > callback definition so that it takes a trip pointer as the argument
> > representing the trip.
> >
> > Please refer to the individual patch changelogs for details.
> >
> > Thanks!
> >
> >
> >
>
> I have issues to apply this series, could you tell me the best
> base branch from your tree?
>
> I will give it a try on my boards and review.

It is there in the thermal-core branch of linux-pm.git.

Thanks!

2023-10-20 16:37:53

by Lukasz Luba

[permalink] [raw]
Subject: Re: [PATCH v1 4/6] thermal: gov_power_allocator: Use trip pointers instead of trip indices



On 10/6/23 18:47, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <[email protected]>
>
> Modify the power allocator thermal governor to use trip pointers instead
> of trip indices everywhere except for the power_allocator_throttle()
> second argument that will be changed subsequently along with the
> definition of the .throttle() governor callback.
>
> The general functionality is not expected to be changed.
>
> Signed-off-by: Rafael J. Wysocki <[email protected]>
> ---
> drivers/thermal/gov_power_allocator.c | 123 +++++++++++++---------------------
> 1 file changed, 49 insertions(+), 74 deletions(-)
>

[snip]

> @@ -636,7 +619,6 @@ static int power_allocator_bind(struct t
> {
> int ret;
> struct power_allocator_params *params;
> - struct thermal_trip trip;
>
> ret = check_power_actors(tz);
> if (ret)
> @@ -662,12 +644,13 @@ static int power_allocator_bind(struct t
> get_governor_trips(tz, params);
>
> if (tz->num_trips > 0) {
> - ret = __thermal_zone_get_trip(tz, params->trip_max_desired_temperature,
> - &trip);
> - if (!ret)
> + const struct thermal_trip *trip;
> +
> + trip = params->trip_max_desired_temperature;
> + if (trip)
> estimate_pid_constants(tz, tz->tzp->sustainable_power,
> params->trip_switch_on,
> - trip.temperature);
> + trip->temperature);
> }

The code check for the populated pointer (by earlier new
get_governor_trips(tz, params)) :

if (params->trip_max_desired_temperature) {
int temp = params->trip_max_desired_temperature->temperature;

estimate_pid_constants(...)
}

looks better (what you have figured out already).

Other than that the patch LGTM:

Reviewed-by: Lukasz Luba <[email protected]>
Tested-by: Lukasz Luba <[email protected]>

I have also tested this is a few ways and it still works as expected:
1. Power allocation in different conditions
2. Trip points properly recognized with this nice get_governor_trips(),
here is the test output, with many tricky trip point setups:

use case A:
5 trip points:
- 2 passive for 50, 60 degC
- 1 active 70degC
- 2 passive 70, 85 degC
- 1 critical 120 degC

expected IPA trip points: 50, 85 deg => 35 degC IPA operating range

[ 24.578806] Power allocator: IPA: trip->temperature=50000
[ 24.578824] Power allocator: IPA: passive trip->temperature=50000
[ 24.578838] Power allocator: IPA: fist passive trip->temperature=50000
[ 24.578851] Power allocator: IPA: trip->temperature=60000
[ 24.578863] Power allocator: IPA: passive trip->temperature=60000
[ 24.578875] Power allocator: IPA: trip->temperature=70000
[ 24.578888] Power allocator: IPA: active trip->temperature=70000
[ 24.578900] Power allocator: IPA: trip->temperature=120000
[ 24.578912] Power allocator: IPA: trip->temperature=70000
[ 24.578925] Power allocator: IPA: passive trip->temperature=70000
[ 24.578937] Power allocator: IPA: trip->temperature=85000
[ 24.578950] Power allocator: IPA: passive trip->temperature=85000
[ 24.578964] Power allocator: IPA: trip_switch_on->temperature=50000
control_temp=85000
[ 24.578978] Power allocator: IPA: temperature_threshold=35000

-------------------------------------------------------------
use case B:
5 trip points:
- 2 active for 50, 60 degC
- 1 active 70degC
- 2 passive 70, 85 degC
- 1 critical 120 degC

expected IPA trip points: 70, 85 deg => 15 degC IPA operating range

[ 27.402474] Power allocator: IPA: trip->temperature=50000
[ 27.402492] Power allocator: IPA: active trip->temperature=50000
[ 27.402505] Power allocator: IPA: trip->temperature=60000
[ 27.402518] Power allocator: IPA: active trip->temperature=60000
[ 27.402531] Power allocator: IPA: trip->temperature=70000
[ 27.402544] Power allocator: IPA: active trip->temperature=70000
[ 27.402557] Power allocator: IPA: trip->temperature=120000
[ 27.402570] Power allocator: IPA: trip->temperature=70000
[ 27.402582] Power allocator: IPA: passive trip->temperature=70000
[ 27.402596] Power allocator: IPA: fist passive trip->temperature=70000
[ 27.402608] Power allocator: IPA: trip->temperature=85000
[ 27.402622] Power allocator: IPA: passive trip->temperature=85000
[ 27.402635] Power allocator: IPA: trip_switch_on->temperature=70000
control_temp=85000
[ 27.402649] Power allocator: IPA: temperature_threshold=15000

--------------------------------------------------------
use case C:
6 trip points:
- 2 active for 50, 60 degC
- 1 active 70degC
- 3 passive 70, 85, 90 degC
- 1 critical 120 degC

expected IPA trip points: 50, 85 deg => 20 degC IPA operating range

[ 36.998907] Power allocator: IPA: trip->temperature=50000
[ 36.998921] Power allocator: IPA: active trip->temperature=50000
[ 36.998935] Power allocator: IPA: trip->temperature=60000
[ 36.998948] Power allocator: IPA: active trip->temperature=60000
[ 36.998960] Power allocator: IPA: trip->temperature=70000
[ 36.998973] Power allocator: IPA: active trip->temperature=70000
[ 36.998985] Power allocator: IPA: trip->temperature=120000
[ 36.998999] Power allocator: IPA: trip->temperature=70000
[ 36.999011] Power allocator: IPA: passive trip->temperature=70000
[ 36.999024] Power allocator: IPA: fist passive trip->temperature=70000
[ 36.999037] Power allocator: IPA: trip->temperature=85000
[ 36.999049] Power allocator: IPA: passive trip->temperature=85000
[ 36.999062] Power allocator: IPA: trip->temperature=90000
[ 36.999074] Power allocator: IPA: passive trip->temperature=90000
[ 36.999087] Power allocator: IPA: trip_switch_on->temperature=70000
control_temp=90000
[ 36.999101] Power allocator: IPA: temperature_threshold=20000

2023-10-20 16:42:06

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH v1 4/6] thermal: gov_power_allocator: Use trip pointers instead of trip indices

On Fri, Oct 20, 2023 at 6:36 PM Lukasz Luba <[email protected]> wrote:
>
>
>
> On 10/6/23 18:47, Rafael J. Wysocki wrote:
> > From: Rafael J. Wysocki <[email protected]>
> >
> > Modify the power allocator thermal governor to use trip pointers instead
> > of trip indices everywhere except for the power_allocator_throttle()
> > second argument that will be changed subsequently along with the
> > definition of the .throttle() governor callback.
> >
> > The general functionality is not expected to be changed.
> >
> > Signed-off-by: Rafael J. Wysocki <[email protected]>
> > ---
> > drivers/thermal/gov_power_allocator.c | 123 +++++++++++++---------------------
> > 1 file changed, 49 insertions(+), 74 deletions(-)
> >
>
> [snip]
>
> > @@ -636,7 +619,6 @@ static int power_allocator_bind(struct t
> > {
> > int ret;
> > struct power_allocator_params *params;
> > - struct thermal_trip trip;
> >
> > ret = check_power_actors(tz);
> > if (ret)
> > @@ -662,12 +644,13 @@ static int power_allocator_bind(struct t
> > get_governor_trips(tz, params);
> >
> > if (tz->num_trips > 0) {
> > - ret = __thermal_zone_get_trip(tz, params->trip_max_desired_temperature,
> > - &trip);
> > - if (!ret)
> > + const struct thermal_trip *trip;
> > +
> > + trip = params->trip_max_desired_temperature;
> > + if (trip)
> > estimate_pid_constants(tz, tz->tzp->sustainable_power,
> > params->trip_switch_on,
> > - trip.temperature);
> > + trip->temperature);
> > }
>
> The code check for the populated pointer (by earlier new
> get_governor_trips(tz, params)) :
>
> if (params->trip_max_desired_temperature) {
> int temp = params->trip_max_desired_temperature->temperature;
>
> estimate_pid_constants(...)
> }
>
> looks better (what you have figured out already).
>
> Other than that the patch LGTM:
>
> Reviewed-by: Lukasz Luba <[email protected]>
> Tested-by: Lukasz Luba <[email protected]>

Thanks!

> I have also tested this is a few ways and it still works as expected:
> 1. Power allocation in different conditions
> 2. Trip points properly recognized with this nice get_governor_trips(),
> here is the test output, with many tricky trip point setups:

Much appreciated!

> use case A:
> 5 trip points:
> - 2 passive for 50, 60 degC
> - 1 active 70degC
> - 2 passive 70, 85 degC
> - 1 critical 120 degC
>
> expected IPA trip points: 50, 85 deg => 35 degC IPA operating range
>
> [ 24.578806] Power allocator: IPA: trip->temperature=50000
> [ 24.578824] Power allocator: IPA: passive trip->temperature=50000
> [ 24.578838] Power allocator: IPA: fist passive trip->temperature=50000
> [ 24.578851] Power allocator: IPA: trip->temperature=60000
> [ 24.578863] Power allocator: IPA: passive trip->temperature=60000
> [ 24.578875] Power allocator: IPA: trip->temperature=70000
> [ 24.578888] Power allocator: IPA: active trip->temperature=70000
> [ 24.578900] Power allocator: IPA: trip->temperature=120000
> [ 24.578912] Power allocator: IPA: trip->temperature=70000
> [ 24.578925] Power allocator: IPA: passive trip->temperature=70000
> [ 24.578937] Power allocator: IPA: trip->temperature=85000
> [ 24.578950] Power allocator: IPA: passive trip->temperature=85000
> [ 24.578964] Power allocator: IPA: trip_switch_on->temperature=50000
> control_temp=85000
> [ 24.578978] Power allocator: IPA: temperature_threshold=35000
>
> -------------------------------------------------------------
> use case B:
> 5 trip points:
> - 2 active for 50, 60 degC
> - 1 active 70degC
> - 2 passive 70, 85 degC
> - 1 critical 120 degC
>
> expected IPA trip points: 70, 85 deg => 15 degC IPA operating range
>
> [ 27.402474] Power allocator: IPA: trip->temperature=50000
> [ 27.402492] Power allocator: IPA: active trip->temperature=50000
> [ 27.402505] Power allocator: IPA: trip->temperature=60000
> [ 27.402518] Power allocator: IPA: active trip->temperature=60000
> [ 27.402531] Power allocator: IPA: trip->temperature=70000
> [ 27.402544] Power allocator: IPA: active trip->temperature=70000
> [ 27.402557] Power allocator: IPA: trip->temperature=120000
> [ 27.402570] Power allocator: IPA: trip->temperature=70000
> [ 27.402582] Power allocator: IPA: passive trip->temperature=70000
> [ 27.402596] Power allocator: IPA: fist passive trip->temperature=70000
> [ 27.402608] Power allocator: IPA: trip->temperature=85000
> [ 27.402622] Power allocator: IPA: passive trip->temperature=85000
> [ 27.402635] Power allocator: IPA: trip_switch_on->temperature=70000
> control_temp=85000
> [ 27.402649] Power allocator: IPA: temperature_threshold=15000
>
> --------------------------------------------------------
> use case C:
> 6 trip points:
> - 2 active for 50, 60 degC
> - 1 active 70degC
> - 3 passive 70, 85, 90 degC
> - 1 critical 120 degC
>
> expected IPA trip points: 50, 85 deg => 20 degC IPA operating range
>
> [ 36.998907] Power allocator: IPA: trip->temperature=50000
> [ 36.998921] Power allocator: IPA: active trip->temperature=50000
> [ 36.998935] Power allocator: IPA: trip->temperature=60000
> [ 36.998948] Power allocator: IPA: active trip->temperature=60000
> [ 36.998960] Power allocator: IPA: trip->temperature=70000
> [ 36.998973] Power allocator: IPA: active trip->temperature=70000
> [ 36.998985] Power allocator: IPA: trip->temperature=120000
> [ 36.998999] Power allocator: IPA: trip->temperature=70000
> [ 36.999011] Power allocator: IPA: passive trip->temperature=70000
> [ 36.999024] Power allocator: IPA: fist passive trip->temperature=70000
> [ 36.999037] Power allocator: IPA: trip->temperature=85000
> [ 36.999049] Power allocator: IPA: passive trip->temperature=85000
> [ 36.999062] Power allocator: IPA: trip->temperature=90000
> [ 36.999074] Power allocator: IPA: passive trip->temperature=90000
> [ 36.999087] Power allocator: IPA: trip_switch_on->temperature=70000
> control_temp=90000
> [ 36.999101] Power allocator: IPA: temperature_threshold=20000
>