Skip to content

Instantly share code, notes, and snippets.

@abn
Last active September 22, 2024 19:19
Show Gist options
  • Save abn/de81ba413f860b00c2db3ee4aa83e035 to your computer and use it in GitHub Desktop.
Save abn/de81ba413f860b00c2db3ee4aa83e035 to your computer and use it in GitHub Desktop.
Fedora thinkfan configuration for Lenovo X1 Carbon (5th Gen)

Thinkfan Configuration Notes

This are notes for configuration thinkfan for Fedora. This configuration procedure was followed on a Lenovo Thinkpad X1 Carbon (5th Gen) running Fedora 25.

Non standard (default) configuration was required for this machine as the default sensors are not available. Eg: /proc/acpi/ibm/thermal does not exist for this model.

An annoted configuration file has been included below. However, there is no guarentee that this will work as-is on every machine.

Installation

dnf -y install thinkfan

Setup and Configuration

Kernel module: coretemp

This step might not be required, but can be performed nonetheless. This is usually required if you cannot fine coretemp listed in your loaded modules. You can check for this with the folllowing;

lsmod | grep coretemp

If not found, execute the following command. You can skip --auto flag if you want to run in interactive mode.

dnf -y install lm_sensors
sensors-detect --auto

Once completed, you have to either restart the machine or load the kernel modules determined by sensors-detect. For the latter, you can execute the following command.

systemctl restart systemd-modules-load

Temprature sensors

Once the module is loaded, you can identify the sensors with the help of find.

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

You should see an output similar to what is shown below.

# find /sys/devices -type f -name 'temp*_input'
/sys/devices/platform/coretemp.0/hwmon/hwmon4/temp2_input
/sys/devices/platform/coretemp.0/hwmon/hwmon4/temp3_input
/sys/devices/platform/coretemp.0/hwmon/hwmon4/temp1_input
/sys/devices/virtual/hwmon/hwmon2/temp1_input
/sys/devices/virtual/hwmon/hwmon0/temp1_input
/sys/devices/virtual/hwmon/hwmon3/temp1_input

Configuring thinkfan.conf

The sensors need to be added to /etc/thinkfan.conf, but prefixed with hwmon. You can append to the config with the following one-liner as root, or manually append it yourself.

find /sys/devices -type f -name 'temp*_input' | xargs -I {} echo "hwmon {}" >> /etc/thinkfan.conf

In order to suppress the warning that it is using the default fan control mechanism, you may also wish to uncomment the following line from the default configuration.

tp_fan /proc/acpi/ibm/fan

Enable thinkfan service

This is pretty self explanatory. We want the thinkfan daemon to start at boot.

systemctl enable thinkfan

If you want to start it immediately you can systemctl start thinkfan.

Configure auto restart of thinkfan service

This is useful since the files in /sys/devices can go away and be recreated under certain conditions (eg: system suspend). This, with the default configuration causes the services to crash and require manual intervention. In order to make this a bit less annoying, we can add a systemd drop-in file to tweak the default service specification. For this you need to add a conf file at /etc/systemd/system/thinkfan.service.d. Execute the following as root.

mkdir -p /etc/systemd/system/thinkfan.service.d
cat > /etc/systemd/system/thinkfan.service.d/10-restart-on-failure.conf << EOF
[Unit]
StartLimitIntervalSec=30
StartLimitBurst=3

[Service]
Restart=on-failure
RestartSec=3
EOF

Once this is done, reload systemd.

systemctl daemon-reload

The drop-in configuration, tells systemd to restart the service on-failure and wait 3 seconds before restarting. The Unit section configuration limits restarts to 3 times every 30 seconds.

Troubleshooting

The configuration methodology of using find to dump all your sensor files from sysfs could, in certain cases be affected by the order in which modules are loaded by the kernel. For example, on my machine the sensors for coretemp and iwlwifi swaps between hwmon3 and hwmon4 when the machine is awakened after being suspended. To make matters worse, this is inconsistent. This causes the thinkfan daemon to crash and keep crashing until the configuration is updated.

To work around this issue, I hacked together the thinkfan-config script. This uses a template embedded in the script to generate and replace the configuration at /etc/thinkfan.conf. Note that this is specific to my system and may not work for other configurations. But you could tweak it based on your needs.

In order to avoid any manual intervention, we can trigger the script before starting the daemon. This can be configured as follows, assuming the thinkfan-config script is installed at /usr/bin/thinkfan-config and set to be an executable.

