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>;
};
};
};
};
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);
--
+++ 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
Warm Regards
Anuz
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies