Stromsparen unter Linux mit Intel P-State

Stromsparen unter Linux ist ja meist eine Wissenschaft für sich. Viele Stromsparmechanismen und Tipps, sowie Tricks werden immer wieder gegeben, andere passen sich mit den Generationen der Geräte auch an. In diesem Fall will ich über eine relativ neue Stromspartechnik namens Intel P-State berichten, dass bei meinem neuen HP Spectre X360 und dem Kernel 4.20.7 standardmäßig zum Einsatz kommt.



Das Notebook ist für Entwickler und Technikaffine ein wichtiger begleiter. Auch Youtuber, Podcaster und Blogger nutzen das Notebook für ihre tägliche mobile Arbeit.
Die Freiheit immer und überall ohne Kabel leistungstarke Hardware für den Videoschnitt zu haben, oder mal schnell einen neuen Text zu schreiben mit einer ordentlichter Tastatur sind wichtige Kriterien dafür.
Aber natürlich muss auch die Akkulaufzeit stimmen. In der Vergangenheit hat sich Linux damit immer etwas schwer getan, da nicht immer alle neuen Stromsparmechanismen dort immer sofort verfügbar waren und weil die Hersteller meist auch mist in ihre Firmware/BIOS/EFI schrieben, die dazu führten dass ihre Stromspartechniken kaputt waren und nicht dem Standard entsprachen. Gefixt haben die Hersteller dies dann nur per Windows Treiber. Leider ist das heutzutage zum Großteil immer noch so.
Linux ist also hier darauf angewiesen diese Quirks zu erkennen und nachzuimplementieren.

Mittlerweile hat auch Intel erkannt, dass es für ihre neuen Ultrastromsparprozessoren Sinn macht evtl. die Steuerung raus aus der reinen Software rein in eine bessere Kooperation von Hardware und Software zu packen.
Aus diesem Grund gibt es auch den Intel P-State Skalierungstreiber für Linux. Dieser bietet im Gegensatz zum alten ACPI Skalierer, nur noch 2 Skalierungsstrategien, Performance & Powersave.

KSysguard zeigt den Takt der Prozessoren mit Performance Skalierungsmethode


Standardmäßig wird zumindest bei mir auf dem Neptune System (Neptune 6 Beta basierend auf Debian Buster) der Performance Skalierer verwendet. Der hat den Vorteil, dass er sehr viel Leistung aus dem Notebook herausholen kann, was man ja auch beim Videoschnitt benötigt.
Der Nachteil ist, dass er zumindest hier aber nicht ordentlich runtertaktet, sondern immer einen hohen Takt an der oberen Grenze. auch wenn nicht viel am Notebook gemacht wird. hält.

Der Trick ist es nun also den Powersave Modus zu benutzen, der auf vernünftigere Werte gesetzt wird und auch deutlich nach unten taktet, wenn nicht viel am Notebook gemacht wird.
Dies kann man mit modernen Tools wie cpupower auch manuell relativ schnell und einfach einstellen.
Dazu reicht der Befehl

sudo cpupower frequency-set -g powersave

Natürlich will man so etwas nicht immer manuell einstellen und hätte gerne diesen stromsparenden Modus standardmäßig im Akkubetrieb aktiv.
Steckt man dann das Stromkabel an, möchte man dann natürlich auch die volle Leistung des Rechners nutzen können und dann wäre es super, wenn der Rechner den Skalierungsmodus in performance ändert.

Gott sei dank sind wir hier bei Linux und so kann man das alles einfach und schnell mittels einiger Konfigurationsdateien auch schnell so einstellen.

Ich habe mich hier von diesem Arch Linux Foren Thread inspiren lassen, der dies für den acpi Skalierer durchführt.

Dazu habe ich mir zuerst dieses power.sh Scrtipt gebastelt, dass mittels upower überprüft ob der Akku gerade aufgeladen wird oder nicht. Je nachdem setzt er dann den entsprechenden Governor (die entsprechende Skalierungsmethode):

#!/usr/bin/bash
STATE=""
BAT="BAT0"
if [[ "$1" == "BAT" || "$1" == "AC" ]]; then
  STATE="$1"
fi
if [[ $STATE == "" ]]; then
  if [[ $(upower -i /org/freedesktop/UPower/devices/battery_$BAT | grep state | grep discharging) == "" ]]; then
    STATE="AC"
  else STATE="BAT"
  fi
fi
echo $STATE
if [[ $STATE == "BAT" ]]; then
  echo "Discharging, set governor to powersave"
  cpupower frequency-set -g powersave
elif [[ $STATE == "AC"  ]]; then
  echo "AC plugged in, set governor to performance"
  cpupower frequency-set -g performance
fi

Angepasst werden muss hier evtl. nur der Name von BAT, der bei meinem Akku BAT0 heißt.
Mittels dieses power.sh scriptes, dass zusätzlich noch mit dem Parametern AC und BAT manuell in einen Skalierungsmodus gezwungen werden kann, habe ich nun Udev und Systemd Service Dateien erstellt, dir mir beim Hochfahren oder dem Abstecken bzw. Anstecken des Stromkabels den entsprechenden Skalierungsmodus setzen.

Das Udev Script, was ich unter /etc/udev/rules.d/powersave.rules angelegt habe, sieht dann so aus:

SUBSYSTEM=="power_supply", ATTR{online}=="1", RUN+="/home/leszek/Downloads/power.sh AC"
SUBSYSTEM=="power_supply", ATTR{online}=="0", RUN+="/home/leszek/Downloads/power.sh BAT"

Der Pfad zum power.sh Script muss man natürlich ggf. anpassen.

Nun sorgt dieses Service File beim Hochfahren des Rechners dazu, dass der richtige Skalierungsmodus verwendet wird:

[Unit]
Description=Sets the CPU governor on boot according to AC mode
Requires=multi-user.target
After=multi-user.target
[Service]
Type=oneshot
RemainAfterExit=no
ExecStart=/home/leszek/Downloads/power.sh
[Install]
WantedBy=multi-user.target
Die Servicedatei habe ich unter /etc/systemd/system/power_management.service angelegt.

Nun kann es aber noch dazu kommen, dass ich das Gerät ja auch manchmal in den Standby bringe und kurz davor den Stromkabel angeschlossen habe, ich dann aber Stunden später den Kabel abstecke und dann das Gerät erst aufwecke. Damit dann die richtige Skalierungsmethode für die CPU Taktung gewählt wird braucht es einen weiteren Systemd Dienst. Dieser root-resume.service getaufte Dienst wird wiederum unter /etc/systemd/system/ angelegt.
[Unit]
Description=Local system resume actions
After=suspend.target
[Service]
Type=simple
ExecStart=/home/leszek/Downloads/power.sh
[Install]
WantedBy=suspend.target
Mit diesen Anpassungen läuft das Notebook nun doppelt so lange und somit genauso wie ich es erhofft habe und ich kann bis etwa 10 Stunden Akkulaufzeit herausholen.