cat > /etc/systemd/system/thinkfan.service.d/00-generate-config.conf << EOF
[Service]
ExecStartPre=-/usr/bin/thinkfan-config
EOF

References

  • The man page for thinkfan man thinkfan is a good resource.
  • The troubleshooting session at http://thinkwiki.de/Thinkfan is the source for majority of the details above.

Fan Related Bugs

The issues that required the use of thinkfan is listed below. This has been resolved since 4.12.4-1 of the kernel.

######################################################################
# thinkfan 0.7 example config file
# ================================
#
# ATTENTION: There is only very basic sanity checking on the configuration.
# That means you can set your temperature limits as insane as you like. You
# can do anything stupid, e.g. turn off your fan when your CPU reaches 70°C.
#
# That's why this program is called THINKfan: You gotta think for yourself.
#
######################################################################
#
# IBM/Lenovo Thinkpads (thinkpad_acpi, /proc/acpi/ibm)
# ====================================================
#
# IMPORTANT:
#
# To keep your HD from overheating, you have to specify a correction value for
# the sensor that has the HD's temperature. You need to do this because
# thinkfan uses only the highest temperature it can find in the system, and
# that'll most likely never be your HD, as most HDs are already out of spec
# when they reach 55 °C.
# Correction values are applied from left to right in the same order as the
# temperatures are read from the file.
#
# For example:
# tp_thermal /proc/acpi/ibm/thermal (0, 0, 10)
# will add a fixed value of 10 °C the 3rd value read from that file. Check out
# http://www.thinkwiki.org/wiki/Thermal_Sensors to find out how much you may
# want to add to certain temperatures.
# use legacy fan control
tp_fan /proc/acpi/ibm/fan
# disable using sysfs pwm
# pwm_fan /sys/devices/platform/thinkpad_hwmon/pwm1
# coretemp-isa-0000
# Adapter: ISA adapter
# Package id 0: +38.0°C (high = +100.0°C, crit = +100.0°C)
hwmon /sys/devices/platform/coretemp.0/hwmon/hwmon4/temp1_input
# Core 0: +35.0°C (high = +100.0°C, crit = +100.0°C)
hwmon /sys/devices/platform/coretemp.0/hwmon/hwmon4/temp2_input
# Core 1: +34.0°C (high = +100.0°C, crit = +100.0°C)
hwmon /sys/devices/platform/coretemp.0/hwmon/hwmon4/temp3_input
# pch_skylake-virtual-0
hwmon /sys/devices/virtual/hwmon/hwmon2/temp1_input
# acpitz-virtual-0
# subtract fixed 5 °C from this value, otherwise switching between levels
# 1 and would happen quite often
hwmon /sys/devices/virtual/hwmon/hwmon0/temp1_input (-5)
# iwlwifi-virtual-0
hwmon /sys/devices/virtual/hwmon/hwmon3/temp1_input
# Syntax:
# (LEVEL, LOW, HIGH)
# LEVEL is the fan level to use (0-7 with thinkpad_acpi)
# LOW is the temperature at which to step down to the previous level
# HIGH is the temperature at which to step up to the next level
# All numbers are integers.
#
(0, 0, 55)
(1, 48, 60)
(2, 50, 61)
(3, 52, 63)
(4, 56, 65)
(5, 59, 66)
(7, 63, 32767)
#!/usr/bin/env bash
# associative array to map sensors to names
declare -A SENSORS
function map_sensors() {
for d in $(find ${1} -mindepth 1 -maxdepth 1 -type d -name 'hwmon*'); do
SENSORS[$(cat ${d}/name)]=${d/${1}/}
done
}
# map sensors from the following sysfs directories
map_sensors "/sys/devices/platform/coretemp.0/hwmon/"
map_sensors "/sys/devices/virtual/hwmon/"
# generate and replace configuration
cat > /etc/thinkfan.conf << EOF
######################################################################
# WARNING: Do not modify. Generated by ${0}.
######################################################################
#
# IBM/Lenovo Thinkpads (thinkpad_acpi, /proc/acpi/ibm)
# ====================================================
#
# IMPORTANT:
#
# To keep your HD from overheating, you have to specify a correction value for
# the sensor that has the HD's temperature. You need to do this because
# thinkfan uses only the highest temperature it can find in the system, and
# that'll most likely never be your HD, as most HDs are already out of spec
# when they reach 55 °C.
# Correction values are applied from left to right in the same order as the
# temperatures are read from the file.
#
# For example:
# tp_thermal /proc/acpi/ibm/thermal (0, 0, 10)
# will add a fixed value of 10 °C the 3rd value read from that file. Check out
# http://www.thinkwiki.org/wiki/Thermal_Sensors to find out how much you may
# want to add to certain temperatures.
# use legacy fan control
tp_fan /proc/acpi/ibm/fan
# disable using sysfs pwm
# pwm_fan /sys/devices/platform/thinkpad_hwmon/pwm1
# coretemp-isa-0000
# Adapter: ISA adapter
# Package id 0: +38.0°C (high = +100.0°C, crit = +100.0°C)
hwmon /sys/devices/platform/coretemp.0/hwmon/${SENSORS['coretemp']}/temp1_input
# Core 0: +35.0°C (high = +100.0°C, crit = +100.0°C)
hwmon /sys/devices/platform/coretemp.0/hwmon/${SENSORS['coretemp']}/temp2_input
# Core 1: +34.0°C (high = +100.0°C, crit = +100.0°C)
hwmon /sys/devices/platform/coretemp.0/hwmon/${SENSORS['coretemp']}/temp3_input
# pch_skylake-virtual-0
hwmon /sys/devices/virtual/hwmon/${SENSORS['pch_skylake']}/temp1_input
# acpitz-virtual-0
# subtract fixed 5 °C from this value, otherwise switching between levels
# 1 and would happen quite often
hwmon /sys/devices/virtual/hwmon/${SENSORS['acpitz']}/temp1_input (-5)
# iwlwifi-virtual-0
hwmon /sys/devices/virtual/hwmon/${SENSORS['iwlwifi']}/temp1_input
# Syntax:
# (LEVEL, LOW, HIGH)
# LEVEL is the fan level to use (0-7 with thinkpad_acpi)
# LOW is the temperature at which to step down to the previous level
# HIGH is the temperature at which to step up to the next level
# All numbers are integers.
#
(0, 0, 55)
(1, 48, 60)
(2, 50, 61)
(3, 52, 63)
(4, 56, 65)
(5, 59, 66)
(7, 63, 32767)
EOF
@ssardina
Copy link

