Message ID | 20230519032719.2581689-5-evalenti@kernel.org |
---|---|
State | New |
Headers | show |
Series | thermal: enhancements on thermal stats | expand |
On Fri, May 19, 2023 at 5:27 AM Eduardo Valentin <evalenti@kernel.org> wrote: > > From: Eduardo Valentin <eduval@amazon.com> > > The patch adds a statistic to track > the minimum gradient (dT/dt) to the thermal zone > stats/ folder. > > Samples: > > $ echo 1000 > emul_temp > $ cat stats/min_gradient > 0 > $ echo 2000 > emul_temp > $ echo 1000 > emul_temp > $ cat stats/min_gradient > -3460 > > Cc: "Rafael J. Wysocki" <rafael@kernel.org> (supporter:THERMAL) > Cc: Daniel Lezcano <daniel.lezcano@linaro.org> (supporter:THERMAL) > Cc: Amit Kucheria <amitk@kernel.org> (reviewer:THERMAL) > Cc: Zhang Rui <rui.zhang@intel.com> (reviewer:THERMAL) > Cc: Jonathan Corbet <corbet@lwn.net> (maintainer:DOCUMENTATION) > Cc: linux-pm@vger.kernel.org (open list:THERMAL) > Cc: linux-doc@vger.kernel.org (open list:DOCUMENTATION) > Cc: linux-kernel@vger.kernel.org (open list) > > Signed-off-by: Eduardo Valentin <eduval@amazon.com> This can be easily folded into the previous patch IMO. > --- > .../driver-api/thermal/sysfs-api.rst | 1 + > drivers/thermal/thermal_sysfs.c | 23 +++++++++++++++++++ > 2 files changed, 24 insertions(+) > > diff --git a/Documentation/driver-api/thermal/sysfs-api.rst b/Documentation/driver-api/thermal/sysfs-api.rst > index 18140dbb1ce1..ed5e6ba4e0d7 100644 > --- a/Documentation/driver-api/thermal/sysfs-api.rst > +++ b/Documentation/driver-api/thermal/sysfs-api.rst > @@ -358,6 +358,7 @@ Thermal zone device sys I/F, created once it's registered:: > |---stats: Directory containing thermal zone device's stats > |---stats/reset_tz_stats: Writes to this file resets the statistics. > |---stats/max_gradient: The maximum recorded dT/dt in uC/ms. > + |---stats/min_gradient: The minimum recorded dT/dt in uC/ms. > > Thermal cooling device sys I/F, created once it's registered:: > > diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c > index aa28c1cae916..f89ec9a7e8c8 100644 > --- a/drivers/thermal/thermal_sysfs.c > +++ b/drivers/thermal/thermal_sysfs.c > @@ -542,6 +542,7 @@ static void destroy_trip_attrs(struct thermal_zone_device *tz) > struct thermal_zone_device_stats { > spinlock_t lock; /* protects this struct */ > s64 max_gradient; > + s64 min_gradient; > ktime_t last_time; > }; > > @@ -569,6 +570,10 @@ static void temperature_stats_update(struct thermal_zone_device *tz) > /* update fastest temperature rise from our perspective */ > if (cur_gradient > stats->max_gradient) > stats->max_gradient = cur_gradient; > + > + /* update fastest temperature decay from our perspective */ > + if (cur_gradient < stats->min_gradient) > + stats->min_gradient = cur_gradient; > } > > void thermal_zone_device_stats_update(struct thermal_zone_device *tz) > @@ -595,6 +600,21 @@ static ssize_t max_gradient_show(struct device *dev, > return ret; > } > > +static ssize_t min_gradient_show(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct thermal_zone_device *tz = to_thermal_zone(dev); > + struct thermal_zone_device_stats *stats = tz->stats; > + int ret; > + > + spin_lock(&stats->lock); > + temperature_stats_update(tz); > + ret = snprintf(buf, PAGE_SIZE, "%lld\n", stats->min_gradient); > + spin_unlock(&stats->lock); > + > + return ret; > +} > + > static ssize_t > reset_tz_stats_store(struct device *dev, struct device_attribute *attr, > const char *buf, size_t count) > @@ -604,6 +624,7 @@ reset_tz_stats_store(struct device *dev, struct device_attribute *attr, > > spin_lock(&stats->lock); > > + stats->min_gradient = 0; > stats->max_gradient = 0; > stats->last_time = ktime_get(); > > @@ -612,10 +633,12 @@ reset_tz_stats_store(struct device *dev, struct device_attribute *attr, > return count; > } > > +static DEVICE_ATTR_RO(min_gradient); > static DEVICE_ATTR_RO(max_gradient); > static DEVICE_ATTR_WO(reset_tz_stats); > > static struct attribute *thermal_zone_device_stats_attrs[] = { > + &dev_attr_min_gradient.attr, > &dev_attr_max_gradient.attr, > &dev_attr_reset_tz_stats.attr, > NULL > -- > 2.34.1 >
diff --git a/Documentation/driver-api/thermal/sysfs-api.rst b/Documentation/driver-api/thermal/sysfs-api.rst index 18140dbb1ce1..ed5e6ba4e0d7 100644 --- a/Documentation/driver-api/thermal/sysfs-api.rst +++ b/Documentation/driver-api/thermal/sysfs-api.rst @@ -358,6 +358,7 @@ Thermal zone device sys I/F, created once it's registered:: |---stats: Directory containing thermal zone device's stats |---stats/reset_tz_stats: Writes to this file resets the statistics. |---stats/max_gradient: The maximum recorded dT/dt in uC/ms. + |---stats/min_gradient: The minimum recorded dT/dt in uC/ms. Thermal cooling device sys I/F, created once it's registered:: diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index aa28c1cae916..f89ec9a7e8c8 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -542,6 +542,7 @@ static void destroy_trip_attrs(struct thermal_zone_device *tz) struct thermal_zone_device_stats { spinlock_t lock; /* protects this struct */ s64 max_gradient; + s64 min_gradient; ktime_t last_time; }; @@ -569,6 +570,10 @@ static void temperature_stats_update(struct thermal_zone_device *tz) /* update fastest temperature rise from our perspective */ if (cur_gradient > stats->max_gradient) stats->max_gradient = cur_gradient; + + /* update fastest temperature decay from our perspective */ + if (cur_gradient < stats->min_gradient) + stats->min_gradient = cur_gradient; } void thermal_zone_device_stats_update(struct thermal_zone_device *tz) @@ -595,6 +600,21 @@ static ssize_t max_gradient_show(struct device *dev, return ret; } +static ssize_t min_gradient_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct thermal_zone_device *tz = to_thermal_zone(dev); + struct thermal_zone_device_stats *stats = tz->stats; + int ret; + + spin_lock(&stats->lock); + temperature_stats_update(tz); + ret = snprintf(buf, PAGE_SIZE, "%lld\n", stats->min_gradient); + spin_unlock(&stats->lock); + + return ret; +} + static ssize_t reset_tz_stats_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -604,6 +624,7 @@ reset_tz_stats_store(struct device *dev, struct device_attribute *attr, spin_lock(&stats->lock); + stats->min_gradient = 0; stats->max_gradient = 0; stats->last_time = ktime_get(); @@ -612,10 +633,12 @@ reset_tz_stats_store(struct device *dev, struct device_attribute *attr, return count; } +static DEVICE_ATTR_RO(min_gradient); static DEVICE_ATTR_RO(max_gradient); static DEVICE_ATTR_WO(reset_tz_stats); static struct attribute *thermal_zone_device_stats_attrs[] = { + &dev_attr_min_gradient.attr, &dev_attr_max_gradient.attr, &dev_attr_reset_tz_stats.attr, NULL