Meifand: control fan speeds on Intel AMT/ME mobos with Linux

I happened to buy an Intel DH57JG motherboard for a project, only to discover it is not possible to control the fans using the normal lm-sensors/fancontrol method. To make a long story short, the fans sit behind the Management Engine, which is part of Intel’s Active Management Technology. There exists some Linux support for the ME in the form of the MEI (/dev/mei), but no tools for doing anything with it. Some of the acronyms involved are:

A probable indicator that you might have the same problem is that you have a mobo with an Intel chipset and running sensors after sensors-detect reports 0 RPM for all fans. Likewise, pwmconfig will not find any fan controllers.

So, what to do? The CPU fan runs too slow, so the cores reach temperatures up to 90°C, which is way beyond the recommended Tjunction in the long run. On the other hand, the case fan runs too fast for my taste. There is some example code available here (Gigaplex’s patched version for new kernels), but that’s still far from an end-user solution.

Getting the examples to compile and run gave at least some hope that something could be done: at least the interface worked and read realistic values from the sensors. With a few hours of tweaking I found a way to set the duty cycles for fan controllers, after which it was no biggie to write a simple daemon that adjusts them according to the CPU temperature. All looked good until I discovered how unreliable either ME or its Linux kernel support is and had to spend many hours more trying to work around the problems.

After several days of fiddling and testing I’m (somewhat) proud to present meifand, which may or may not remedy your similar situation. I won’t accept complaints if you happen to fry your mobo/CPU with it.

Installation

Meifand requires some compiling and tweaking according to your particular system, so consider it more of an experiment rather than a turnkey solution. To get it installed follow these steps:

  1. Make sure you can read core temperatures by running sensors. Usually ok by default these days.
  2. Check that mei and mei_me modules are loaded (lsmod | grep mei).
  3. Download Gigaplex’s version of the QST SDK.
  4. Compile and install the libraries – the example programs won’t compile straight away, but they’re not needed either. In case you want to fix them, move the library linking parameters, such as “-lQstComm” to the end of the gcc command line in the Makefiles.
  5. On 64-bit systems it’s useless to create anything under /usr/lib64, so in src/libraries/Linux/makefile it’s probably a good idea to change LIBDIR to /usr/lib
  6. Unpack meifand, make and sudo make install. Add -DDEBUG to the Makefile if you want to experiment a bit.
  7. Add to /etc/rc.local the following line: /usr/local/bin/meifan_watchdog.sh &
  8. It seems recently there’s no /dev/mei even if the libs expect that 🙁 As a quick fix precede the previous line in /usr/rc.local with this: ln -s /dev/mei0 /dev/mei

The meifan_watchdog.sh script starts meifand and keeps it alive when needed.

Configuration

The default values are probably off for your setup, so some tweaks are needed. Run as root meifand –detect to show your core temperature sensors and fan controllers. The settings reside in /etc/meifand.conf and contain three kinds of items – better be careful with whitespace, as the parser is not too forgiving.

  1. interval. Simply the number of seconds between polling the temperatures.
  2. sensor. Add on separate lines all temperature sensors you want to involve in fan speed setting. The highest temperature will be used for the calculations.
  3. fan. Fan (controller). Contains the fan number as shown by –detect, whether it should be dynamic (likely a CPU fan) or run at constant speed (likely a case fan). For a constant speed fan specify the wanted duty cycle, and for a dynamic one the minimum and maximum temperatures followed by the corresponding duty cycles.

Duty cycles range from 0 to 100 and their values depend on your particular setup. In practice zero is not the minimum speed (e.g. values less than 40 might provide exactly the same results). You’ll find the optimal values only by experimenting and making compromises between noise and heat.

If the core temperature is less than the minimum you specified, the fan will run at the constant minimum speed. Likewise, if it’s hotter than the maximum, the fan will run at the given maximum speed. Between the extremes meifand will scale the duty cycles linearly according to the temperature.

Usage

In general you shouldn’t need to worry about the background processes. When trying to find the optimal values you can edit meifand.conf and do a killall meifand – the watchdog will restart it soon again. Maybe one day I’ll make it possible to reload the config a bit more conveniently. To return back to automatic fan control, try this as root: killall meifan_watchdog.sh && killall meifand