thinkfan control doesn't use the fan full potential when needed

Solution 1:

I used in my Lenovo Thinkpad x220 (this is an updated answer that related to systems with systemd

sudo -i
  • install thinkfan

    apt install thinkfan
    
  • configure kernel module

    echo "options thinkpad_acpi fan_control=1" > /etc/modprobe.d/thinkfan.conf
    
  • reload kernel module

    modprobe thinkpad_acpi
    
  • configure default thinkfan configuration

    sed -i 's|START=no|START=yes|' /etc/default/thinkfan
    sed -i 's|DAEMON_ARGS="-q"|DAEMON_ARGS="-q -b 1 -s 15"|' /etc/default/thinkfan
    
  • Check your sensors

    find /sys/devices -type f -name "temp*_input"
    

and this is the result in my Lenovo Thinkpad x220:

/sys/devices/virtual/hwmon/hwmon0/temp1_input
/sys/devices/platform/coretemp.0/hwmon/hwmon2/temp3_input
/sys/devices/platform/coretemp.0/hwmon/hwmon2/temp1_input
/sys/devices/platform/coretemp.0/hwmon/hwmon2/temp2_input
  • write in /etc/thinkpad.conf based on the results above

    tp_fan /proc/acpi/ibm/fan
    hwmon /sys/devices/virtual/hwmon/hwmon0/temp1_input
    hwmon /sys/devices/platform/coretemp.0/hwmon/hwmon2/temp3_input
    hwmon /sys/devices/platform/coretemp.0/hwmon/hwmon2/temp1_input
    hwmon /sys/devices/platform/coretemp.0/hwmon/hwmon2/temp2_input
    (0,     0,      40)
    (1,     32,     55)
    (2,     54,     66)
    (3,     65,     76)
    (4,     75,     80)
    (5,     78,     85)
    (6,     82,     88)
    (7,     85,     32767)
    
  • Enable the service so it will be started automatically at every boot and drop privileges.

    systemctl enable thinkfan
    exit
    
  • Reboot your notebook

    systemctl enable thinkfan
    
  • After reboot, check the service

    systemctl status thinkfan.service
    

the result will be like this:

● thinkfan.service - simple and lightweight fan control program
   Loaded: loaded (/lib/systemd/system/thinkfan.service; enabled; vendor preset: enabled)
   Active: active (running) since Jum 2016-10-07 20:09:30 WIB; 28min ago
  Process: 2494 ExecStart=/usr/sbin/thinkfan (code=exited, status=0/SUCCESS)
 Main PID: 2496 (thinkfan)
   CGroup: /system.slice/thinkfan.service
           └─2496 /usr/sbin/thinkfan

Okt 07 20:09:30 thinkpad-x220 systemd[1]: Starting simple and lightweight fan control program...
Okt 07 20:09:30 thinkpad-x220 thinkfan[2494]: thinkfan 0.9.1 starting...
Okt 07 20:09:30 thinkpad-x220 thinkfan[2494]: Daemon PID: 2496
Okt 07 20:09:30 thinkpad-x220 systemd[1]: Started simple and lightweight fan control program.

Solution 2:

Try this configuration, it works fine on a Lenovo ThinkPad L512 / L520:

Install thinkfan

sudo apt-get install -y thinkfan

Configure kernel modules

echo "options thinkpad_acpi fan_control=1" > /etc/modprobe.d/thinkpad_acpi.conf

Reload kernel module

modprobe -r thinkpad_acpi && modprobe thinkpad_acpi

Configure thinkfan

sudo sed -i 's|START=no|START=yes|' /etc/default/thinkfan
sudo sed -i 's|DAEMON_ARGS="-q"|DAEMON_ARGS="-q -b 1 -s 15"|' /etc/default/thinkfan

cat <<EOF> /etc/thinkfan.conf
hwmon /sys/devices/virtual/hwmon/hwmon0/temp1_input
(0, 0,  65)
(1, 65, 70)
(2, 70, 75)
(3, 75, 80)
(4, 80, 85)
(5, 85, 90)
(7, 90, 32767)
EOF

Restart thinkfan daemon

/etc/init.d/thinkfan restart

Solution 3:

After some further research this is how I managed to make it work as I wanted.

Custom temperature thresholds - fan speed configuration

I have installed thinkfan from apt (to be honest I cannot remember if it was already installed or not :-S)

To be sure check if you have a process named thinkfan

CLI:

ps -ef | grep thinkfan

and if it is not there install it with

CLI:

sudo apt-get install thinkfan 

It's configuration is situated at /etc/thinkfan.conf

The mapping temperature - speed is defined like in the following snippet :

...
(0, 0, 21)
(1, 20, 22)
(2, 21, 25)
...

Each group defines the following values (level, minTemperature, maxTemperature), another rule is that the groups have to overlap between each other.

The level is defined in as an integer and not a string as I initially thought, like so:

  • 0 - 7 - eight level points from 0 to ~4200RPM
  • 126 - max speed
  • 127 - disengaged ~6900RPM

My configuration in /etc/thinkfan.conf looks now like so :

(0, 0, 21)
(1, 20, 22)
(2, 21, 25)
(3, 24, 28)
(4, 26, 33)
(5, 30, 40)
(6, 36, 49)
(7, 44, 52)
(126, 50, 59)
(127, 57, 100000)

The values for the temperatures ware more or less calculated from the graphs of psensor which showed very clear that I have an inefficient fan, but I think that is normal considering that the laptop is quite old.

Solution 4:

In order to debug the speed of the fan and the temperatures, I use this handy one-liner. It might be helpful.

while true; do echo -e "\n\n\n####################\n$(sensors)\n\n###\n$(uptime)\n###\n$(cat /proc/cpuinfo | grep -i "mhz")\n####################"; sleep 1; done

One would need to have lm-sensors installed and configured.

Let me explain the loop.

This is a while loop and it is running as long as the state is true while true. Since the state does not change inside the loop, it is running basically forever. To get out of the loop you need to cancel it out with ctrl+c on your keyboard.

So while the state is true, do something. In this case, do echo with the parameter -e. Check man echo in order to find out what it does. First I am adding some line breaks \n and just some hash symbols in order to make it visually better to tell apart what you are looking at.

The next thing I want to be echoed out is the result of sensors. When you run sensors in your terminal it returns something - the result. So in bash you can echo out the result of something with wrapping $() around it.

Then again I want to have some separations in order to tell information apart.

Then I want to see what load there is currently on the computer. So I am echo'ing out the result of uptime.

And then again, I want some separations.

In order to see at what speed the cpu is currently running, I am looking into /proc/cpuinfo and greping with -i (checkout man grep for details on that) for mhz since that is the Information I would like to see.

With the ; A am ending the first part of the loop. Because a while loop has no limit on how often it should process things it will run just super fast. So I am adding a sleep -1 to let it pause for a second. I'm also ending this command with a ; and to tell the loop that it can end right there, I am finishing the loop with the done at the end.

I hope this explanation is easy to understand.