ssardina commented Jan 7, 2018

Thanks a lot @abn for this guide! I have the same machine and I wonder why there are only two cores reported (Core 0 and Core 1):

[ssardina@Thinkpad-X1 lenovo-x1]$ sensors
coretemp-isa-0000
Adapter: ISA adapter
Package id 0:  +41.0°C  (high = +100.0°C, crit = +100.0°C)
Core 0:        +40.0°C  (high = +100.0°C, crit = +100.0°C)
Core 1:        +41.0°C  (high = +100.0°C, crit = +100.0°C)

The laptop should have 4 cores. But your config files have only two so I suspect you know what is happening here and I am missing something.

Also do you know what "Package id 0:" represents?

Thanks!

@jptissot
Copy link

Thanks for this !

@RK4
Copy link

RK4 commented Feb 18, 2019

Thank you !

@gunar
Copy link

gunar commented Feb 27, 2019

Thank you!

@Tuurlijk
Copy link

Thx!

@theinfinityproject
Copy link

theinfinityproject commented May 28, 2019

Thanks for this first of a lot. I have an issue which i have a hard time to get my head around. When i run systemd-analyze verify thinkfan.service it states:

/etc/systemd/system/thinkfan.service.d/00-generate-config.conf:3: Missing '='.
/etc/systemd/system/thinkfan.service.d/10-restart-on-failure.conf:7: Missing '='.

From what i understand so far it might be an encoding issue but the system locale is UTF8 and the files are encoded in ascii which is a subset of utf8.

@danarellano
Copy link

You are amazing. Thank you!

@monosoul
Copy link

For anyone from 2021, there's an easier way to configure thinkfan nowadays with yaml configuration. Here's a detailed guide how to do that: https://blog.monosoul.dev/2021/10/17/how-to-control-thinkpad-p14s-fan-speed-in-linux/ .

@pglpm
Copy link

pglpm commented Jun 11, 2022

monosoul's guide seems very thorough, but it's difficult to understand what to do for someone who has never touched a thinkfan.conf file before.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment