Thread (1 message) 1 message, 1 author, 2017-07-21

Under some conditions i.MX temperature is not read out from on-SOC temperature sensor

From: p.zabel@pengutronix.de (Philipp Zabel)
Date: 2017-07-21 10:30:47

Hi Maxim,

thank you for the patch and the analysis. I have some comments below.

On Fri, 2017-07-21 at 12:30 +0300, Maxim Yu. Osipov wrote:
Hello, Shawn, Sascha,

We use yocto (with mainline kernel 4.4.18) for our i.MX 6SOLO-based 
custom board. We use in-kernel thermal management framework with
default thermal governor (step_wise) (drivers/thermal/imx-thermal.c) 
with defined trip points:

imx_thermal 2000000.aips-bus:tempmon: Commercial CPU temperature grade - 
max:95C critical:90C passive:85C

We heat up the board in climate chamber until temperature reaches 
critical value (90C) and in-kernel thermal management powers it off. 
After short period of time (when temperature is in range 
passive(85C)...critical(90C), we power up the board again so the alarm 
condition is met and imx_thermal interrupt fires up. When we try to read 
out the temperature from corresponding sysfs file we permanently get the 
error -EAGAIN:

root at mybox:/usr/lib/strace/ptest# ./strace cat 
/sys/class/thermal/thermal_zone0/temp
...
open("/sys/class/thermal/thermal_zone0/temp", O_RDONLY|O_LARGEFILE) = 3
sendfile64(1, 3, NULL, 16777216)        = -1 EAGAIN (Resource 
temporarily unavailable)
read(3, 0x7ee5bc00, 4096)               = -1 EAGAIN (Resource 
temporarily unavailable)
brk(NULL)                               = 0x1ad9000
brk(0x1afa000)                          = 0x1afa000
write(2, "cat: read error: Resource tempor"..., 50cat: read error: 
Resource temporarily unavailable

root at mybox:~# cat /proc/interrupts
      CPU0        <snip>
      271:          2       GPC  49 Level     imx_thermal
      <snip>

There are a couple of workarounds to enforce the temperature file to be 
readable. If we explicitly enable the thermal's mode via sysfs (echo 
enabled > /sys/sys/class/therma/thermal_zone0/mode) the temperature file 
becomes readable. The same applies to suspend/resume cycles - after 
resume the temperature file is readable.


Having analyzed/debugged the code (for both mainline and freescale's 
trees) I figured out the reason of the problem:

In imx_thermal_probe() thermal alarm interrupt is enabled before 
device's 'mode' field is set to THERMAL_DEVICE_ENABLED while the sensor 
hardware is already powered up. If alarm condition is met -
the interrupt immediately fires up. During (threaded) interrupt 
processing imx_get_temp() is called. The field 'mode' is still set to 
DISABLED, so imx_get_temp() processes such case by special way: sensor 
is powered up,
measurement is enabled, a reading is taken, after that measurement is 
DISABLED and temperature sensor is POWERED DOWN.
When processing of alarm interrupt ends, imx_thermal_probe() continues 
and sets mode field to ENABLED, but in fact the device is powered off!

This leads to broken logic of further calls of imx_get_temp().

The consequences of this bug could be quite serious - the temperature is 
not read out from the sensor, so in-kernel thermal management is useless 
- the board is not powered off by thermal management when the CPU is 
overheated.


Attached is patch against current mainline kernel tree.
It would be preferable to have the patch sent inline. That way it would
be easier to comment on specifics. Also, as a thermal patch, this should
be sent to linux-pm at vger.kernel.org. The scripts/get_maintainers.pl
script in the kernel sources can help to find the relevant maintainers
and mailing lists.

I think the data->irq_enabled assignment should be moved up before the
call to devm_request_threaded_irq as well. If the interrupt triggers
immediately (and sets data->irq_enabled=false), and then
imx_thermal_probe returns (after setting data->irq_enabled=true) before
the threaded irq handler gets to run, imx_get_temp will not reenable the
interrupt at the end, if the temperature has just fallen below the alarm
temperature.

Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>

best regards
Philipp
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help