Commit 7ef01f22 authored by Daniel Lezcano's avatar Daniel Lezcano Committed by Rafael J. Wysocki

thermal/debugfs: Add thermal debugfs information for mitigation episodes

The mitigation episodes are recorded. A mitigation episode happens
when the first trip point is crossed the way up and then the way
down. During this episode other trip points can be crossed also and
are accounted for this mitigation episode. The interesting information
is the average temperature at the trip point, the undershot and the
overshot. The standard deviation of the mitigated temperature will be
added later.

The thermal debugfs directory structure tries to stay consistent with
the sysfs one but in a very simplified way:

thermal/
 `-- thermal_zones
     |-- 0
     |   `-- mitigations
     `-- 1
         `-- mitigations

The content of the mitigations file has the following format:

,-Mitigation at 349988258us, duration=130136ms
| trip |     type | temp(°mC) | hyst(°mC) |  duration  |  avg(°mC) |  min(°mC) |  max(°mC) |
|    0 |  passive |     65000 |      2000 |     130136 |     68227 |     62500 |     75625 |
|    1 |  passive |     75000 |      2000 |     104209 |     74857 |     71666 |     77500 |
,-Mitigation at 272451637us, duration=75000ms
| trip |     type | temp(°mC) | hyst(°mC) |  duration  |  avg(°mC) |  min(°mC) |  max(°mC) |
|    0 |  passive |     65000 |      2000 |      75000 |     68561 |     62500 |     75000 |
|    1 |  passive |     75000 |      2000 |      60714 |     74820 |     70555 |     77500 |
,-Mitigation at 238184119us, duration=27316ms
| trip |     type | temp(°mC) | hyst(°mC) |  duration  |  avg(°mC) |  min(°mC) |  max(°mC) |
|    0 |  passive |     65000 |      2000 |      27316 |     73377 |     62500 |     75000 |
|    1 |  passive |     75000 |      2000 |      19468 |     75284 |     69444 |     77500 |
,-Mitigation at 39863713us, duration=136196ms
| trip |     type | temp(°mC) | hyst(°mC) |  duration  |  avg(°mC) |  min(°mC) |  max(°mC) |
|    0 |  passive |     65000 |      2000 |     136196 |     73922 |     62500 |     75000 |
|    1 |  passive |     75000 |      2000 |      91721 |     74386 |     69444 |     78125 |

More information for a better understanding of the thermal behavior
will be added after. The idea is to give detailed statistics
information about the undershots and overshots, the temperature speed,
etc... As all the information in a single file is too much, the idea
would be to create a directory named with the mitigation timestamp
where all data could be added.

