Die Host-CPU skaliert die Frequenz nicht, wenn der KVM-Gast sie benötigt

8

Beobachtung:
Ich habe einen HP Server mit einer AMD Dual-Core-CPU (Turion II Neo N40L), die Frequenzen von 800 bis 1500 MHz skalieren kann. Die Frequenzskalierung funktioniert unter FreeBSD 9 und unter Ubuntu 12.04 mit dem Linux-Kernel 3.5. Wenn ich FreeBSD 9 jedoch in eine KVM-Umgebung über Ubuntu lege, funktioniert die Frequenzskalierung nicht. Der Gast (also FreeBSD) erkennt die minimalen und maximalen Frequenzen nicht und skaliert daher nichts, wenn die CPU-Belegung höher wird. Auf dem Host (also Ubuntu) verbraucht der KVM-Prozess zwischen 80 und 140% der CPU-Ressource, aber es findet keine Frequenzskalierung statt. Die Frequenz bleibt bei 800 MHz, obwohl der On-Demand-Governor schnell ausgeführt wird, wenn ich einen anderen Prozess auf derselben Ubuntu-Box ausführe skaliert die Frequenz auf 1500 MHz!

Bedenken und Fragen:
Ich verstehe nicht, wie die CPU möglicherweise virtualisiert ist und ob es an dem Gast liegt, die richtige Skalierung durchzuführen. Müssen einige CPU-Funktionen für den Gast verfügbar gemacht werden, damit dies funktioniert?

Anhang:
Der folgende Versionshinweis zu Red Hat deutet darauf hin, dass die Frequenzskalierung auch in einer virtualisierten Umgebung funktioniert (siehe Kapitel 6.2.2 und 6.2.3). In diesem Hinweis wird jedoch nicht darauf eingegangen, mit welcher Virtualisierungstechnologie dies funktioniert (kvm, xen) , usw.?)

Zur Information cpufreq-infolautet die Ausgabe unter Ubuntu:

$ cpufreq-info
cpufrequtils 007: cpufreq-info (C) Dominik Brodowski 2004-2009
Report errors and bugs to [email protected], please.
analyzing CPU 0:
  driver: powernow-k8
  CPUs which run at the same hardware frequency: 0
  CPUs which need to have their frequency coordinated by software: 0
  maximum transition latency: 8.0 us.
  hardware limits: 800 MHz - 1.50 GHz
  available frequency steps: 1.50 GHz, 1.30 GHz, 1000 MHz, 800 MHz
  available cpufreq governors: conservative, ondemand, userspace, powersave, performance
  current policy: frequency should be within 800 MHz and 1.50 GHz.
                  The governor "ondemand" may decide which speed to use
                  within this range.
  current CPU frequency is 800 MHz.
  cpufreq stats: 1.50 GHz:14.79%, 1.30 GHz:1.07%, 1000 MHz:0.71%, 800 MHz:83.43%  (277433)
analyzing CPU 1:
  driver: powernow-k8
  CPUs which run at the same hardware frequency: 1
  CPUs which need to have their frequency coordinated by software: 1
  maximum transition latency: 8.0 us.
  hardware limits: 800 MHz - 1.50 GHz
  available frequency steps: 1.50 GHz, 1.30 GHz, 1000 MHz, 800 MHz
  available cpufreq governors: conservative, ondemand, userspace, powersave, performance
  current policy: frequency should be within 800 MHz and 1.50 GHz.
                  The governor "ondemand" may decide which speed to use
                  within this range.
  current CPU frequency is 800 MHz.
  cpufreq stats: 1.50 GHz:14.56%, 1.30 GHz:1.06%, 1000 MHz:0.79%, 800 MHz:83.59%  (384089)

Der Grund, warum diese Funktion funktionieren soll, ist: Energie sparen, leiser (weniger heiß) laufen und auch einfach neugierig sein, besser zu verstehen, warum dies nicht funktioniert und wie es funktioniert.

