From 9b73b5052ae841037682da93a17f80f8ed57788d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 28 May 2024 16:53:47 +0200 Subject: [PATCH] thermal/debugfs: Do not extend mitigation episodes beyond system resume Because thermal zone handling by the thermal core is started from scratch during resume from system-wide suspend, prevent the debug code from extending mitigation episodes beyond that point by ending the mitigation episode currently in progress, if any, for each thermal zone. Signed-off-by: Rafael J. Wysocki Acked-by: Daniel Lezcano --- drivers/thermal/thermal_core.c | 1 + drivers/thermal/thermal_debugfs.c | 36 +++++++++++++++++++++++++++++++ drivers/thermal/thermal_debugfs.h | 2 ++ 3 files changed, 39 insertions(+) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index d70e76dd3c94..bd31193bb583 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -1648,6 +1648,7 @@ static void thermal_zone_device_resume(struct work_struct *work) tz->suspended = false; + thermal_debug_tz_resume(tz); thermal_zone_device_init(tz); __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); diff --git a/drivers/thermal/thermal_debugfs.c b/drivers/thermal/thermal_debugfs.c index 66c0105465dd..c592eca11a50 100644 --- a/drivers/thermal/thermal_debugfs.c +++ b/drivers/thermal/thermal_debugfs.c @@ -926,3 +926,39 @@ void thermal_debug_tz_remove(struct thermal_zone_device *tz) thermal_debugfs_remove_id(thermal_dbg); kfree(trips_crossed); } + +void thermal_debug_tz_resume(struct thermal_zone_device *tz) +{ + struct thermal_debugfs *thermal_dbg = tz->debugfs; + ktime_t now = ktime_get(); + struct tz_debugfs *tz_dbg; + struct tz_episode *tze; + int i; + + if (!thermal_dbg) + return; + + mutex_lock(&thermal_dbg->lock); + + tz_dbg = &thermal_dbg->tz_dbg; + + if (!tz_dbg->nr_trips) + goto out; + + /* + * A mitigation episode was in progress before the preceding system + * suspend transition, so close it because the zone handling is starting + * over from scratch. + */ + tze = list_first_entry(&tz_dbg->tz_episodes, struct tz_episode, node); + + for (i = 0; i < tz_dbg->nr_trips; i++) + tz_episode_close_trip(tze, tz_dbg->trips_crossed[i], now); + + tze->duration = ktime_sub(now, tze->timestamp); + + tz_dbg->nr_trips = 0; + +out: + mutex_unlock(&thermal_dbg->lock); +} diff --git a/drivers/thermal/thermal_debugfs.h b/drivers/thermal/thermal_debugfs.h index 74ee65ee82ff..1c957ce2ec8f 100644 --- a/drivers/thermal/thermal_debugfs.h +++ b/drivers/thermal/thermal_debugfs.h @@ -7,6 +7,7 @@ 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_tz_add(struct thermal_zone_device *tz); void thermal_debug_tz_remove(struct thermal_zone_device *tz); +void thermal_debug_tz_resume(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, @@ -20,6 +21,7 @@ static inline void thermal_debug_cdev_state_update(const struct thermal_cooling_ 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_resume(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,