From: alexander.levin@verizon.com
To: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"stable@vger.kernel.org" <stable@vger.kernel.org>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>,
Keerthy <j-keerthy@ti.com>, John Stultz <john.stultz@linaro.org>,
Leo Yan <leo.yan@linaro.org>,
"Eduardo Valentin" <edubezval@gmail.com>,
alexander.levin@verizon.com
Subject: [PATCH AUTOSEL for 3.18 45/59] thermal/drivers/step_wise: Fix temperature regulation misbehavior
Date: Thu, 7 Dec 2017 15:51:33 +0000 [thread overview]
Message-ID: <20171207155116.6013-45-alexander.levin@verizon.com> (raw)
In-Reply-To: <20171207155116.6013-1-alexander.levin@verizon.com>
From: Daniel Lezcano <daniel.lezcano@linaro.org>
[ Upstream commit 07209fcf33542c1ff1e29df2dbdf8f29cdaacb10 ]
There is a particular situation when the cooling device is cpufreq and the heat
dissipation is not efficient enough where the temperature increases little by
little until reaching the critical threshold and leading to a SoC reset.
The behavior is reproducible on a hikey6220 with bad heat dissipation (eg.
stacked with other boards).
Running a simple C program doing while(1); for each CPU of the SoC makes the
temperature to reach the passive regulation trip point and ends up to the
maximum allowed temperature followed by a reset.
This issue has been also reported by running the libhugetlbfs test suite.
What is observed is a ping pong between two cpu frequencies, 1.2GHz and 900MHz
while the temperature continues to grow.
It appears the step wise governor calls get_target_state() the first time with
the throttle set to true and the trend to 'raising'. The code selects logically
the next state, so the cpu frequency decreases from 1.2GHz to 900MHz, so far so
good. The temperature decreases immediately but still stays greater than the
trip point, then get_target_state() is called again, this time with the
throttle set to true *and* the trend to 'dropping'. From there the algorithm
assumes we have to step down the state and the cpu frequency jumps back to
1.2GHz. But the temperature is still higher than the trip point, so
get_target_state() is called with throttle=1 and trend='raising' again, we jump
to 900MHz, then get_target_state() is called with throttle=1 and
trend='dropping', we jump to 1.2GHz, etc ... but the temperature does not
stabilizes and continues to increase.
[ 237.922654] thermal thermal_zone0: Trip0[type=1,temp=65000]:trend=1,throttle=1
[ 237.922678] thermal thermal_zone0: Trip1[type=1,temp=75000]:trend=1,throttle=1
[ 237.922690] thermal cooling_device0: cur_state=0
[ 237.922701] thermal cooling_device0: old_target=0, target=1
[ 238.026656] thermal thermal_zone0: Trip0[type=1,temp=65000]:trend=2,throttle=1
[ 238.026680] thermal thermal_zone0: Trip1[type=1,temp=75000]:trend=2,throttle=1
[ 238.026694] thermal cooling_device0: cur_state=1
[ 238.026707] thermal cooling_device0: old_target=1, target=0
[ 238.134647] thermal thermal_zone0: Trip0[type=1,temp=65000]:trend=1,throttle=1
[ 238.134667] thermal thermal_zone0: Trip1[type=1,temp=75000]:trend=1,throttle=1
[ 238.134679] thermal cooling_device0: cur_state=0
[ 238.134690] thermal cooling_device0: old_target=0, target=1
In this situation the temperature continues to increase while the trend is
oscillating between 'dropping' and 'raising'. We need to keep the current state
untouched if the throttle is set, so the temperature can decrease or a higher
state could be selected, thus preventing this oscillation.
Keeping the next_target untouched when 'throttle' is true at 'dropping' time
fixes the issue.
The following traces show the governor does not change the next state if
trend==2 (dropping) and throttle==1.
[ 2306.127987] thermal thermal_zone0: Trip0[type=1,temp=65000]:trend=1,throttle=1
[ 2306.128009] thermal thermal_zone0: Trip1[type=1,temp=75000]:trend=1,throttle=1
[ 2306.128021] thermal cooling_device0: cur_state=0
[ 2306.128031] thermal cooling_device0: old_target=0, target=1
[ 2306.231991] thermal thermal_zone0: Trip0[type=1,temp=65000]:trend=2,throttle=1
[ 2306.232016] thermal thermal_zone0: Trip1[type=1,temp=75000]:trend=2,throttle=1
[ 2306.232030] thermal cooling_device0: cur_state=1
[ 2306.232042] thermal cooling_device0: old_target=1, target=1
[ 2306.335982] thermal thermal_zone0: Trip0[type=1,temp=65000]:trend=0,throttle=1
[ 2306.336006] thermal thermal_zone0: Trip1[type=1,temp=75000]:trend=0,throttle=1
[ 2306.336021] thermal cooling_device0: cur_state=1
[ 2306.336034] thermal cooling_device0: old_target=1, target=1
[ 2306.439984] thermal thermal_zone0: Trip0[type=1,temp=65000]:trend=2,throttle=1
[ 2306.440008] thermal thermal_zone0: Trip1[type=1,temp=75000]:trend=2,throttle=0
[ 2306.440022] thermal cooling_device0: cur_state=1
[ 2306.440034] thermal cooling_device0: old_target=1, target=0
[ ... ]
After a while, if the temperature continues to increase, the next state becomes
2 which is 720MHz on the hikey. That results in the temperature stabilizing
around the trip point.
[ 2455.831982] thermal thermal_zone0: Trip0[type=1,temp=65000]:trend=1,throttle=1
[ 2455.832006] thermal thermal_zone0: Trip1[type=1,temp=75000]:trend=1,throttle=0
[ 2455.832019] thermal cooling_device0: cur_state=1
[ 2455.832032] thermal cooling_device0: old_target=1, target=1
[ 2455.935985] thermal thermal_zone0: Trip0[type=1,temp=65000]:trend=0,throttle=1
[ 2455.936013] thermal thermal_zone0: Trip1[type=1,temp=75000]:trend=0,throttle=0
[ 2455.936027] thermal cooling_device0: cur_state=1
[ 2455.936040] thermal cooling_device0: old_target=1, target=1
[ 2456.043984] thermal thermal_zone0: Trip0[type=1,temp=65000]:trend=0,throttle=1
[ 2456.044009] thermal thermal_zone0: Trip1[type=1,temp=75000]:trend=0,throttle=0
[ 2456.044023] thermal cooling_device0: cur_state=1
[ 2456.044036] thermal cooling_device0: old_target=1, target=1
[ 2456.148001] thermal thermal_zone0: Trip0[type=1,temp=65000]:trend=1,throttle=1
[ 2456.148028] thermal thermal_zone0: Trip1[type=1,temp=75000]:trend=1,throttle=1
[ 2456.148042] thermal cooling_device0: cur_state=1
[ 2456.148055] thermal cooling_device0: old_target=1, target=2
[ 2456.252009] thermal thermal_zone0: Trip0[type=1,temp=65000]:trend=2,throttle=1
[ 2456.252041] thermal thermal_zone0: Trip1[type=1,temp=75000]:trend=2,throttle=0
[ 2456.252058] thermal cooling_device0: cur_state=2
[ 2456.252075] thermal cooling_device0: old_target=2, target=1
IOW, this change is needed to keep the state for a cooling device if the
temperature trend is oscillating while the temperature increases slightly.
Without this change, the situation above leads to a catastrophic crash by a
hardware reset on hikey. This issue has been reported to happen on an OMAP
dra7xx also.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Keerthy <j-keerthy@ti.com>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Leo Yan <leo.yan@linaro.org>
Tested-by: Keerthy <j-keerthy@ti.com>
Reviewed-by: Keerthy <j-keerthy@ti.com>
Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
---
drivers/thermal/step_wise.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/thermal/step_wise.c b/drivers/thermal/step_wise.c
index dc4b69671d87..eed5b448fbf9 100644
--- a/drivers/thermal/step_wise.c
+++ b/drivers/thermal/step_wise.c
@@ -31,8 +31,7 @@
* If the temperature is higher than a trip point,
* a. if the trend is THERMAL_TREND_RAISING, use higher cooling
* state for this trip point
- * b. if the trend is THERMAL_TREND_DROPPING, use lower cooling
- * state for this trip point
+ * b. if the trend is THERMAL_TREND_DROPPING, do nothing
* c. if the trend is THERMAL_TREND_RAISE_FULL, use upper limit
* for this trip point
* d. if the trend is THERMAL_TREND_DROP_FULL, use lower limit
@@ -94,9 +93,11 @@ static unsigned long get_target_state(struct thermal_instance *instance,
if (!throttle)
next_target = THERMAL_NO_TARGET;
} else {
- next_target = cur_state - 1;
- if (next_target > instance->upper)
- next_target = instance->upper;
+ if (!throttle) {
+ next_target = cur_state - 1;
+ if (next_target > instance->upper)
+ next_target = instance->upper;
+ }
}
break;
case THERMAL_TREND_DROP_FULL:
--
2.11.0
next prev parent reply other threads:[~2017-12-07 15:58 UTC|newest]
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-12-07 15:51 [PATCH AUTOSEL for 3.18 01/59] usb: phy: isp1301: Add OF device ID table alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 02/59] net: bcmgenet: correct the RBUF_OVFL_CNT and RBUF_ERR_CNT MIB values alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 06/59] NFSD: fix nfsd_reset_versions for NFSv4 alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 04/59] net: bcmgenet: Power up the internal PHY before probing the MII alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 05/59] NFSD: fix nfsd_minorversion(.., NFSD_AVAIL) alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 03/59] net: bcmgenet: correct MIB access of UniMAC RUNT counters alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 07/59] Input: i8042 - add TUXEDO BU1406 (N24_25BU) to the nomux list alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 09/59] dmaengine: Fix array index out of bounds warning in __get_unmap_pool() alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 10/59] net: Resend IGMP memberships upon peer notification alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 08/59] net: wimax/i2400m: fix NULL-deref at probe alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 14/59] drm/radeon: reinstate oland workaround for sclk alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 12/59] drm/radeon/si: add dpm quirk for Oland alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 13/59] sched/deadline: Use deadline instead of period when calculating overflow alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 11/59] openrisc: fix issue handling 8 byte get_user calls alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 17/59] afs: Adjust mode bits processing alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 16/59] afs: Populate group ID from vnode status alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 15/59] afs: Fix missing put_page() alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 21/59] afs: Fix page leak in afs_write_begin() alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 20/59] afs: Populate and use client modification time alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 19/59] afs: Fix the maths in afs_fs_store_data() alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 18/59] afs: Flush outstanding writes when an fd is closed alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 24/59] NFSv4.1 respect server's max size in CREATE_SESSION alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 22/59] afs: Fix afs_kill_pages() alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 23/59] perf symbols: Fix symbols__fixup_end heuristic for corner cases alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 25/59] btrfs: add missing memset while reading compressed inline extents alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 27/59] fbdev: controlfb: Add missing modes to fix out of bounds access alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 29/59] video: fbdev: au1200fb: Release some resources if a memory allocation fails alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 26/59] target: Use system workqueue for ALUA transitions alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 28/59] video: udlfb: Fix read EDID timeout alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 31/59] ASoC: cs42l56: Fix reset GPIO name in example DT binding alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 33/59] powerpc/powernv/cpufreq: Fix the frequency read by /proc/cpuinfo alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 32/59] PCI/PME: Handle invalid data when reading Root Status alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 30/59] video: fbdev: au1200fb: Return an error code if a memory allocation fails alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 36/59] platform/x86: sony-laptop: Fix error handling in sony_nc_setup_rfkill() alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 34/59] powerpc/opal: Fix EBUSY bug in acquiring tokens alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 37/59] target/iscsi: Fix a race condition in iscsit_add_reject_from_cmd() alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 35/59] powerpc/ipic: Fix status get and status clear alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 39/59] target:fix condition return in core_pr_dump_initiator_port() alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 41/59] arm-ccn: perf: Prevent module unload while PMU is in use alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 38/59] iscsi-target: fix memory leak in lio_target_tiqn_addtpg() alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 40/59] target/file: Do not return error for UNMAP if length is zero alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 44/59] ppp: Destroy the mutex when cleanup alexander.levin
2017-12-07 15:51 ` alexander.levin [this message]
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 42/59] mm: Handle 0 flags in _calc_vm_trans() macro alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 43/59] clk: tegra: Fix cclk_lp divisor register alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 46/59] GFS2: Take inode off order_write list when setting jdata flag alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 47/59] bcache: explicitly destroy mutex while exiting alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 51/59] tty fix oops when rmmod 8250 alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 49/59] xfs: fix log block underflow during recovery cycle verification alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 50/59] PCI: Detach driver before procfs & sysfs teardown on device remove alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 52/59] pinctrl: adi2: Fix Kconfig build problem alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 56/59] scsi: bfa: integer overflow in debugfs alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 53/59] raid5: Set R5_Expanded on parity devices as well as data alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 54/59] scsi: scsi_devinfo: Add REPORTLUN2 to EMC SYMMETRIX blacklist entry alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 55/59] ASoC: samsung: i2s: disable secondary DAI until it gets fixed alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 59/59] ath9k: fix tx99 potential info leak alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 58/59] macvlan: Only deliver one copy of the frame to the macvlan interface alexander.levin
2017-12-07 15:51 ` [PATCH AUTOSEL for 3.18 57/59] udf: Avoid overflow when session starts at large offset alexander.levin
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=20171207155116.6013-45-alexander.levin@verizon.com \
--to=alexander.levin@verizon.com \
--cc=daniel.lezcano@linaro.org \
--cc=edubezval@gmail.com \
--cc=j-keerthy@ti.com \
--cc=john.stultz@linaro.org \
--cc=leo.yan@linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
/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
all inboxes | Powered by JetHome®