Please note this code is immune against trip ordering but not against
a trip temperature change while a mitigation is happening. However,
this situation should be extremely rare, perhaps not happening and we
might question ourselves if something should be done in the core
framework for other components first.
Signed-off-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
[ rjw: White space fixups, rebase ]
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 755113d7
...@@ -382,6 +382,7 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, ...@@ -382,6 +382,7 @@ static void handle_thermal_trip(struct thermal_zone_device *tz,
*/ */
if (tz->temperature >= trip->temperature) { if (tz->temperature >= trip->temperature) {
thermal_notify_tz_trip_up(tz, trip); thermal_notify_tz_trip_up(tz, trip);
thermal_debug_tz_trip_up(tz, trip);
trip->threshold = trip->temperature - trip->hysteresis; trip->threshold = trip->temperature - trip->hysteresis;
} else { } else {
trip->threshold = trip->temperature; trip->threshold = trip->temperature;
...@@ -399,6 +400,7 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, ...@@ -399,6 +400,7 @@ static void handle_thermal_trip(struct thermal_zone_device *tz,
*/ */
if (tz->temperature < trip->temperature - trip->hysteresis) { if (tz->temperature < trip->temperature - trip->hysteresis) {
thermal_notify_tz_trip_down(tz, trip); thermal_notify_tz_trip_down(tz, trip);
thermal_debug_tz_trip_down(tz, trip);
trip->threshold = trip->temperature; trip->threshold = trip->temperature;
} else { } else {
trip->threshold = trip->temperature - trip->hysteresis; trip->threshold = trip->temperature - trip->hysteresis;
...@@ -430,6 +432,7 @@ static void update_temperature(struct thermal_zone_device *tz) ...@@ -430,6 +432,7 @@ static void update_temperature(struct thermal_zone_device *tz)
trace_thermal_temperature(tz); trace_thermal_temperature(tz);
thermal_genl_sampling_temp(tz->id, temp); thermal_genl_sampling_temp(tz->id, temp);
thermal_debug_update_temp(tz);
} }
static void thermal_zone_device_check(struct work_struct *work) static void thermal_zone_device_check(struct work_struct *work)
...@@ -1413,6 +1416,8 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t ...@@ -1413,6 +1416,8 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
thermal_notify_tz_create(tz); thermal_notify_tz_create(tz);
thermal_debug_tz_add(tz);
return tz; return tz;
unregister: unregister:
...@@ -1476,6 +1481,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) ...@@ -1476,6 +1481,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
if (!tz) if (!tz)
return; return;
thermal_debug_tz_remove(tz);
mutex_lock(&thermal_list_lock); mutex_lock(&thermal_list_lock);
list_for_each_entry(pos, &thermal_tz_list, node) list_for_each_entry(pos, &thermal_tz_list, node)
if (pos == tz) if (pos == tz)
......
This diff is collapsed.
...@@ -5,10 +5,24 @@ void thermal_debug_init(void); ...@@ -5,10 +5,24 @@ void thermal_debug_init(void);
void thermal_debug_cdev_add(struct thermal_cooling_device *cdev); void thermal_debug_cdev_add(struct thermal_cooling_device *cdev);
void thermal_debug_cdev_remove(struct thermal_cooling_device *cdev); void thermal_debug_cdev_remove(struct thermal_cooling_device *cdev);
void thermal_debug_cdev_state_update(const struct thermal_cooling_device *cdev, int state); void thermal_debug_cdev_state_update(const struct thermal_cooling_device *cdev, int state);
void thermal_debug_tz_add(struct thermal_zone_device *tz);
void thermal_debug_tz_remove(struct thermal_zone_device *tz);
void thermal_debug_tz_trip_up(struct thermal_zone_device *tz,
const struct thermal_trip *trip);
void thermal_debug_tz_trip_down(struct thermal_zone_device *tz,
const struct thermal_trip *trip);
void thermal_debug_update_temp(struct thermal_zone_device *tz);
#else #else
static inline void thermal_debug_init(void) {} static inline void thermal_debug_init(void) {}
static inline void thermal_debug_cdev_add(struct thermal_cooling_device *cdev) {} static inline void thermal_debug_cdev_add(struct thermal_cooling_device *cdev) {}
static inline void thermal_debug_cdev_remove(struct thermal_cooling_device *cdev) {} static inline void thermal_debug_cdev_remove(struct thermal_cooling_device *cdev) {}
static inline void thermal_debug_cdev_state_update(const struct thermal_cooling_device *cdev, static inline void thermal_debug_cdev_state_update(const struct thermal_cooling_device *cdev,
int state) {} int state) {}
static inline void thermal_debug_tz_add(struct thermal_zone_device *tz) {}
static inline void thermal_debug_tz_remove(struct thermal_zone_device *tz) {}
static inline void thermal_debug_tz_trip_up(struct thermal_zone_device *tz,
const struct thermal_trip *trip) {};
static inline void thermal_debug_tz_trip_down(struct thermal_zone_device *tz,
const struct thermal_trip *trip) {}
static inline void thermal_debug_update_temp(struct thermal_zone_device *tz) {}
#endif /* CONFIG_THERMAL_DEBUGFS */ #endif /* CONFIG_THERMAL_DEBUGFS */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment