* [PATCH 1/3] Thermal: initialize thermal zone device correctly
@ 2015-09-27 5:48 Chen Yu
2015-09-28 14:28 ` Javi Merino
0 siblings, 1 reply; 8+ messages in thread
From: Chen Yu @ 2015-09-27 5:48 UTC (permalink / raw)
To: linux-pm, edubezval, javi.merino; +Cc: rui.zhang, linux-kernel, stable
From: Zhang Rui <rui.zhang@intel.com>
After thermal zone device registered, as we have not read any
temperature before, thus tz->temperature should not be 0,
which actually means 0C, and thermal trend is not available.
In this case, we need specially handling for the first
thermal_zone_device_update().
Both thermal core framework and step_wise governor is
enhanced to handle this.
CC: <stable@vger.kernel.org> #3.18+
Tested-by: Manuel Krause <manuelkrause@netscape.net>
Tested-by: szegad <szegadlo@poczta.onet.pl>
Tested-by: prash <prash.n.rao@gmail.com>
Tested-by: amish <ammdispose-arch@yahoo.com>
Tested-by: Matthias <morpheusxyz123@yahoo.de>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Chen Yu <yu.c.chen@intel.com>
---
drivers/thermal/step_wise.c | 18 ++++++++++++++++--
drivers/thermal/thermal_core.c | 19 +++++++++++++++++--
drivers/thermal/thermal_core.h | 1 +
include/linux/thermal.h | 3 +++
4 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/drivers/thermal/step_wise.c b/drivers/thermal/step_wise.c
index 2f9f708..405de04 100644
--- a/drivers/thermal/step_wise.c
+++ b/drivers/thermal/step_wise.c
@@ -63,6 +63,19 @@ static unsigned long get_target_state(struct thermal_instance *instance,
next_target = instance->target;
dev_dbg(&cdev->device, "cur_state=%ld\n", cur_state);
+ if (!instance->initialized) {
+ if (throttle) {
+ next_target = (cur_state + 1) >= instance->upper ?
+ instance->upper :
+ ((cur_state + 1) < instance->lower ?
+ instance->lower : (cur_state + 1));
+ } else {
+ next_target = THERMAL_NO_TARGET;
+ }
+
+ return next_target;
+ }
+
switch (trend) {
case THERMAL_TREND_RAISING:
if (throttle) {
@@ -149,7 +162,8 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
dev_dbg(&instance->cdev->device, "old_target=%d, target=%d\n",
old_target, (int)instance->target);
- if (old_target == instance->target)
+ if (instance->initialized &&
+ old_target == instance->target)
continue;
/* Activate a passive thermal instance */
@@ -161,7 +175,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
instance->target == THERMAL_NO_TARGET)
update_passive_instance(tz, trip_type, -1);
-
+ instance->initialized = true;
instance->cdev->updated = false; /* cdev needs update */
}
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index d9e525c..682bc1e 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -532,8 +532,22 @@ static void update_temperature(struct thermal_zone_device *tz)
mutex_unlock(&tz->lock);
trace_thermal_temperature(tz);
- dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
- tz->last_temperature, tz->temperature);
+ if (tz->last_temperature == THERMAL_TEMP_INVALID)
+ dev_dbg(&tz->device, "last_temperature N/A, current_temperature=%d\n",
+ tz->temperature);
+ else
+ dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
+ tz->last_temperature, tz->temperature);
+}
+
+static void thermal_zone_device_reset(struct thermal_zone_device *tz)
+{
+ struct thermal_instance *pos;
+
+ tz->temperature = THERMAL_TEMP_INVALID;
+ tz->passive = 0;
+ list_for_each_entry(pos, &tz->thermal_instances, tz_node)
+ pos->initialized = false;
}
void thermal_zone_device_update(struct thermal_zone_device *tz)
@@ -1900,6 +1914,7 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check);
+ thermal_zone_device_reset(tz);
thermal_zone_device_update(tz);
return tz;
diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
index d7ac1fc..749d41a 100644
--- a/drivers/thermal/thermal_core.h
+++ b/drivers/thermal/thermal_core.h
@@ -41,6 +41,7 @@ struct thermal_instance {
struct thermal_zone_device *tz;
struct thermal_cooling_device *cdev;
int trip;
+ bool initialized;
unsigned long upper; /* Highest cooling state for this trip point */
unsigned long lower; /* Lowest cooling state for this trip point */
unsigned long target; /* expected cooling state */
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 157d366..5bcabc7 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -43,6 +43,9 @@
/* Default weight of a bound cooling device */
#define THERMAL_WEIGHT_DEFAULT 0
+/* use value, which < 0K, to indicate an invalid/uninitialized temperature */
+#define THERMAL_TEMP_INVALID -274000
+
/* Unit conversion macros */
#define KELVIN_TO_CELSIUS(t) (long)(((long)t-2732 >= 0) ? \
((long)t-2732+5)/10 : ((long)t-2732-5)/10)
--
1.8.4.2
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH 1/3] Thermal: initialize thermal zone device correctly
2015-09-27 5:48 [PATCH 1/3] Thermal: initialize thermal zone device correctly Chen Yu
@ 2015-09-28 14:28 ` Javi Merino
2015-09-28 17:30 ` Chen, Yu C
0 siblings, 1 reply; 8+ messages in thread
From: Javi Merino @ 2015-09-28 14:28 UTC (permalink / raw)
To: Chen Yu
Cc: linux-pm@vger.kernel.org, edubezval@gmail.com,
rui.zhang@intel.com, linux-kernel@vger.kernel.org,
stable@vger.kernel.org
On Sun, Sep 27, 2015 at 06:48:28AM +0100, Chen Yu wrote:
> From: Zhang Rui <rui.zhang@intel.com>
>
> After thermal zone device registered, as we have not read any
> temperature before, thus tz->temperature should not be 0,
> which actually means 0C, and thermal trend is not available.
> In this case, we need specially handling for the first
> thermal_zone_device_update().
>
> Both thermal core framework and step_wise governor is
> enhanced to handle this.
It may be worth pointing out that the step_wise governor is the only
one that uses trends, so it's the only thermal governor that needs to
be updated.
> CC: <stable@vger.kernel.org> #3.18+
> Tested-by: Manuel Krause <manuelkrause@netscape.net>
> Tested-by: szegad <szegadlo@poczta.onet.pl>
> Tested-by: prash <prash.n.rao@gmail.com>
> Tested-by: amish <ammdispose-arch@yahoo.com>
> Tested-by: Matthias <morpheusxyz123@yahoo.de>
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> Signed-off-by: Chen Yu <yu.c.chen@intel.com>
One minor nit below, other than that,
Reviewed-by: Javi Merino <javi.merino@arm.com>
> ---
> drivers/thermal/step_wise.c | 18 ++++++++++++++++--
> drivers/thermal/thermal_core.c | 19 +++++++++++++++++--
> drivers/thermal/thermal_core.h | 1 +
> include/linux/thermal.h | 3 +++
> 4 files changed, 37 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/thermal/step_wise.c b/drivers/thermal/step_wise.c
> index 2f9f708..405de04 100644
> --- a/drivers/thermal/step_wise.c
> +++ b/drivers/thermal/step_wise.c
> @@ -63,6 +63,19 @@ static unsigned long get_target_state(struct thermal_instance *instance,
> next_target = instance->target;
> dev_dbg(&cdev->device, "cur_state=%ld\n", cur_state);
>
> + if (!instance->initialized) {
> + if (throttle) {
> + next_target = (cur_state + 1) >= instance->upper ?
> + instance->upper :
> + ((cur_state + 1) < instance->lower ?
> + instance->lower : (cur_state + 1));
> + } else {
> + next_target = THERMAL_NO_TARGET;
> + }
> +
> + return next_target;
> + }
> +
> switch (trend) {
> case THERMAL_TREND_RAISING:
> if (throttle) {
> @@ -149,7 +162,8 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
> dev_dbg(&instance->cdev->device, "old_target=%d, target=%d\n",
> old_target, (int)instance->target);
>
> - if (old_target == instance->target)
> + if (instance->initialized &&
> + old_target == instance->target)
nit: it fits in one line,
if (instance->initialized && old_target == instance->target)
is 77 characters.
Cheers,
Javi
^ permalink raw reply [flat|nested] 8+ messages in thread* RE: [PATCH 1/3] Thermal: initialize thermal zone device correctly
2015-09-28 14:28 ` Javi Merino
@ 2015-09-28 17:30 ` Chen, Yu C
2015-09-28 17:47 ` Javi Merino
0 siblings, 1 reply; 8+ messages in thread
From: Chen, Yu C @ 2015-09-28 17:30 UTC (permalink / raw)
To: Javi Merino
Cc: linux-pm@vger.kernel.org, edubezval@gmail.com, Zhang, Rui,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
Hi, Javi,
> -----Original Message-----
> From: Javi Merino [mailto:javi.merino@arm.com]
> Sent: Monday, September 28, 2015 10:28 PM
> To: Chen, Yu C
> Cc: linux-pm@vger.kernel.org; edubezval@gmail.com; Zhang, Rui; linux-
> kernel@vger.kernel.org; stable@vger.kernel.org
> Subject: Re: [PATCH 1/3] Thermal: initialize thermal zone device correctly
>
> On Sun, Sep 27, 2015 at 06:48:28AM +0100, Chen Yu wrote:
> > From: Zhang Rui <rui.zhang@intel.com>
> >
> > After thermal zone device registered, as we have not read any
> > temperature before, thus tz->temperature should not be 0, which
> > actually means 0C, and thermal trend is not available.
> > In this case, we need specially handling for the first
> > thermal_zone_device_update().
> >
> > Both thermal core framework and step_wise governor is enhanced to
> > handle this.
>
> It may be worth pointing out that the step_wise governor is the only one
> that uses trends, so it's the only thermal governor that needs to be updated.
>
OK, will add.
>
> > - if (old_target == instance->target)
> > + if (instance->initialized &&
> > + old_target == instance->target)
>
> nit: it fits in one line,
>
> if (instance->initialized && old_target == instance->target)
>
> is 77 characters.
>
Not sure if the limit for one line is 75 in checkpatch.pl, I'll have a try.
Thanks!
Best Regards,
Yu
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/3] Thermal: initialize thermal zone device correctly
2015-09-28 17:30 ` Chen, Yu C
@ 2015-09-28 17:47 ` Javi Merino
0 siblings, 0 replies; 8+ messages in thread
From: Javi Merino @ 2015-09-28 17:47 UTC (permalink / raw)
To: Chen, Yu C
Cc: linux-pm@vger.kernel.org, edubezval@gmail.com, Zhang, Rui,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
On Mon, Sep 28, 2015 at 06:30:30PM +0100, Chen, Yu C wrote:
> Hi, Javi,
>
> > -----Original Message-----
> > From: Javi Merino [mailto:javi.merino@arm.com]
> > Sent: Monday, September 28, 2015 10:28 PM
> > To: Chen, Yu C
> > Cc: linux-pm@vger.kernel.org; edubezval@gmail.com; Zhang, Rui; linux-
> > kernel@vger.kernel.org; stable@vger.kernel.org
> > Subject: Re: [PATCH 1/3] Thermal: initialize thermal zone device correctly
> >
> > On Sun, Sep 27, 2015 at 06:48:28AM +0100, Chen Yu wrote:
> > > From: Zhang Rui <rui.zhang@intel.com>
> > >
> > > After thermal zone device registered, as we have not read any
> > > temperature before, thus tz->temperature should not be 0, which
> > > actually means 0C, and thermal trend is not available.
> > > In this case, we need specially handling for the first
> > > thermal_zone_device_update().
> > >
> > > Both thermal core framework and step_wise governor is enhanced to
> > > handle this.
> >
> > It may be worth pointing out that the step_wise governor is the only one
> > that uses trends, so it's the only thermal governor that needs to be updated.
> >
> OK, will add.
> >
> > > - if (old_target == instance->target)
> > > + if (instance->initialized &&
> > > + old_target == instance->target)
> >
> > nit: it fits in one line,
> >
> > if (instance->initialized && old_target == instance->target)
> >
> > is 77 characters.
> >
> Not sure if the limit for one line is 75 in checkpatch.pl, I'll have a try.
The limit is 80:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/CodingStyle#n79
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/scripts/checkpatch.pl#n47
Cheers,
Javi
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 0/3] Thermal: thermal enhancements for boot and system sleep
@ 2015-03-24 5:21 Zhang Rui
2015-03-24 5:21 ` [PATCH 1/3] Thermal: initialize thermal zone device correctly Zhang Rui
0 siblings, 1 reply; 8+ messages in thread
From: Zhang Rui @ 2015-03-24 5:21 UTC (permalink / raw)
To: linux-pm; +Cc: Zhang Rui
Currently, there are a couple of problems in thermal core framework after boot
and resume from system sleep state, because the thermal zone devices are not
put into a proper state in these cases.
Details of the problems are described in the patch change logs.
In general, altogether they fix three bugs
https://bugzilla.kernel.org/show_bug.cgi?id=78201
https://bugzilla.kernel.org/show_bug.cgi?id=91411
https://bugzilla.kernel.org/show_bug.cgi?id=92431
Bug 78201 needs patch 1/3 and 2/3.
Bug 91411 and 92431 are regressions caused by
commit 19593a1fb1f6718406afca5b867dab184289d406
Author: Aaron Lu <aaron.lu@intel.com>
Date: Tue Nov 19 16:59:20 2013 +0800
ACPI / fan: convert to platform driver
Convert ACPI fan driver to a platform driver for the purpose of phasing
out ACPI bus.
Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
which is shipped in 3.18.
Bug 91411 needs patch 1/3, 2/3 to fix, while 92431 needs all three patches.
If possible, I'd like to push these patches into 4.0-rc and 3.18/3.19 stable
kernel as it actually fixes a regression in 3.18.
Any comments are welcome.
thanks,
rui
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 1/3] Thermal: initialize thermal zone device correctly
2015-03-24 5:21 [PATCH 0/3] Thermal: thermal enhancements for boot and system sleep Zhang Rui
@ 2015-03-24 5:21 ` Zhang Rui
2015-03-24 15:00 ` Eduardo Valentin
0 siblings, 1 reply; 8+ messages in thread
From: Zhang Rui @ 2015-03-24 5:21 UTC (permalink / raw)
To: linux-pm; +Cc: Zhang Rui, stable
After thermal zone device registered, as we have not read any
temperature before, thus tz->temperature should not be 0, which actually
means 0C, and thermal trend is not available.
In this case, we need specially handling for the first
thermal_zone_device_update().
Both thermal core framework and step_wise governor is enhanced to handle this.
CC: <stable@vger.kernel.org> #3.18+
Tested-by: Manuel Krause <manuelkrause@netscape.net>
Tested-by: szegad <szegadlo@poczta.onet.pl>
Tested-by: prash <prash.n.rao@gmail.com>
Tested-by: amish <ammdispose-arch@yahoo.com>
Tested-by: Matthias <morpheusxyz123@yahoo.de>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
drivers/thermal/step_wise.c | 15 +++++++++++++--
drivers/thermal/thermal_core.c | 19 +++++++++++++++++--
drivers/thermal/thermal_core.h | 1 +
include/linux/thermal.h | 3 +++
4 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/drivers/thermal/step_wise.c b/drivers/thermal/step_wise.c
index 5a0f12d..c2bb37c 100644
--- a/drivers/thermal/step_wise.c
+++ b/drivers/thermal/step_wise.c
@@ -63,6 +63,16 @@ static unsigned long get_target_state(struct thermal_instance *instance,
next_target = instance->target;
dev_dbg(&cdev->device, "cur_state=%ld\n", cur_state);
+ if (!instance->initialized) {
+ if (throttle) {
+ next_target = (cur_state + 1) >= instance->upper ?
+ instance->upper :
+ ((cur_state + 1) < instance->lower ?
+ instance->lower : (cur_state + 1));
+ } else
+ next_target = THERMAL_NO_TARGET;
+ }
+
switch (trend) {
case THERMAL_TREND_RAISING:
if (throttle) {
@@ -149,7 +159,8 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
dev_dbg(&instance->cdev->device, "old_target=%d, target=%d\n",
old_target, (int)instance->target);
- if (old_target == instance->target)
+ if (instance->initialized &&
+ old_target == instance->target)
continue;
/* Activate a passive thermal instance */
@@ -161,7 +172,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
instance->target == THERMAL_NO_TARGET)
update_passive_instance(tz, trip_type, -1);
-
+ instance->initialized = true;
instance->cdev->updated = false; /* cdev needs update */
}
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 174d3bc..9d6f71b 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -469,8 +469,22 @@ static void update_temperature(struct thermal_zone_device *tz)
mutex_unlock(&tz->lock);
trace_thermal_temperature(tz);
- dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
- tz->last_temperature, tz->temperature);
+ if (tz->last_temperature == THERMAL_TEMP_INVALID)
+ dev_dbg(&tz->device, "last_temperature N/A, current_temperature=%d\n",
+ tz->temperature);
+ else
+ dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
+ tz->last_temperature, tz->temperature);
+}
+
+static void thermal_zone_device_reset(struct thermal_zone_device *tz)
+{
+ struct thermal_instance *pos;
+
+ tz->temperature = THERMAL_TEMP_INVALID;
+ tz->passive = 0;
+ list_for_each_entry(pos, &tz->thermal_instances, tz_node)
+ pos->initialized = false;
}
void thermal_zone_device_update(struct thermal_zone_device *tz)
@@ -1574,6 +1588,7 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
if (!tz->ops->get_temp)
thermal_zone_device_set_polling(tz, 0);
+ thermal_zone_device_reset(tz);
thermal_zone_device_update(tz);
return tz;
diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
index 0531c75..6d9ffa5 100644
--- a/drivers/thermal/thermal_core.h
+++ b/drivers/thermal/thermal_core.h
@@ -41,6 +41,7 @@ struct thermal_instance {
struct thermal_zone_device *tz;
struct thermal_cooling_device *cdev;
int trip;
+ bool initialized;
unsigned long upper; /* Highest cooling state for this trip point */
unsigned long lower; /* Lowest cooling state for this trip point */
unsigned long target; /* expected cooling state */
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 5eac316..8650b0b 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -40,6 +40,9 @@
/* No upper/lower limit requirement */
#define THERMAL_NO_LIMIT ((u32)~0)
+/* Invalid/uninitialized temperature */
+#define THERMAL_TEMP_INVALID -27400
+
/* Unit conversion macros */
#define KELVIN_TO_CELSIUS(t) (long)(((long)t-2732 >= 0) ? \
((long)t-2732+5)/10 : ((long)t-2732-5)/10)
--
1.9.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH 1/3] Thermal: initialize thermal zone device correctly
2015-03-24 5:21 ` [PATCH 1/3] Thermal: initialize thermal zone device correctly Zhang Rui
@ 2015-03-24 15:00 ` Eduardo Valentin
2015-03-24 17:20 ` Javi Merino
2015-03-25 2:14 ` Zhang, Rui
0 siblings, 2 replies; 8+ messages in thread
From: Eduardo Valentin @ 2015-03-24 15:00 UTC (permalink / raw)
To: Zhang Rui; +Cc: linux-pm, stable
[-- Attachment #1: Type: text/plain, Size: 5472 bytes --]
Rui,
A couple of comments.
On Tue, Mar 24, 2015 at 01:21:28PM +0800, Zhang Rui wrote:
> After thermal zone device registered, as we have not read any
> temperature before, thus tz->temperature should not be 0, which actually
> means 0C, and thermal trend is not available.
> In this case, we need specially handling for the first
> thermal_zone_device_update().
>
> Both thermal core framework and step_wise governor is enhanced to handle this.
>
> CC: <stable@vger.kernel.org> #3.18+
> Tested-by: Manuel Krause <manuelkrause@netscape.net>
> Tested-by: szegad <szegadlo@poczta.onet.pl>
> Tested-by: prash <prash.n.rao@gmail.com>
> Tested-by: amish <ammdispose-arch@yahoo.com>
> Tested-by: Matthias <morpheusxyz123@yahoo.de>
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> ---
> drivers/thermal/step_wise.c | 15 +++++++++++++--
> drivers/thermal/thermal_core.c | 19 +++++++++++++++++--
> drivers/thermal/thermal_core.h | 1 +
> include/linux/thermal.h | 3 +++
> 4 files changed, 34 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/thermal/step_wise.c b/drivers/thermal/step_wise.c
Should this patch also include changes in other governors ?
> index 5a0f12d..c2bb37c 100644
> --- a/drivers/thermal/step_wise.c
> +++ b/drivers/thermal/step_wise.c
> @@ -63,6 +63,16 @@ static unsigned long get_target_state(struct thermal_instance *instance,
> next_target = instance->target;
> dev_dbg(&cdev->device, "cur_state=%ld\n", cur_state);
>
> + if (!instance->initialized) {
> + if (throttle) {
> + next_target = (cur_state + 1) >= instance->upper ?
> + instance->upper :
> + ((cur_state + 1) < instance->lower ?
> + instance->lower : (cur_state + 1));
Why it makes sense to change the next state if a instance is
uninitialized?
> + } else
> + next_target = THERMAL_NO_TARGET;
> + }
> +
> switch (trend) {
> case THERMAL_TREND_RAISING:
> if (throttle) {
> @@ -149,7 +159,8 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
> dev_dbg(&instance->cdev->device, "old_target=%d, target=%d\n",
> old_target, (int)instance->target);
>
> - if (old_target == instance->target)
> + if (instance->initialized &&
> + old_target == instance->target)
> continue;
>
> /* Activate a passive thermal instance */
> @@ -161,7 +172,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
> instance->target == THERMAL_NO_TARGET)
> update_passive_instance(tz, trip_type, -1);
>
> -
> + instance->initialized = true;
> instance->cdev->updated = false; /* cdev needs update */
> }
>
> diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
> index 174d3bc..9d6f71b 100644
> --- a/drivers/thermal/thermal_core.c
> +++ b/drivers/thermal/thermal_core.c
> @@ -469,8 +469,22 @@ static void update_temperature(struct thermal_zone_device *tz)
> mutex_unlock(&tz->lock);
>
> trace_thermal_temperature(tz);
> - dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
> - tz->last_temperature, tz->temperature);
> + if (tz->last_temperature == THERMAL_TEMP_INVALID)
> + dev_dbg(&tz->device, "last_temperature N/A, current_temperature=%d\n",
> + tz->temperature);
> + else
> + dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
> + tz->last_temperature, tz->temperature);
Should we also teach the tracing facility about THERMAL_TEMP_INVALID?
> +}
> +
> +static void thermal_zone_device_reset(struct thermal_zone_device *tz)
> +{
> + struct thermal_instance *pos;
> +
> + tz->temperature = THERMAL_TEMP_INVALID;
> + tz->passive = 0;
> + list_for_each_entry(pos, &tz->thermal_instances, tz_node)
> + pos->initialized = false;
> }
>
> void thermal_zone_device_update(struct thermal_zone_device *tz)
> @@ -1574,6 +1588,7 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
> if (!tz->ops->get_temp)
> thermal_zone_device_set_polling(tz, 0);
>
> + thermal_zone_device_reset(tz);
> thermal_zone_device_update(tz);
>
> return tz;
> diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
> index 0531c75..6d9ffa5 100644
> --- a/drivers/thermal/thermal_core.h
> +++ b/drivers/thermal/thermal_core.h
> @@ -41,6 +41,7 @@ struct thermal_instance {
> struct thermal_zone_device *tz;
> struct thermal_cooling_device *cdev;
> int trip;
> + bool initialized;
> unsigned long upper; /* Highest cooling state for this trip point */
> unsigned long lower; /* Lowest cooling state for this trip point */
> unsigned long target; /* expected cooling state */
> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> index 5eac316..8650b0b 100644
> --- a/include/linux/thermal.h
> +++ b/include/linux/thermal.h
> @@ -40,6 +40,9 @@
> /* No upper/lower limit requirement */
> #define THERMAL_NO_LIMIT ((u32)~0)
>
> +/* Invalid/uninitialized temperature */
> +#define THERMAL_TEMP_INVALID -27400
> +
> /* Unit conversion macros */
> #define KELVIN_TO_CELSIUS(t) (long)(((long)t-2732 >= 0) ? \
> ((long)t-2732+5)/10 : ((long)t-2732-5)/10)
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH 1/3] Thermal: initialize thermal zone device correctly
2015-03-24 15:00 ` Eduardo Valentin
@ 2015-03-24 17:20 ` Javi Merino
2015-03-25 2:14 ` Zhang, Rui
1 sibling, 0 replies; 8+ messages in thread
From: Javi Merino @ 2015-03-24 17:20 UTC (permalink / raw)
To: Eduardo Valentin
Cc: Punit Agrawal, Zhang Rui, linux-pm@vger.kernel.org,
stable@vger.kernel.org
On Tue, Mar 24, 2015 at 03:00:06PM +0000, Eduardo Valentin wrote:
> Rui,
>
> A couple of comments.
>
> On Tue, Mar 24, 2015 at 01:21:28PM +0800, Zhang Rui wrote:
> > After thermal zone device registered, as we have not read any
> > temperature before, thus tz->temperature should not be 0, which actually
> > means 0C, and thermal trend is not available.
> > In this case, we need specially handling for the first
> > thermal_zone_device_update().
> >
> > Both thermal core framework and step_wise governor is enhanced to handle this.
> >
> > CC: <stable@vger.kernel.org> #3.18+
> > Tested-by: Manuel Krause <manuelkrause@netscape.net>
> > Tested-by: szegad <szegadlo@poczta.onet.pl>
> > Tested-by: prash <prash.n.rao@gmail.com>
> > Tested-by: amish <ammdispose-arch@yahoo.com>
> > Tested-by: Matthias <morpheusxyz123@yahoo.de>
> > Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> > ---
> > drivers/thermal/step_wise.c | 15 +++++++++++++--
> > drivers/thermal/thermal_core.c | 19 +++++++++++++++++--
> > drivers/thermal/thermal_core.h | 1 +
> > include/linux/thermal.h | 3 +++
> > 4 files changed, 34 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/thermal/step_wise.c b/drivers/thermal/step_wise.c
>
> Should this patch also include changes in other governors ?
If I understand it correctly, instance->initialized actually means
"is the trend valid?". As step_wise is the only governor that uses
the trend, it's the only one that needs updating.
> > index 5a0f12d..c2bb37c 100644
> > --- a/drivers/thermal/step_wise.c
> > +++ b/drivers/thermal/step_wise.c
> > @@ -63,6 +63,16 @@ static unsigned long get_target_state(struct thermal_instance *instance,
> > next_target = instance->target;
> > dev_dbg(&cdev->device, "cur_state=%ld\n", cur_state);
> >
> > + if (!instance->initialized) {
> > + if (throttle) {
> > + next_target = (cur_state + 1) >= instance->upper ?
> > + instance->upper :
> > + ((cur_state + 1) < instance->lower ?
> > + instance->lower : (cur_state + 1));
>
> Why it makes sense to change the next state if a instance is
> uninitialized?
>
> > + } else
> > + next_target = THERMAL_NO_TARGET;
CodingStyle says that if one branch of an if statement needs braces,
all branches must have braces:
if (condition) {
do_this();
do_that();
} else {
otherwise();
}
> > + }
> > +
Does this really work? The update of next_target will probably be
overwritten by the switch below, shouldn't you "return next_target;"
at the end of the "if (!instance->initialized)"?
> > switch (trend) {
> > case THERMAL_TREND_RAISING:
> > if (throttle) {
> > @@ -149,7 +159,8 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
> > dev_dbg(&instance->cdev->device, "old_target=%d, target=%d\n",
> > old_target, (int)instance->target);
> >
> > - if (old_target == instance->target)
> > + if (instance->initialized &&
> > + old_target == instance->target)
> > continue;
> >
> > /* Activate a passive thermal instance */
> > @@ -161,7 +172,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
> > instance->target == THERMAL_NO_TARGET)
> > update_passive_instance(tz, trip_type, -1);
> >
> > -
> > + instance->initialized = true;
> > instance->cdev->updated = false; /* cdev needs update */
> > }
> >
> > diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
> > index 174d3bc..9d6f71b 100644
> > --- a/drivers/thermal/thermal_core.c
> > +++ b/drivers/thermal/thermal_core.c
> > @@ -469,8 +469,22 @@ static void update_temperature(struct thermal_zone_device *tz)
> > mutex_unlock(&tz->lock);
> >
> > trace_thermal_temperature(tz);
> > - dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
> > - tz->last_temperature, tz->temperature);
> > + if (tz->last_temperature == THERMAL_TEMP_INVALID)
> > + dev_dbg(&tz->device, "last_temperature N/A, current_temperature=%d\n",
> > + tz->temperature);
> > + else
> > + dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
> > + tz->last_temperature, tz->temperature);
>
> Should we also teach the tracing facility about THERMAL_TEMP_INVALID?
I don't think there's a good way of putting this information in
trace. The format string is fixed and playing with it like we do here
is not an option. In practical terms, trace will collect a weird
"-27400" for the previous temperature, so it's not too bad. I guess
it would help if the invalid temperature was something more obvious,
like INT_MIN.
> > +}
> > +
> > +static void thermal_zone_device_reset(struct thermal_zone_device *tz)
> > +{
> > + struct thermal_instance *pos;
> > +
> > + tz->temperature = THERMAL_TEMP_INVALID;
> > + tz->passive = 0;
> > + list_for_each_entry(pos, &tz->thermal_instances, tz_node)
> > + pos->initialized = false;
> > }
> >
> > void thermal_zone_device_update(struct thermal_zone_device *tz)
> > @@ -1574,6 +1588,7 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
> > if (!tz->ops->get_temp)
> > thermal_zone_device_set_polling(tz, 0);
> >
> > + thermal_zone_device_reset(tz);
> > thermal_zone_device_update(tz);
> >
> > return tz;
> > diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
> > index 0531c75..6d9ffa5 100644
> > --- a/drivers/thermal/thermal_core.h
> > +++ b/drivers/thermal/thermal_core.h
> > @@ -41,6 +41,7 @@ struct thermal_instance {
> > struct thermal_zone_device *tz;
> > struct thermal_cooling_device *cdev;
> > int trip;
> > + bool initialized;
This could be more specific. If I understand it correctly, this flag
indicates if the trend is valid or not. Can we call it "valid_trend"
instead?
> > unsigned long upper; /* Highest cooling state for this trip point */
> > unsigned long lower; /* Lowest cooling state for this trip point */
> > unsigned long target; /* expected cooling state */
> > diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> > index 5eac316..8650b0b 100644
> > --- a/include/linux/thermal.h
> > +++ b/include/linux/thermal.h
> > @@ -40,6 +40,9 @@
> > /* No upper/lower limit requirement */
> > #define THERMAL_NO_LIMIT ((u32)~0)
> >
> > +/* Invalid/uninitialized temperature */
> > +#define THERMAL_TEMP_INVALID -27400
Out of curiosity, why -27400? Why not INT_MIN?
Cheers,
Javi
^ permalink raw reply [flat|nested] 8+ messages in thread* RE: [PATCH 1/3] Thermal: initialize thermal zone device correctly
2015-03-24 15:00 ` Eduardo Valentin
2015-03-24 17:20 ` Javi Merino
@ 2015-03-25 2:14 ` Zhang, Rui
1 sibling, 0 replies; 8+ messages in thread
From: Zhang, Rui @ 2015-03-25 2:14 UTC (permalink / raw)
To: Eduardo Valentin; +Cc: linux-pm@vger.kernel.org, stable@vger.kernel.org
> -----Original Message-----
> From: Eduardo Valentin [mailto:edubezval@gmail.com]
> Sent: Tuesday, March 24, 2015 11:00 PM
> To: Zhang, Rui
> Cc: linux-pm@vger.kernel.org; stable@vger.kernel.org
> Subject: Re: [PATCH 1/3] Thermal: initialize thermal zone device correctly
> Importance: High
>
> Rui,
>
> A couple of comments.
>
> On Tue, Mar 24, 2015 at 01:21:28PM +0800, Zhang Rui wrote:
> > After thermal zone device registered, as we have not read any
> > temperature before, thus tz->temperature should not be 0, which
> > actually means 0C, and thermal trend is not available.
> > In this case, we need specially handling for the first
> > thermal_zone_device_update().
> >
> > Both thermal core framework and step_wise governor is enhanced to handle
> this.
> >
> > CC: <stable@vger.kernel.org> #3.18+
> > Tested-by: Manuel Krause <manuelkrause@netscape.net>
> > Tested-by: szegad <szegadlo@poczta.onet.pl>
> > Tested-by: prash <prash.n.rao@gmail.com>
> > Tested-by: amish <ammdispose-arch@yahoo.com>
> > Tested-by: Matthias <morpheusxyz123@yahoo.de>
> > Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> > ---
> > drivers/thermal/step_wise.c | 15 +++++++++++++--
> > drivers/thermal/thermal_core.c | 19 +++++++++++++++++--
> > drivers/thermal/thermal_core.h | 1 +
> > include/linux/thermal.h | 3 +++
> > 4 files changed, 34 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/thermal/step_wise.c b/drivers/thermal/step_wise.c
>
> Should this patch also include changes in other governors ?
>
No, I've checked the code, step_wise/bang_bang/user_space governor does not have this problem.
> > index 5a0f12d..c2bb37c 100644
> > --- a/drivers/thermal/step_wise.c
> > +++ b/drivers/thermal/step_wise.c
> > @@ -63,6 +63,16 @@ static unsigned long get_target_state(struct
> thermal_instance *instance,
> > next_target = instance->target;
> > dev_dbg(&cdev->device, "cur_state=%ld\n", cur_state);
> >
> > + if (!instance->initialized) {
> > + if (throttle) {
> > + next_target = (cur_state + 1) >= instance->upper ?
> > + instance->upper :
> > + ((cur_state + 1) < instance->lower ?
> > + instance->lower : (cur_state + 1));
>
> Why it makes sense to change the next state if a instance is uninitialized?
>
For thermal safety reason, I prefer to use a higher cooling state because the system is overheating with current cooling state
I even used to think about using instance->upper directly, but in this case, cooling devices like processors are put into the lowest frequency, and processors on ACPI based platform are put into lowest t-state, which is overkill.
> > + } else
> > + next_target = THERMAL_NO_TARGET;
> > + }
> > +
> > switch (trend) {
> > case THERMAL_TREND_RAISING:
> > if (throttle) {
> > @@ -149,7 +159,8 @@ static void thermal_zone_trip_update(struct
> thermal_zone_device *tz, int trip)
> > dev_dbg(&instance->cdev->device, "old_target=%d,
> target=%d\n",
> > old_target, (int)instance->target);
> >
> > - if (old_target == instance->target)
> > + if (instance->initialized &&
> > + old_target == instance->target)
> > continue;
> >
> > /* Activate a passive thermal instance */ @@ -161,7 +172,7
> @@
> > static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
> > instance->target == THERMAL_NO_TARGET)
> > update_passive_instance(tz, trip_type, -1);
> >
> > -
> > + instance->initialized = true;
> > instance->cdev->updated = false; /* cdev needs update */
> > }
> >
> > diff --git a/drivers/thermal/thermal_core.c
> > b/drivers/thermal/thermal_core.c index 174d3bc..9d6f71b 100644
> > --- a/drivers/thermal/thermal_core.c
> > +++ b/drivers/thermal/thermal_core.c
> > @@ -469,8 +469,22 @@ static void update_temperature(struct
> thermal_zone_device *tz)
> > mutex_unlock(&tz->lock);
> >
> > trace_thermal_temperature(tz);
> > - dev_dbg(&tz->device, "last_temperature=%d,
> current_temperature=%d\n",
> > - tz->last_temperature, tz->temperature);
> > + if (tz->last_temperature == THERMAL_TEMP_INVALID)
> > + dev_dbg(&tz->device, "last_temperature N/A,
> current_temperature=%d\n",
> > + tz->temperature);
> > + else
> > + dev_dbg(&tz->device, "last_temperature=%d,
> current_temperature=%d\n",
> > + tz->last_temperature, tz->temperature);
>
> Should we also teach the tracing facility about THERMAL_TEMP_INVALID?
>
Hmm, I don't quite understand your question.
Thanks,
rui
> > +}
> > +
> > +static void thermal_zone_device_reset(struct thermal_zone_device *tz)
> > +{
> > + struct thermal_instance *pos;
> > +
> > + tz->temperature = THERMAL_TEMP_INVALID;
> > + tz->passive = 0;
> > + list_for_each_entry(pos, &tz->thermal_instances, tz_node)
> > + pos->initialized = false;
> > }
> >
> > void thermal_zone_device_update(struct thermal_zone_device *tz) @@
> > -1574,6 +1588,7 @@ struct thermal_zone_device
> *thermal_zone_device_register(const char *type,
> > if (!tz->ops->get_temp)
> > thermal_zone_device_set_polling(tz, 0);
> >
> > + thermal_zone_device_reset(tz);
> > thermal_zone_device_update(tz);
> >
> > return tz;
> > diff --git a/drivers/thermal/thermal_core.h
> > b/drivers/thermal/thermal_core.h index 0531c75..6d9ffa5 100644
> > --- a/drivers/thermal/thermal_core.h
> > +++ b/drivers/thermal/thermal_core.h
> > @@ -41,6 +41,7 @@ struct thermal_instance {
> > struct thermal_zone_device *tz;
> > struct thermal_cooling_device *cdev;
> > int trip;
> > + bool initialized;
> > unsigned long upper; /* Highest cooling state for this trip point */
> > unsigned long lower; /* Lowest cooling state for this trip point */
> > unsigned long target; /* expected cooling state */
> > diff --git a/include/linux/thermal.h b/include/linux/thermal.h index
> > 5eac316..8650b0b 100644
> > --- a/include/linux/thermal.h
> > +++ b/include/linux/thermal.h
> > @@ -40,6 +40,9 @@
> > /* No upper/lower limit requirement */
> > #define THERMAL_NO_LIMIT ((u32)~0)
> >
> > +/* Invalid/uninitialized temperature */
> > +#define THERMAL_TEMP_INVALID -27400
> > +
> > /* Unit conversion macros */
> > #define KELVIN_TO_CELSIUS(t) (long)(((long)t-2732 >= 0) ? \
> > ((long)t-2732+5)/10 : ((long)t-2732-5)/10)
> > --
> > 1.9.1
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-pm" in
> > the body of a message to majordomo@vger.kernel.org More majordomo info
> > at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2015-09-28 17:47 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-09-27 5:48 [PATCH 1/3] Thermal: initialize thermal zone device correctly Chen Yu
2015-09-28 14:28 ` Javi Merino
2015-09-28 17:30 ` Chen, Yu C
2015-09-28 17:47 ` Javi Merino
-- strict thread matches above, loose matches on Subject: below --
2015-03-24 5:21 [PATCH 0/3] Thermal: thermal enhancements for boot and system sleep Zhang Rui
2015-03-24 5:21 ` [PATCH 1/3] Thermal: initialize thermal zone device correctly Zhang Rui
2015-03-24 15:00 ` Eduardo Valentin
2015-03-24 17:20 ` Javi Merino
2015-03-25 2:14 ` Zhang, Rui
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).