Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save krlvi/c1bbb462c214242cae8c5a7c75db0173 to your computer and use it in GitHub Desktop.
Save krlvi/c1bbb462c214242cae8c5a7c75db0173 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment