MacPro 1,1 : Optimiser le refroidissement d’un GPU AMD sous Linux

Sur ces machines, la ventilation est réalisée en 3 canaux séparés

  • Canal 1 : CPU & RAM : 2 ventilateurs, 1 en façade et 1 à l’arrière en extraction, dont la vitesse est régulée en fonction de la température CPU
  • Canal 2 : GPU et cartes d’extensions : 1 ventilateur en façade
  • Canal 3 : Alimentation & lecteurs optiques.

Sur mon système, si les canaux 1 et 3 sont gérés correctement par le SMC ( le chip chargé de la gestion du système ), le ventilateur du canal 2 a sa vitesse fixe à 500 tr/min. J’imagine que la cause est à trouver dans mon utilisation peut habituelle de cette machine : un GPU non officiel (AMD R9 380) sous un OS non officiel (Linux).

Pour pallier à ce problème, et effectivement piloter ce ventilateur en fonction de la demande en refroidissement du GPU, j’ai écrit un script bash, qui contrôle ce ventilateur en fonction de la commande PWM du ventilateur du GPU ( attention, à ma connaissance cette information n’est disponible que sur le pilote graphique libre AMD ) :

$ cat /opt/IO_fan_control.sh
#!/bin/bash

BASE_FAN="/sys/devices/platform/applesmc.768/fan2"
GPU_PWM_FILE="/sys/class/drm/card0/device/hwmon/hwmon0/pwm1"
GPU_PWM_MIN=75
GPU_PWM_MAX=250

function setfancontrolmanual()
{
        echo $1 > $BASE_FAN"_manual"
        if (( $? == 0 ))
        then
                if (( $1 == 0 ))
        then
                        echo "Returning fan control to SMC"
                else
                        echo "Taking control of fan from SMC"
                fi
        else
                if (( $1 == 0 ))
        then
                        echo "Failed to return fan control to SMC"
                        exit 1
                else
                        echo "Failed to take control of fan from SMC"
                        exit 1
                fi
        fi
}

function abort()
{
        setfancontrolmanual 0
        exit
}

function checkforroot()
{
        if(( $(id -u)  != 0 ));
        then
                echo "Need to be run as root";
                exit
        fi
}

checkforroot
if [ "$1" == "release" ]; then
        setfancontrolmanual 0
        exit
fi

trap abort SIGINT
setfancontrolmanual 1

while true
do
        INPUT_RPM=$(<$BASE_FAN'_input')
        MAX_RPM=$(<$BASE_FAN'_max')
        MIN_RPM=$(<$BASE_FAN'_min')
        GPU_PWM=$(<$GPU_PWM_FILE)

        #compute MAC fan RPM from GPU fan PWM
        if (( $GPU_PWM >= $GPU_PWM_MAX )); then
                TARGET_RPM=$MAX_RPM
        elif (( $GPU_PWM <= $GPU_PWM_MIN )); then
                TARGET_RPM=$MIN_RPM
        else
                TARGET_RPM=$(( ($MAX_RPM - $MIN_RPM) * ( $GPU_PWM - $GPU_PWM_MIN ) / ($GPU_PWM_MAX - $GPU_PWM_MIN) + $MIN_RPM))
        fi

        #clamp value between MIN_RPM and MAX_RPM
        if (( $TARGET_RPM < $MIN_RPM )); then
                OUTPUT_RPM=$MIN_RPM
        elif (( $TARGET_RPM > $MAX_RPM )); then
                OUTPUT_RPM=$MAX_RPM
        else
                OUTPUT_RPM=$TARGET_RPM
        fi

        echo $OUTPUT_RPM > $BASE_FAN'_output'

        echo 'INPUT_RPM: '$INPUT_RPM' MAX_RPM: '$MAX_RPM' MIN_RPM: '$MIN_RPM' GPU_PWM: '$GPU_PWM' TARGET_RPM: '$TARGET_RPM' OUTPUT_RPM: '$OUTPUT_RPM

        sleep 2
done

Les variables GPU_PWM_MIN et GPU_PWM_MAX correspondent respectivement aux 2 valeur PWM à laquelle le ventilateur du canal 2 sera commandé à sa vitesse minimum, et celle où il sera commandé à sa vitesse maximum.

Ce script est exécuté automatiquement au démarrage grâce à systemd

$ cat /etc/systemd/system/system_mac-io-fan-control.service
[Unit]
Description=MacPro IO fan control from GPU temperature
After=systemd-udevd.service

[Service]
ExecStart=/opt/IO_fan_control.sh
Restart=always
StartLimitIntervalSec=10
ExecStopPost=/opt/IO_fan_control.sh release

[Install]
WantedBy=multi-user.target

Il ne reste plus qu’à activer l’unité systemd créé :

$ sudo systemctl enable system_mac-io-fan-control.service
$ sudo systemctl start system_mac-io-fan-control.service

La vitesse du ventilateur du canal 2 est maintenant asservie à celle du GPU, facilitant le refroidissement de ce dernier, et réduisant le niveau sonore de la machine.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.