sched/power: implement simple PI with integral decaying
authorLukasz Luba <l.luba@partner.samsung.com>
Thu, 8 Nov 2018 18:02:26 +0000 (19:02 +0100)
committerLukasz Luba <l.luba@partner.samsung.com>
Fri, 17 May 2019 07:15:48 +0000 (09:15 +0200)
The patch adds simple implementation of control algorithm
based on PI with additional decaying for integral.

Signed-off-by: Lukasz Luba <l.luba@partner.samsung.com>
kernel/sched/power.c
kernel/sched/power.h

index f74c59e83d4f0a73f8497b5db4ab5ee370b18b0f..20f5618d8f2b949ab411c23f7240763b028e645b 100644 (file)
@@ -475,6 +475,9 @@ struct trip_ctrl_alg {
        int switch_on_temp;
        int desired_id;
        int desired_temp;
+       int k_p;
+       int k_i;
+       s64 integral;
 };
 
 struct _thermal_zone {
@@ -532,16 +535,33 @@ static u32 calc_power_budget(struct _thermal_zone *zone)
 {
        s64 temp_diff;
        int desired_temp = zone->trip_ctrl_alg.desired_temp;
-       s64 power_budget;
+       s64 power_budget, p, i;
+       s64 decay;
+       int k_i = zone->trip_ctrl_alg.k_i;
        struct thermal_zone_device *tz = zone->tz;
 
        /* temperature is represented in milidegress */
        temp_diff = desired_temp - tz->temperature;
 
-       power_budget = temp_diff;
+       p = temp_diff * zone->trip_ctrl_alg.k_p;
+
+       i = zone->trip_ctrl_alg.integral * k_i;
+
+       if (temp_diff < 0) {
+               s64 i_0 = i + k_i * temp_diff;
+
+               zone->trip_ctrl_alg.integral += temp_diff;
+       }
+
+       power_budget = p + i;
+       power_budget >>= 10;
 
        power_budget = max(0LL, power_budget);
 
+       /* decay of 1/8 (~12.5%), after a while will reach 0 */
+       decay = zone->trip_ctrl_alg.integral >> 3;
+       zone->trip_ctrl_alg.integral -= decay;
+
        return power_budget;
 }
 
@@ -764,6 +784,8 @@ static int sched_power_setup_trips(struct _thermal_zone *zone)
 
        zone->trip_ctrl_alg.switch_on_id = -EINVAL;
        zone->trip_ctrl_alg.desired_id = -EINVAL;
+       zone->trip_ctrl_alg.k_p = DEFAULT_K_P;
+       zone->trip_ctrl_alg.k_i = DEFAULT_K_I;
 
        for (i = 0; i < tz->trips; i++) {
                ret = tz->ops->get_trip_ctrl_alg_flag(tz, i,
index 77516a6f5809c64545565da70c2181e0c77a11dc..340b3924ecd717c13efff4123ce552a28899fb55 100644 (file)
@@ -19,6 +19,8 @@
 
 #define MAX_WEIGHT 1024
 #define DEFAULT_WEIGHT MAX_WEIGHT
+#define DEFAULT_K_P 500
+#define DEFAULT_K_I 50
 
 struct power_budget {
        s64 temp;