2133 words
11 minutes
A temporary solution to rattling fan noise of Dell XPS 13 7390 in Arch Linux

To be clear

  1. This is for Arch Linux. No idea about Windows.
  2. It only works if the noise comes from a loosened or shaking fan.
  3. It works when only one fan has this problem. If both fans are making the same noise, it’s hopeless. Just get a replacement.
  4. It’s a temporary solution. And the system temperature will be higher than usual because we’ll lose some cooling capability.

Disclaimer: See point 4 above. If you follow my solution and the CPU is eventually burnt down, I’m not going to be responsible for that.

Updates: I finally replaced the fan. See this blog.

Just murmuring…#

The pandemic is giving most people a hard time, including me, which is surprising to me. I used to work from home a lot. After all, I only need stable internet to work, and I’m a perfect homebody. So I never thought I would one day be unhappy about working from home for an extended period.

My unhappiness comes from my newly purchased XPS 13 7390. It started making a very annoying noise. That noise really drove me crazy before I fixed it. And this is a new laptop. So even though the noise is now gone, I’m still kind of sad that I had to open the back panel when it is just 5 months old. I think opening the back panel voids the warranty.

XPS 13 7390 is a fantastic machine, except for the fan quality. Though it might also be because I attached this XPS 13 to a 27” 4K monitor and never shut it down since mid-March. The fan axle, or somewhere around it, had worn down. I guess an ultrabook is not supposed to be used as a desktop. A bit disappointing.

My other laptop (Lenovo W540) has been up and running as a server since 2014 without a single problem. (I had to replace the thermal paste last year, but that counts as maintenance.)

I. Symptom#

Rattling noise coming from the fans. Note that the fans also create an airflow noise. The airflow noise is normal and is fine. Here’s a video showing the rattling noise. Not sure if headphones are required to hear that.

https://youtu.be/fclAuJWgcEo

II. Diagnosis#

After removing the back panel, we can check the condition of the fans. In the following video, we can see one fan making a “click click click” sound when I tap it, while the other one does not. (You may need headphones/earphones to hear the sound.) This is the one making the rattling noise.

https://youtu.be/6is85RMe1m4

I’m not sure what really happened to this fan. But I’ll just call it a loosened fan because it sounds like something is loose. I have to admit I’m kind of disappointed in Dell’s quality control. The greatness of the XPS 13 is undermined by this little plastic fan.

III. A permanent solution#

The fan should be replaced. The part number can be found on the surface of the cooling assembly. Unfortunately, I couldn’t find a replacement in the market. (Well, I did find two sellers on eBay. But the shipments would take more than 40 days.)

My XPS 13 7390 uses a combined fan-heatpipe assembly. In other words, the fan module and the heatpipe cannot be detached from each other. But currently, most available cooling modules on the market are for previous generations, such as 9380 and 9370. These earlier generations use separate fans and heatpipes. I’m not sure whether those fan and heatpipe modules can replace the fan-heatpipe assembly in my XPS 13. The pictures look alike, though. I just haven’t tried them yet, and I haven’t purchased them either.

IV. A temporary solution#

A temporary solution is to delay the point at which the loosened fan kicks in. By default, both fans have the same speed profile. But we can actually control them separately in Linux.

The basic idea is to rely on the normal fan to cool the system for most temperature ranges. The loosened fan only kicks in when the temperature is close to a critical value. This will, of course, keep the system at a higher temperature than usual. But the CPU is designed to tolerate temperatures up to 100ºC (supposedly…). So it should be fine, hopefully, to let it stay at something like 50ºC when idle or under light workloads.

Step 1: i8kutils-git#

i8kutils provides utilities to monitor and control the fans in Dell laptops. The i8kutils package in AUR, however, has outdated code and is buggy (for example, it doesn’t handle more than 4 stages). So here we need to use the version on GitHub. Fortunately, i8kutils-git can also be found in AUR.

The package provides a kernel module, dell_smm_hwmon. This module has trouble being loaded for recent generations of XPS. To force the kernel to automatically load dell_smm_hwmon during startup, we have to add an option ignore_dmi=1. Here’s what I have in /etc/modprobe.d/dell-smm-hwmon.conf:

Content in /etc/modprobe.d/dell-smm-hwmon