Huygens
quelle
1
Dass Microserver nur Windows und RHEL unterstützt, finden Sie in den Quickspecs.
Wenn Sie cpufreq-infoauf dem Host-Betriebssystem ausgeführt werden, wird sich wahrscheinlich beschweren, dass kein Treiber verfügbar ist.
Chris S
Es unterstützt offiziell Windows und RHEL. Ich meine nicht, dass andere Betriebssysteme nicht darauf laufen. Beachten Sie, dass die CPU-Skalierung unter Ubuntu und FreeBSD einwandfrei funktioniert, wenn sie auf dem Bare-Metal-System installiert sind (also nicht durch Virtualisierung). Darüber hinaus funktionieren beide Betriebssysteme bei der Installation auf Bare-Metal-Systemen einwandfrei, es fehlt kein Treiber oder es verhält sich seltsam. Schließlich cpufreq-infobeschwert sich nicht und gibt die richtigen Informationen aus, so dass die CPU voll unterstützt wird (natürlich in gewisser Weise!). Der verwendete Treiber ist powernow-k8, was ebenfalls logisch ist.
Huygens
@ChrisS Ich habe die cpufreq-info-Informationen zur ursprünglichen Frage hinzugefügt.
Huygens
Wenn Sie die Frequenzskalierung nicht wirklich benötigen, können Sie sie jederzeit deaktivieren.
Michael Hampton

Antworten:

10

Ich habe die Lösung dank des Tippes von Nils und eines schönen Artikels gefunden .

Optimieren des On-Demand- CPU-DVFS-Reglers

Der On-Demand-Regler verfügt über eine Reihe von Parametern, die gesteuert werden können, wenn die dynamische Frequenzskalierung (oder DVFS für die dynamische Spannungs- und Frequenzskalierung) ausgelöst wird. Diese Parameter befinden sich unter dem sysfs-Baum:/sys/devices/system/cpu/cpufreq/ondemand/

Einer dieser Parameter ist up_threshold, wie der Name schon sagt, ein Schwellenwert (Einheit ist% der CPU, ich habe jedoch nicht herausgefunden, ob dies pro Kern oder zusammengeführte Kerne ist), oberhalb dessen der On-Demand-Regler einschaltet und beginnt, die Frequenz dynamisch zu ändern.

Es ist einfach, es mit sudo auf 50% (zum Beispiel) zu ändern:
sudo bash -c "echo 50 > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold"

Wenn Sie root sind, ist ein noch einfacherer Befehl möglich:
echo 50 > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold

Hinweis: Diese Änderungen gehen nach dem nächsten Neustart des Hosts verloren. Sie sollten sie einer Konfigurationsdatei hinzufügen, die beim Booten gelesen wird, wie /etc/init.d/rc.localunter Ubuntu.

Ich habe herausgefunden, dass meine Gast-VM, obwohl sie viel CPU (80-140%) auf dem Host verbrauchte, die Last auf beide Kerne verteilte, so dass kein einzelner Kern über 95% lag, daher war die CPU zu meinem Ärger bei 800 MHz bleiben. Mit dem obigen Patch ändert die CPU die Frequenz pro Kern dynamisch viel schneller, was meinen Anforderungen besser entspricht. 50% scheinen ein besserer Schwellenwert für die Nutzung durch meine Gäste zu sein. Ihr Kilometerstand kann variieren.

Überprüfen Sie optional, ob Sie HPET verwenden

Es ist möglich, dass einige anwendbare, die Timer falsch implementieren, von DVFS betroffen sind. Dies kann ein Problem in der Host- und / oder Gastumgebung sein, obwohl der Host über einen komplizierten Algorithmus verfügen kann, um dies zu minimieren. Moderne CPUs verfügen jedoch über neuere TSC (Time Stamp Counter), die unabhängig von der aktuellen CPU- / Kernfrequenz sind. Dies sind: konstant (constant_tsc), invariant (invariant_tsc) oder nonstop (nonstop_tsc). Weitere Informationen finden Sie in diesem Chromium-Artikel zur TSC-Resynchronisation Weitere Informationen zu jedem. Wenn Ihre CPU mit einem dieser TSC ausgestattet ist, müssen Sie HPET nicht erzwingen. Verwenden Sie einen ähnlichen Befehl, um zu überprüfen, ob Ihre Host-CPU sie unterstützt (ändern Sie den grep-Parameter in die entsprechende CPU-Funktion, hier testen wir die konstante TSC):

