linux-doc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Eduardo Valentin <evalenti@kernel.org>
To: eduval@amazon.com, linux-pm@vger.kernel.org
Cc: "Rafael J. Wysocki" <rafael@kernel.org>,
	Daniel Lezcano <daniel.lezcano@linaro.org>,
	Amit Kucheria <amitk@kernel.org>, Zhang Rui <rui.zhang@intel.com>,
	Jonathan Corbet <corbet@lwn.net>,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 5/7] thermal: stats: introduce tz time in trip
Date: Thu, 18 May 2023 20:27:17 -0700	[thread overview]
Message-ID: <20230519032719.2581689-6-evalenti@kernel.org> (raw)
In-Reply-To: <20230519032719.2581689-1-evalenti@kernel.org>

From: Eduardo Valentin <eduval@amazon.com>

This patch adds a statistic to report how long
the thermal zone spent on temperature intervals
created by each trip point. The first interval
is the range below the first trip point. All
subsequent intervals are accounted when temperature
is above the trip point temperature value.

Samples:
$ cat /sys//class/thermal/thermal_zone0/stats/time_in_trip_ms
trip-1	0	0
trip0	-10000	35188
trip1	25000	0
$ cat /sys//class/thermal/thermal_zone0/stats/time_in_trip_ms
trip-1	0	0
trip0	-10000	36901
trip1	25000	0
$ echo 25001 > /sys//class/thermal/thermal_zone0/emul_temp
$ cat /sys//class/thermal/thermal_zone0/stats/time_in_trip_ms
trip-1	0	0
trip0	-10000	47810
trip1	25000	2259
$ cat /sys//class/thermal/thermal_zone0/stats/time_in_trip_ms
trip-1	0	0
trip0	-10000	47810
trip1	25000	3224
$ echo 24001 > /sys//class/thermal/thermal_zone0/emul_temp
$ cat /sys//class/thermal/thermal_zone0/stats/time_in_trip_ms
trip-1	0	0
trip0	-10000	48960
trip1	25000	10080
$ cat /sys//class/thermal/thermal_zone0/stats/time_in_trip_ms
trip-1	0	0
trip0	-10000	49844
trip1	25000	10080

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>
---
 .../driver-api/thermal/sysfs-api.rst          |  2 +
 drivers/thermal/thermal_sysfs.c               | 86 +++++++++++++++++++
 2 files changed, 88 insertions(+)

diff --git a/Documentation/driver-api/thermal/sysfs-api.rst b/Documentation/driver-api/thermal/sysfs-api.rst
index ed5e6ba4e0d7..4a2b92a7488c 100644
--- a/Documentation/driver-api/thermal/sysfs-api.rst
+++ b/Documentation/driver-api/thermal/sysfs-api.rst
@@ -359,6 +359,8 @@ Thermal zone device sys I/F, created once it's registered::
     |---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.
+    |---stats/time_in_trip_ms:	Time spent on each temperature interval of
+				trip points.
 
 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 f89ec9a7e8c8..25851fe073c3 100644
--- a/drivers/thermal/thermal_sysfs.c
+++ b/drivers/thermal/thermal_sysfs.c
@@ -544,6 +544,7 @@ struct thermal_zone_device_stats {
 	s64 max_gradient;
 	s64 min_gradient;
 	ktime_t last_time;
+	ktime_t *time_in_trip;
 };
 
 #define DELTA_MILLI_C_TO_MICRO_C(t0, t1)		(((t0) - (t1)) * 1000)
@@ -552,6 +553,7 @@ static void temperature_stats_update(struct thermal_zone_device *tz)
 	struct thermal_zone_device_stats *stats = tz->stats;
 	ktime_t now = ktime_get(), delta;
 	s64 cur_gradient, delta_temp;
+	int i, trip_id = -1;
 
 	delta = ktime_sub(now, stats->last_time);
 	stats->last_time = now;
@@ -567,6 +569,29 @@ static void temperature_stats_update(struct thermal_zone_device *tz)
 	if (tz->last_temperature == 0)
 		cur_gradient = 0;
 
+	for (i = 0; i < tz->num_trips; i++) {
+		struct thermal_trip trip;
+		int ret;
+
+		ret = __thermal_zone_get_trip(tz, i, &trip);
+		if (ret)
+			continue;
+
+		if (tz->temperature > trip.temperature)
+			trip_id = i;
+	}
+
+	/*
+	 * Update how long we spend in each temperature interval.
+	 * This array is like as follows:
+	 * time_in_trip[0] == time spent with temperature <= trip[0]
+	 * time_in_trip[1] == time spent with temperature > trip[0]
+	 * time_in_trip[2] == time spent with temperature > trip[1]
+	 * ...
+	 */
+	stats->time_in_trip[trip_id + 1] =
+		ktime_add(stats->time_in_trip[trip_id + 1], delta);
+
 	/* update fastest temperature rise from our perspective */
 	if (cur_gradient > stats->max_gradient)
 		stats->max_gradient = cur_gradient;
@@ -615,12 +640,66 @@ static ssize_t min_gradient_show(struct device *dev,
 	return ret;
 }
 