Terminal window
$ cat /etc/modprobe.d/dell-smm-hwmon.conf
-----------------------------------------------------------------------
# This file must be at /etc/modprobe.d/
options dell-smm-hwmon restricted=0 ignore_dmi=1

Or, if you want to manually load the module without rebooting, use # modprobe dell_smm_hwmon ignore_dmi=1. For loading and checking the status of kernel modules, please see the article on kernel modules in ArchWiki.

Next, enable the i8kmon daemon with # systemctl enable i8kmon.service. If you don’t want to reboot later, you also need to start the daemon. i8kmon is a daemon provided by i8kutils to monitor temperatures and then adjust fan speeds according to the configured profiles. We haven’t configured the fan profile yet, so i8kmon is not ready to work. We need to wait until the next step is done. i8kutils also provides i8kctl and i8kfan to manually control the fans, but they will also only work after the next step is done.

Step 2: dell-bios-fan-control-git#

The package dell-bios-fan-control-git provides a tool called dell-bios-fan-control and can be found in AUR. For recent XPS 13 models, the fans are controlled by the BIOS by default. So in order for i8kmon to control the fans, we need to transfer that control from the BIOS to ourselves. This is what dell-bios-fan-control does. After installing dell-bios-fan-control-git, enable the daemon with # systemctl enable dell-bios-fan-control.service. And if you don’t want to reboot, start the daemon too.

Step 3: testing if manual control is working#

We haven’t configured the profiles yet. Before that, we may want to see if the two packages above are working. Let’s try to control the fan manually. Follow the instructions in lm_sensors’ wiki page, and check whether you can see the current fan speeds in the output of the sensors command. Here’s an example showing the speeds of the two fans in my XPS 13 7390:

Report from lm_sensors

Terminal window
$ sensors
------------------------------------------------------------------------
coretemp-isa-0000
Adapter: ISA adapter
Package id 0: +75.0°C (high = +100.0°C, crit = +100.0°C)
Core 0: +71.0°C (high = +100.0°C, crit = +100.0°C)
Core 1: +70.0°C (high = +100.0°C, crit = +100.0°C)
Core 2: +70.0°C (high = +100.0°C, crit = +100.0°C)
Core 3: +72.0°C (high = +100.0°C, crit = +100.0°C)
Core 4: +75.0°C (high = +100.0°C, crit = +100.0°C)
Core 5: +69.0°C (high = +100.0°C, crit = +100.0°C)
nvme-pci-7100
Adapter: PCI adapter
Composite: +44.9°C (low = -0.1°C, high = +81.8°C)
(crit = +85.8°C)
iwlwifi_1-virtual-0
Adapter: Virtual device
temp1: +49.0°C
BAT0-acpi-0
Adapter: ACPI interface
in0: 8.51 V
curr1: N/A
dell_smm-virtual-0
Adapter: Virtual device
fan1: 7349 RPM
fan2: 7072 RPM

If you haven’t rebooted yet, or if you haven’t loaded/started the kernel module and systemd services, you may want to do so now. Next, use i8kfan to change the fan speeds and see whether it is working.

In fact, we are not controlling the real speeds of the fans directly. We are controlling the modes. These fans have three modes: 0, 1, and 2. Mode 0 means no motion, i.e., 0 RPM. Mode 1 makes the fans rotate at around 4500 RPM. Mode 2 makes the fans rotate at the highest speed, around 7500 RPM. The usage of i8kfan is $ i8kfan <mode for fan 1> <mode for fan 2>. For example, $ i8kfan 2 2 makes both fans rotate at around 7500 RPM.

You can check the speeds again with the sensors command. Another command to check the speeds is i8kctl. Now try different mode combinations for the two fans and identify which fan is making the rattling noise. In my case, fan1 is the one. Note that the fan id (fan1 or fan2) may be different between lm_sensors and i8kutils. So you need to use i8kfan to determine which id is the rattling fan in i8kutils.

Step 4: setting up the fan speed profile#

Now we can set up the profile. The fan profile can be set in either /etc/i8kutils/i8kmon.conf or ${HOME}/.i8kmon. But by default, the i8kmon.service shipped with the Arch Linux package ignores ${HOME}/.i8kmon. So if you want to use ${HOME}/.i8kmon, you’ll have to create your own systemd service. Let’s just use /etc/i8kutils/i8kmon.conf. Here’s what I have:

Terminal window
cat /etc/i8kutils/i8kmon.conf
------------------------------------------------------------------------
# i8kmon configuration file for Dell XPS 13 7390 with one fan rattling
# Requires the version on GitHub. In Arch, install i8kutils-git
# External program to control the fans
set config(i8kfan) /usr/bin/i8kfan
# Report status on stdout, override with --verbose option
set config(verbose) 0
# Status check timeout (seconds), override with --timeout option
set config(timeout) 1
# Temperature threshold at which the temperature is displayed in red
set config(t_high) 90
# Number of temperature configurations
set config(num_configs) 5
# Temperature thresholds: {fan_speeds low_ac high_ac low_batt high_batt}
set config(0) {{0 0} -1 40 -1 40}
set config(1) {{0 1} 35 55 35 55}
set config(2) {{0 2} 50 75 50 75}
set config(3) {{1 2} 70 80 70 80}
set config(4) {{2 2} 75 128 75 128}

set config(num_configs) 5 means we have 5 stages in our speed profile. The most important part is the lines with the following pattern: set config(<stage_id>) {{<fan1_mode> <fan2_mode>} <low_temp_ac> <high_temp_ac> <low_temp_bat> <high_temp_bat>}.

<stage_id> speaks for itself. <fan1_mode> and <fan2_mode> are the fan modes (0, 1, or 2) at this stage. <low_temp_ac> means that when:

  1. we’re using AC power, and
  2. the temperature is decreasing,

once the temperature reaches this value, the fans will go back to the previous stage (the stage with the <stage_id> that is one smaller). <low_temp_bat> is the same except it applies when using battery power. <high_temp_ac> and <high_temp_bat>, on the other hand, mean that when the temperature is increasing, the fan speed will move to the next stage when reaching that temperature value.

In my profile, I don’t use different profiles for AC power and battery power. My profile says that when the temperature is increasing:

  1. at 40 ºC, fan2 kicks in but with medium speed;
  2. at 55 ºC, fan2 starts to rotate at the highest speed, but fan1 is still unmoving;
  3. at 75 ºC, fan1 finally starts to work, though with medium speed (while fan2 still running at the highest speed); and
  4. at 80 ºC, fan1 starts to rotate at the highest speed.

When the temperature is decreasing:

  1. at 75ºC, fan1 lowers the speed to the medium speed;
  2. at 70ºC, fan1 stops working, and only fan2 continues to work;
  3. at 50ºC, fan2 slows down; and
  4. at 35ºC, fan2 also stops working.

With this profile, if the laptop is not under a heavy workload, then most of the time only the normal fan is working. The rattling fan only starts working when the temperature is high. After setting up the profile, remember to restart the i8kmon.service daemon, or simply reboot.

Step 5: relax the CPU frequency restriction at high temperature: throttled#

The last step is recommended but not required.

The CPU is designed to withstand temperatures up to 100ºC. But if we allow the CPU to reach 100ºC, the machine will automatically shut down for protection, and we will lose all data before the shutdown. The Linux kernel therefore reduces a CPU core’s frequency at around 80ºC, so that the machine never really reaches 100ºC.

But now, because we are using only one fan most of the time, the temperature is usually high. For example, in my case, the temperature is usually around 70ºC when watching YouTube and doing a video call at the same time. It’s easy to reach 80ºC if I’m also doing something else in that situation. The Linux kernel would start to limit the CPU frequencies soon because of the 80ºC threshold.

To change this threshold temperature, we need to install throttled. throttled can be found in the official Arch Linux repository. After installation, enable lenovo_fix.service with # systemctl enable lenovo_fix.service. If you don’t want to reboot, don’t forget to start the daemon too. And I don’t know why the service is named Lenovo.

throttled’s default configuration changes the 80ºC threshold to 95ºC. This means the Linux kernel should not limit the CPU frequency until reaching 95ºC. So now, even though my machine may stay around 70-ish ºC and sometimes spike to 80-ish ºC, the CPU can still run at a normal frequency. If you don’t like 95ºC and want another threshold value, you’ll have to check throttled’s manual.

V. Finally …#

The best solution is still to get a brand new replacement, of course. If anyone reads this post and knows where to get one, please tell me. Thanks.

Written content, images, and videos in this post are licensed under CC BY-NC-SA 4.0 . Code snippets are licensed separately under BSD 3-Clause .