$ grep constant_tsc /proc/cpuinfo

Wenn Sie keinen dieser modernen TSC haben, sollten Sie entweder:

  1. Aktives HPET, das wird hier nachfolgend beschrieben;
  2. Verwenden Sie CPU DVFS nicht, wenn Sie Anwendungen in der VM haben, die auf einem präzisen Timing basieren, das von Red Hat empfohlen wird .

Eine sichere Lösung besteht darin, HPET-Timer zu aktivieren (siehe unten für weitere Details). Sie sind langsamer abzufragen als TSC-Timer (TSC befinden sich in der CPU, HPET im Motherboard) und haben möglicherweise keine genaue Genauigkeit (HPET> 10 MHz; TSC) oft der maximale CPU-Takt), aber sie sind viel zuverlässiger, insbesondere in einer DVFS-Konfiguration, in der jeder Kern eine andere Frequenz haben könnte. Linux ist klug genug, um den besten verfügbaren Timer zu verwenden. Es wird zuerst auf dem TSC basieren, aber wenn es zu unzuverlässig ist, wird es den HPET verwenden. Dies funktioniert gut auf Hostsystemen (Bare-Metal-Systemen). Da jedoch nicht alle Informationen vom Hypervisor ordnungsgemäß exportiert wurden, ist dies für die Gast-VM eine größere Herausforderung, sich schlecht verhaltende TSC zu erkennen. Der Trick besteht dann darin, die Verwendung von HPET im Gast zu erzwingen, obwohl Sie den Hypervisor benötigen würden, um diese Taktquelle den Gästen zur Verfügung zu stellen!

Im Folgenden finden Sie Informationen zum Konfigurieren und / oder Aktivieren von HPET unter Linux und FreeBSD.

Linux HPET Konfiguration

HPET oder hochpräziser Ereignis-Timer ist ein Hardware-Timer, den Sie seit 2005 auf den meisten Standard-PCs finden. Dieser Timer kann von modernen Betriebssystemen effizient verwendet werden (der Linux-Kernel unterstützt ihn seit 2.6, stabile Unterstützung unter FreeBSD seit dem neuesten 9.x. wurde jedoch in 6.3 ) eingeführt, um ein konsistentes Timing für die CPU-Energieverwaltung bereitzustellen. Es ermöglicht auch das Erstellen einfacher Scheduler-Implementierungen ohne Ticks .

Grundsätzlich ist HPET wie eine Sicherheitsbarriere, die selbst dann, wenn auf dem Host DVFS aktiv ist, die Timing-Ereignisse von Host und Gast weniger beeinflusst.

Es gibt einen guten Artikel von IBM zum Aktivieren von HPET , in dem erläutert wird, wie Sie überprüfen können, welchen Hardware-Timer Ihr Kernel verwendet und welche verfügbar sind. Ich gebe hier eine kurze Zusammenfassung:

Überprüfen der verfügbaren Hardware-Timer:
cat /sys/devices/system/clocksource/clocksource0/available_clocksource

Überprüfen des aktuell aktiven Timers:
cat /sys/devices/system/clocksource/clocksource0/current_clocksource

Eine einfachere Möglichkeit, die Verwendung von HPET zu erzwingen, wenn es verfügbar ist, besteht darin, den Bootloader so zu ändern, dass er nach der Aktivierung fragt (seit Kernel 2.6.16). Diese Konfiguration ist verteilungsabhängig. Informationen zum richtigen Einstellen finden Sie in Ihrer eigenen Verteilungsdokumentation. Sie sollten hpet=enableoder clocksource=hpetin der Kernel-Boot-Zeile aktivieren (dies hängt wiederum von der Kernel-Version oder -Distribution ab, ich habe keine zusammenhängenden Informationen gefunden).
Stellen Sie sicher, dass der Gast den HPET-Timer verwendet.

