Thermal governor related help

Anuz Pratap Singh Tomar chambilkethakur at gmail.com
Sun Nov 3 01:58:31 EST 2024


Hi all,
I am trying to modify bang_bang thermal governor
The source code I have taken from here
https://android.googlesource.com/kernel/common/+/15753588bcd4/drivers/thermal/gov_bang_bang.c

bang bang governor  will switch fan on when temperature reaches "trip"
temperature and turn the fan off when temperature falls below "trip -
hysteresis temperature". These Properties are set in the device file.

I am modifying it to operate in three modes, ON, 50% and 100% fan speed
depending on the temperature. At 100% fan is noisy, so 50% offers a good
compromise for a slightly hotter system but when the system is too hot a
100% fan should be acceptable.

Here are the device entries
"trips" are set for 70-65 and 65-70 degrees celsius. and cooling maps use
fan with state 0, 1 and 2 which are OFF, 50% and 100%

thermal-zones {
                cpu-thermal {

                        trips {

                                cpu_trip_low: active-low {

                                        temperature = <65000>;

                                        hysteresis = <5000>;

                                        type = "active";

                                };



                                cpu_trip_high: active-high {

                                        temperature = <70000>;

                                        hysteresis = <5000>;

                                        type = "active";

                                };


                        };



                        cooling-maps {

                                map1 {

                                        cooling-device = <&fan 0 1>;

                                        trip = <&cpu_trip_low>;

                                };



                                map2 {

                                        cooling-device = <&fan 1 2>;

                                        trip = <&cpu_trip_high>;

                                };



                        };

                };

        };



The modified algorithm is

--- drivers/thermal/gov_bang_bang.c 2024-11-02 05:54:17.385093959 +0000
+++ drivers/thermal/gov_bang_bang.c.orig 2024-11-02 06:09:31.108870820 +0000
@@ -13,6 +13,10 @@

 #include "thermal_core.h"

+#define FAN_OFF 0
+#define FAN_ON_50 1
+#define FAN_ON_100 2
+
 static void thermal_zone_trip_update(struct thermal_zone_device *tz, int
trip)
 {
  int trip_temp, trip_hyst;
@@ -32,29 +36,59 @@
  trip_hyst);

  list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
+
+ unsigned long upper;
+ unsigned long lower;
+
  if (instance->trip != trip)
  continue;

+ upper = instance->upper;
+ lower = instance->lower;
+
+ dev_dbg(&instance->cdev->device,"instance state = %ld trip = %d lower =
%ld upper= %ld\n",
+ instance->target, trip,lower, upper);
+
  /* in case fan is in initial state, switch the fan off */
  if (instance->target == THERMAL_NO_TARGET)
- instance->target = 0;
+ instance->target = FAN_OFF;

- /* in case fan is neither on nor off set the fan to active */
- if (instance->target != 0 && instance->target != 1) {
- pr_warn("Thermal instance %s controlled by bang-bang has unexpected
state: %ld\n",
- instance->name, instance->target);
- instance->target = 1;
+ /*
+ * In case fan is not off or running at 50/100% settings, set the fan to
+ * upper or 50%.
+ */
+ if (instance->target != FAN_OFF &&
+    instance->target !=  FAN_ON_50 &&
+    instance->target !=  FAN_ON_100) {
+ pr_warn("Thermal instance %s controlled by bang-bang has"
+ " unexpected state: %ld\n lower=%ld upper=%ld",
+ instance->name, instance->target,
+ lower, upper);
+
+ if(upper > FAN_ON_100 || lower > FAN_ON_100)
+ instance->target = FAN_ON_50;
+ else
+ instance->target = upper;
  }

  /*
- * enable fan when temperature exceeds trip_temp and disable
- * the fan in case it falls below trip_temp minus hysteresis
+ * set fan to upper when temperature exceeds trip_temp and set
+ * fan to lower in case it falls below trip_temp minus hysteresis
  */
- if (instance->target == 0 && tz->temperature >= trip_temp)
- instance->target = 1;
- else if (instance->target == 1 &&
- tz->temperature <= trip_temp - trip_hyst)
- instance->target = 0;
+ if (instance->target < upper && tz->temperature >= trip_temp) {
+ dev_dbg(&instance->cdev->device, "increase cooling: target"
+ " = %ld, upper = %ld, temp = %ld\n, trip_temp = %ld\n",
+ instance->target, upper tz->temperature trip_temp);
+ instance->target = upper;
+
+ } else if (instance->target > lower &&
+ tz->temperature <= trip_temp - trip_hyst) {
+ dev_dbg(&instance->cdev->device, "increase cooling: target"
+ " = %ld, lower = %ld, temp = %ld\n, trip_temp - hyst = %ld\n",
+ instance->target, lower, tz->temperature,
+ trip_temp - trip_hyst);
+ instance->target = lower;
+ }

  dev_dbg(&instance->cdev->device, "target=%d\n",
  (int)instance->target);

What I have observed
When temperature goes up from 60-65, the fan is switched on at 50%, and
when temperature goes on from 65-70, fan is switched on at 100%.
When the temperature goes down  from 70-65, the fan goes from 100% to 50%,
but it doesn't switch off when  the temperature goes from 65-60. Fan stays
running at 50% when temperature has fallen below the "trip - hysteresis"
point.

I put some debugs around the code to see what is happening.
I observed that "instance->target" is showing two values 0 and 1, which are
OFF and 50%, when I expect it to be OFF. My guess is these values are for
different trips, since "trip2" has a "lower" set to 1.
I am not quite sure how to make sure that value goes back 0 here. Any
insight  on what I have done wrong and what can I do to make it work?


-- 
Thank you
Warm Regards
Anuz
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20241103/1d3b289c/attachment.html>


More information about the Kernelnewbies mailing list