thermal: Add ratelimited print for HOT trip point

Message ID 20200402135242.11117-1-vincent.whitchurch@axis.com
State New
Headers show
Series
  • thermal: Add ratelimited print for HOT trip point
Related show

Commit Message

Vincent Whitchurch April 2, 2020, 1:52 p.m.
Currently, HOT trips don't do much in the core except for emitting an
ftrace event.  Unlike for ACTIVE/PASSIVE, cooling/throttling is not
activated.

The ACPI driver sends a netlink notification to userspace, but the other
drivers either don't implement ->notify() (all but rcar_thermal), or
don't do anything for HOT in their ->notify() implementation
(rcar_thermal).  (tegra appears to use the HOT trip device tree data for
other purposes.)

To make this trip point a bit more useful, add a warning print in the
core when this temperature is reached, so that this information is
available in the kernel log for diagnostic purposes.  The warning is
ratelimited by default to once an hour and can be adjusted with module
parameters.

Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com>
---
 drivers/thermal/thermal_core.c | 12 ++++++++++++
 include/linux/thermal.h        |  1 +
 2 files changed, 13 insertions(+)

Patch

diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 9a321dc548c8..06f1dfae0310 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -47,6 +47,12 @@  static bool power_off_triggered;
 
 static struct thermal_governor *def_governor;
 
+static unsigned int thermal_ratelimit_interval = 60 * 60 * HZ;
+static unsigned int thermal_ratelimit_burst = 1;
+
+module_param_named(ratelimit_interval, thermal_ratelimit_interval, uint, 0);
+module_param_named(ratelimit_burst, thermal_ratelimit_burst, uint, 0);
+
 /*
  * Governor section: set of functions to handle thermal governors
  *
@@ -404,6 +410,9 @@  static void handle_critical_trips(struct thermal_zone_device *tz,
 			power_off_triggered = true;
 		}
 		mutex_unlock(&poweroff_lock);
+	} else if (__ratelimit(&tz->ratelimit)) {
+		dev_warn(&tz->device, "hot temperature reached (%d C)\n",
+			  tz->temperature / 1000);
 	}
 }
 
@@ -1290,6 +1299,9 @@  thermal_zone_device_register(const char *type, int trips, int mask,
 	tz->passive_delay = passive_delay;
 	tz->polling_delay = polling_delay;
 
+	ratelimit_state_init(&tz->ratelimit, thermal_ratelimit_interval,
+			     thermal_ratelimit_burst);
+
 	/* sys I/F */
 	/* Add nodes that are always present via .groups */
 	result = thermal_zone_create_device_groups(tz, mask);
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 126913c6a53b..d3d0d6c7c4a1 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -196,6 +196,7 @@  struct thermal_zone_device {
 	int passive;
 	int prev_low_trip;
 	int prev_high_trip;
+	struct ratelimit_state ratelimit;
 	unsigned int forced_passive;
 	atomic_t need_update;
 	struct thermal_zone_device_ops *ops;