Hinweis: Auf meinem Kernel 3.5 scheint Linux den HPP-Timer automatisch zu erfassen.

FreeBSD-Gast-HPET-Konfiguration

Auf FreeBSD kann man überprüfen, welche Timer verfügbar sind, indem man Folgendes ausführt:
sysctl kern.timecounter.choice

Der aktuell ausgewählte Timer kann überprüft werden mit:
sysctl kern.timecounter.hardware

FreeBSD 9.1 scheint HPET automatisch anderen Timer-Anbietern vorzuziehen.

Todo: Wie man HPET auf FreeBSD erzwingt.

Hypervisor HPET-Export

KVM scheint HPET automatisch zu exportieren, wenn der Host dies unterstützt. Für Linux-Gäste wird jedoch die andere automatisch exportierte Uhr bevorzugt, nämlich kvm-clock (eine paravirtualisierte Version des Host-TSC). Einige Personen melden Probleme mit der bevorzugten Uhr. Ihr Kilometerstand kann variieren. Wenn Sie HPET im Gast erzwingen möchten, lesen Sie den obigen Abschnitt.

VirtualBox exportiert die HPET-Uhr standardmäßig nicht in den Gast, und es gibt keine Option, dies in der GUI zu tun. Sie müssen die Befehlszeile verwenden und sicherstellen, dass die VM ausgeschaltet ist. Der Befehl lautet:

./VBoxManage modifyvm "VM NAME" --hpet on

Wenn der Gast nach der obigen Änderung weiterhin eine andere Quelle als HPET auswählt, lesen Sie bitte den obigen Abschnitt, wie Sie den Kernel zwingen, die HPET-Uhr als Quelle zu verwenden.

Huygens
quelle
Gibt es dafür eine echte Anwendung oder ist es nur ein einmaliger Trick?
ewwhite
@ewwhite was meinst du mit einem einmaligen Trick? Das Ergebnis ist, dass DVFS (Dynamic Voltage and Frequency Scaling) tatsächlich mit KVM und einem Linux-Host funktioniert. Die Prozess-CPU-Auslastung von 80-140% war wahrscheinlich gleichmäßig auf beide Kerne verteilt, sodass kein Kern den Standardschwellenwert von 95% erreichte, was zu einer Frequenzskalierung führen würde. Wenn ich wirklich einen einzelnen Thread-Prozess erstelle, der 100% eines Kerns in der VM verwendet, wird die Frequenzskalierung ohne Änderung geändert, sodass ich sie einfach nicht gesehen habe. Bei der realen Anwendung von DVFS geht es darum, Energie zu sparen und die Temperatur zu senken.
Huygens
@ewwhite Meinst du "gibt es eine Anwendung, die diesen Wert für mich optimiert?" Ich denke die Antwort ist nein. Sonst hätte schon jemand einen vernünftigen Standard gesetzt. 95 ist hier definitiv nicht sinnvoll.
Michael Hampton
Nein, gibt es eine Anwendung (Grund), die dies in einem virtualisierten Setup verwenden möchte?
ewwhite
Grund: Ich möchte aus mehreren Gründen nicht, dass die CPU mit voller Geschwindigkeit läuft: Der Stromverbrauch ist höher, die Temperatur ist höher, der Verschleiß ist schneller, der Lüfter dreht sich schneller (mehr Leistung und schnellerer Verschleiß), erfordert eine größere USV-Batterie.
Huygens
4

Es ist nicht der Gast, der die Hochskalierung auslöst - der Host muss dies tun. Sie müssen also den entsprechenden Triggerpegel auf dem Host senken.