+static ssize_t
+time_in_trip_ms_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;
+	ssize_t len = 0, ret = 0;
+	int i;
+
+	spin_lock(&stats->lock);
+	temperature_stats_update(tz);
+
+	/*
+	 * This should look like this:
+	 * trip-1	X
+	 * trip0	Y
+	 * trip1	Z
+	 * ...
+	 * and the way to read is. This thermal zone temperature was seen
+	 * X ms with tz->temperature <= trip0, Y ms with tz->temperature > trip0
+	 * and Z ms with tz->temperature > trip1.
+	 */
+	for (i = 0; i <= tz->num_trips; i++) {
+		int trip_temp = 0, r = 0;
+
+		if (i > 0) {
+			struct thermal_trip trip;
+
+			r = __thermal_zone_get_trip(tz, i - 1, &trip);
+			if (r < 0) {
+				ret = r;
+				break;
+			}
+			trip_temp = trip.temperature;
+		}
+
+		ret = snprintf(buf + len, PAGE_SIZE - len, "trip%d\t%d\t%llu\n",
+			       i - 1, trip_temp,
+			       ktime_to_ms(stats->time_in_trip[i]));
+
+		if (ret == 0)
+			ret = -EOVERFLOW;
+
+		if (ret < 0)
+			break;
+
+		len += ret;
+	}
+	spin_unlock(&stats->lock);
+
+	return ret < 0 ? ret : len;
+}
+
 static ssize_t
 reset_tz_stats_store(struct device *dev, struct device_attribute *attr,
 		     const char *buf, size_t count)
 {
 	struct thermal_zone_device *tz = to_thermal_zone(dev);
 	struct thermal_zone_device_stats *stats = tz->stats;
+	int i;
 
 	spin_lock(&stats->lock);
 
@@ -628,6 +707,9 @@ reset_tz_stats_store(struct device *dev, struct device_attribute *attr,
 	stats->max_gradient = 0;
 	stats->last_time = ktime_get();
 
+	for (i = 0; i <= tz->num_trips; i++)
+		stats->time_in_trip[i] = ktime_set(0, 0);
+
 	spin_unlock(&stats->lock);
 
 	return count;
@@ -635,11 +717,13 @@ reset_tz_stats_store(struct device *dev, struct device_attribute *attr,
 
 static DEVICE_ATTR_RO(min_gradient);
 static DEVICE_ATTR_RO(max_gradient);
+static DEVICE_ATTR_RO(time_in_trip_ms);
 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_time_in_trip_ms.attr,
 	&dev_attr_reset_tz_stats.attr,
 	NULL
 };
@@ -657,11 +741,13 @@ thermal_zone_device_stats_setup(struct thermal_zone_device *tz,
 	int var;
 
 	var = sizeof(*stats);
+	var += sizeof(*stats->time_in_trip) * (tz->num_trips + 1);
 
 	stats = kzalloc(var, GFP_KERNEL);
 	if (!stats)
 		return;
 
+	stats->time_in_trip = (ktime_t *)(stats + 1);
 	stats->last_time = ktime_get();
 	spin_lock_init(&stats->lock);
 	tz->stats = stats;
-- 
2.34.1


  parent reply	other threads:[~2023-05-19  3:27 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-19  3:27 [PATCH 0/7] thermal: enhancements on thermal stats Eduardo Valentin
2023-05-19  3:27 ` [PATCH 1/7] thermal: stats: track time each dev changes due to tz Eduardo Valentin
2023-06-20 13:43   ` Rafael J. Wysocki
2023-06-21  4:37     ` Eduardo Valentin
2023-05-19  3:27 ` [PATCH 2/7] thermal: stats: track number of change requests " Eduardo Valentin
2023-06-20 17:12   ` Rafael J. Wysocki
2023-06-21  4:40     ` Eduardo Valentin
2023-05-19  3:27 ` [PATCH 3/7] thermal: stats: introduce thermal zone stats/ directory Eduardo Valentin
2023-05-19  3:27 ` [PATCH 4/7] thermal: stats: introduce thermal zone stats/min_gradient Eduardo Valentin
2023-06-20 17:17   ` Rafael J. Wysocki
2023-05-19  3:27 ` Eduardo Valentin [this message]
2023-06-20 17:27   ` [PATCH 5/7] thermal: stats: introduce tz time in trip Rafael J. Wysocki
2023-06-21  4:45     ` Eduardo Valentin
2023-06-23 16:40       ` Rafael J. Wysocki
2023-06-28 20:00         ` Eduardo Valentin
2023-05-19  3:27 ` [PATCH 6/7] ythermal: core: report errors to governors Eduardo Valentin
2023-06-20 17:29   ` Rafael J. Wysocki
2023-06-21  4:49     ` Eduardo Valentin
2023-05-19  3:27 ` [PATCH 7/7] thermal: stats: add error accounting to thermal zone Eduardo Valentin
2023-06-20 17:32   ` Rafael J. Wysocki
2023-06-21  4:50     ` Eduardo Valentin
2023-05-24 18:22 ` [PATCH 0/7] thermal: enhancements on thermal stats Rafael J. Wysocki
2023-06-05 23:28   ` Eduardo Valentin
2023-06-20 19:05 ` Daniel Lezcano
2023-06-21  4:24   ` Eduardo Valentin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230519032719.2581689-6-evalenti@kernel.org \
    --to=evalenti@kernel.org \
    --cc=amitk@kernel.org \
    --cc=corbet@lwn.net \
    --cc=daniel.lezcano@linaro.org \
    --cc=eduval@amazon.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=rafael@kernel.org \
    --cc=rui.zhang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).