https://ounapuu.ee/posts/2022/09/26/minimum-viable-fan-control-script/ ./techtipsy * About * Posts * The Archive * About * Posts * The Archive RSS The minimum viable fan control script 2022-09-26 -- 6 min read I've always been a fan of tinkering with cooling setups on my computers. I've even went as far as writing crappy solutions to make up for deficiencies on the hardware level. After years of dumb experiments I've seen how little you can get away with in cooling and how to run your machines as quietly as possible without giving up too much performance. I also appreciate simplicity, which is why I'm currently running the simplest damn solution you can imagine to control how my ThinkPad T430 and ASRock DeskMini X300 run: a shell script. It also comes with some added benefits: * self-documenting * highly customizable * low resource usage These scripts are not "battle-hardened" and using them incorrectly may or may not result in hardware failure. Use at your own risk. The only guarantee I can give is that it works on my machine(tm). If you're someone who doesn't like tinkering with their computers and wants their machines to "just work", then this article likely isn't for you. [image] ThinkPad T430 With the ThinkPad T430, the script does two things: * control the fan speed * preemptively throttle the CPU and GPU This type of behaviour is optimized for mostly quiet operation. The fan is running at its lowest speed when under a small load, and the CPU/GPU throttling has an added benefit of reducing the overall power usage, too. The difference between non-turbo and turbo speeds on the Intel i7-3820QM can be as much as 13-15 watts. To enable fan control on ThinkPads, you need to have a file at /usr/ lib/modprobe.d/thinkpad_acpi.conf with the following contents: options thinkpad_acpi fan_control=1 Reboot, and you can now have full control over the fan speed in your ThinkPad! The script itself looks like this: #!/bin/bash set -e while true; do temp=$(cat /sys/class/thermal/thermal_zone1/temp) if ((temp > 90000)); then echo level 7 >/proc/acpi/ibm/fan elif ((temp > 75000)); then echo level 5 >/proc/acpi/ibm/fan elif ((temp > 60000)); then echo level 3 >/proc/acpi/ibm/fan elif ((temp > 30000)); then echo level 1 >/proc/acpi/ibm/fan else echo level 0 >/proc/acpi/ibm/fan fi if ((temp > 97000)); then echo 350 >/sys/class/drm/card*/gt_max_freq_mhz echo 350 >/sys/class/drm/card*/gt_boost_freq_mhz elif ((temp > 90000)); then echo 650 >/sys/class/drm/card*/gt_max_freq_mhz echo 650 >/sys/class/drm/card*/gt_boost_freq_mhz else echo 1250 >/sys/class/drm/card*/gt_max_freq_mhz echo 1250 >/sys/class/drm/card*/gt_boost_freq_mhz fi if ((temp > 70000)); then echo 1 >/sys/devices/system/cpu/intel_pstate/no_turbo else echo 0 >/sys/devices/system/cpu/intel_pstate/no_turbo fi sleep 0.5 done What we're doing is reading the temperature of the CPU package and then setting the fan speed and throttling based on that. Note that the temperatures are represented without any decimal places. A reading of 78000 means that the chip is running at 78 degC. On my ThinkPad T430, the fan speed levels can be roughly described as such: * level 1: lowest speed, barely audible * level 3: audible, but tolerable * level 5 and above: it's probably loud enough to bother you The second section controls the integrated GPU. What I've found in my testing is that a weak integrated GPU can still chug up to 20 watts, which is a considerable amount, especially on a laptop. The card* wildcard is there because the integrated GPU may change between card0 and card1, and I'm too lazy to make the script any smarter. The values written there correspond to the maximum GPU clock speed. 1250 happens to be the max clock speed (in MHz) and at that speed the GPU is using a lot of power. 650 is the speed at which the integrated GPU is running most efficiently. 350 is the lowest speed, and you will notice it due to the performance being extra crappy. With the CPU, I chose to just turn the turbo boost on or off. With turbo boost off, the CPU will top out at 2.7 GHz and around 22 watts of power usage. With turbo boost, the CPU can run anywhere between 3.4-3.7 GHz, depending on the number of cores under load. You'll likely notice much higher CPU temperatures and power usage climbing to around 35 watts. Fast at short and bursty workloads, and yet efficient and relatively cool at sustained loads. And at the very end, you have a simple sleep statement. I've set it to half a second, but feel free to set it as you see fit. Higher intervals might not be that good of an idea because the script may not be able to respond quickly enough to changing thermals, just keep that in mind. ASRock DeskMini X300 Although I've opted for a more experimental setup with my home server and the ASRock DeskMini X300 is no longer running as one, I think it's still worthwhile to share how I configured the fan control logic on this machine. With the ASRock DeskMini X300, my goal was simple: let it run as quietly as reasonably possible without losing too much performance. This machine was running 24/7 as a server and has a powerful 8-core AMD Ryzen 7 5700G CPU in it. One thing this script is heavily relying on is the fact that Ryzen CPU-s have well-engineered boosting logic in them, meaning that they're already designed to run at the highest speed possible and only limit their speed if they hit power or thermal limits. One thing you may need to do first is installing lm-sensors and running sudo sensors-detect. By default the CPU fan speed controls were not properly exposed, but after running sensors-detect and saying yes at every prompt, they were picked up. The script looks like this: #!/bin/bash set -e # /sys/devices/platform/nct6775.656/hwmon/hwmon3 echo 1 >/sys/devices/platform/nct6775.656/hwmon/hwmon3/pwm2_enable while true; do temp=$(cat /sys/class/hwmon/hwmon4/temp1_input) if ((temp > 94000)); then echo 170 >/sys/devices/platform/nct6775.656/hwmon/hwmon3/pwm2 elif ((temp > 90000)); then echo 140 >/sys/devices/platform/nct6775.656/hwmon/hwmon3/pwm2 elif ((temp > 70000)); then echo 120 >/sys/devices/platform/nct6775.656/hwmon/hwmon3/pwm2 elif ((temp > 40000)); then echo 30 >/sys/devices/platform/nct6775.656/hwmon/hwmon3/pwm2 else echo 0 >/sys/devices/platform/nct6775.656/hwmon/hwmon3/pwm2 fi sleep 5 done The hwmon values and which fan you're controlling is likely different on your own PC. Take a look at the paths found in the script and poke around while also physically looking at your PC. Try enabling PWM control by writing to pwm*_enable handles and then setting the fan speed. As a result of your poking, you should see the CPU fan change its speed. If it doesn't, try another value. The values you can write are in the range 0-255, where the higher value corresponds to a higher speed. I've limited the TDP of my CPU to 35 watts using a setting found in UEFI settings. This results in the CPU running cool and quiet even under a full load. systemd service To run your fan control script as a systemd service, drop the script to your preferred location (I placed it in /root/.local/bin/ fancontrol), then create a file /etc/systemd/system/ fancontrol.service with the following contents: [Unit] Description=Quick fan control software [Service] ExecStart=/root/.local/bin/fancontrol [Install] WantedBy=multi-user.target And once that is done, enable and start your fan control service with sudo systemctl enable --now fancontrol.service. If you encounter issues or something isn't working right, check the status of the service with systemctl status fancontrol.service or full logs with journalctl -u fancontrol.service. Conclusion If you want something that works out of the box and does the smart stuff for you, then give this Arch Linux wiki page a look. If you're not into that and want to easily tune the behaviour of your machine, then feel free to use these scripts as a baseline for your own experimentation. Comments If you prefer to share your thoughts on this post privately, just send me an e-mail! Places where you can discuss this post: * Hacker News * Level1Techs forum * LinkedIn * Reddit Other things I've written --------------------------------------------------------------------- DIY cloud gaming: NVIDIA and Moonlight How to make digital copies of your old video tapes Things I've learned during my self-hosting adventure How I treat my urge to hoard data btrbk is awesome ./techtipsy (c) 2022 Powered by Hugo Theme created by panr, tweaked by me.