Nils
quelle
Interessant, würden Sie zufällig wissen, wie das geht?
Huygens
@Huygens Normalerweise erfolgt dies über eine Art cpufrequency-Daemon. Für diesen Dämon gibt es eine Konfigurationsdatei, in der Sie sein Verhalten und die Werte für das Hoch- / Herunterskalieren ändern können. Ich bin mir nicht sicher, wo genau sich das bei Ubuntu befindet.
Nils
Sie haben es gelöst. Standardmäßig (zumindest unter Ubuntu) liegt der Schwellenwert bei 95%. Ich bin mir jedoch nicht sicher, ob es sich um eine CPU handelt. Wenn ich es auf 50% absenke, habe ich das erwartete Verhalten! Unter Ubuntu würden Sie das so machen: sudo bash -c "echo 50 > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold"Quelle: ivanlam.info/blog/2012/04/26/…
Huygens
1
@Huygens ich dieses Problem auf CentOS hatte - da die config-Datei für cpuspeedbefindet sich unter / etc / sysconfig / cpuspeed eine solche Änderung dauerhaft zu machen. In meinem Fall hatte ich eine VBox-VM mit nur einer CPU (physisch Dual-Core). Ich musste den Level auf 45% senken, um den Upscale-Effekt in der VM zu erzielen.
Nils
2

Auf dem Host sieht eine kvm-CPU wie ein Prozess aus. Der Skalierungsmechanismus überwacht keine Prozesse, sondern nur den gesamten CPU-Verbrauch.

und es wird im Allgemeinen empfohlen, die CPU-Skalierung / Drosselung / usw. zu deaktivieren, wenn VMs ausgeführt werden

dyasny
quelle
Seltsamerweise sehe ich, wenn ich auf dem Host oben bin, dass der Gesamt-CPU-Verbrauch etwa 80-130% beträgt (übrigens alle von den kvm- und ksm-Prozessen verbraucht), aber nicht die Frequenzskalierung. Wenn ich andere Prozesse ausführe, die CPUs verbrauchen, wird der On-Demand-Governor schnell aktiviert! Der einzige Unterschied, den ich annehme, besteht darin, dass der kvm-Prozess eine Virtualisierungstechnologie verwendet (in meinem Fall AMD svm), die dazu führen kann, dass der Governor des Hosts nicht reagiert. Und der Gast schafft es wohl nicht, das zugrunde liegende Hardware zu skalieren, obwohl es auf Bare Metal funktioniert hat.
Huygens
Können Sie sich auf einen Artikel beziehen, in dem erläutert wird, warum die Frequenzskalierung beim Ausführen von VMs keine bewährte Methode ist? Ich bin neugierig zu verstehen warum. Red Hat scheint dies zu unterstützen, siehe Kapitel 6.2.4 (es gab ein Problem in einer früheren Version als RHEL 5.3) access.redhat.com/knowledge/docs/en-US/Red_Hat_Enterprise_Linux/…
Huygens
Ich habe keine Artikel zur Hand, denke aber darüber nach, wofür Virtualisierung gedacht ist und wie sie funktioniert. Sie planen, eine nicht ausgelastete Maschine zu verwenden, indem Sie sie mit VMs laden. Die VMs sollten stabil und vorhersehbar sein. Denken Sie, dass eine Anpassung der CPU-Frequenz unter den VMs dabei helfen wird? Und wenn ich über Best Practice spreche, ist Ubuntu als virtueller Gastgeber meiner Erfahrung nach keine gute Idee
dyasny
Sie können VMs zwischen verschiedenen Hosts migrieren, die sich manchmal in der Häufigkeit unterscheiden. In diesem Fall sollten die Funktionen stabil sein, die von der CPU vom Host bereitgestellt werden. Wenn also SSE4 verfügbar gemacht wird und Ihre Anwendung davon Gebrauch macht, funktioniert Ihre VM nach der Migration auf eine CPU, die dies nicht unterstützt, nicht Absturz. Daher sollte die Frequenzskalierung, die ein wichtiger Faktor für die Reduzierung des Stromverbrauchs ist, kein Problem darstellen. Ich habe es gegoogelt und keinen Artikel gefunden, der das erwähnt.
Huygens
1
In Bezug auf die Distribution habe ich Ubuntu als problematisch erwähnt, weil es so ist. Sowohl auf SF als auch auf anderen Websites sehe ich immer wieder Leute, die Probleme im Zusammenhang mit KVM melden, die ich auf Fedora oder RHEL nie reproduzieren kann. Bitte zögern Sie nicht zu widersprechen, ich werde hier nicht in Flammen aufgehen.
Dyasny