La CPU host non scala la frequenza quando ne ha bisogno il guest KVM


8

Osservazione:
ho un server HP con una CPU dual core AMD (Turion II Neo N40L) in grado di scalare frequenze da 800 a 1500 MHz. Il ridimensionamento di frequenza funziona con FreeBSD 9 e Ubuntu 12.04 con il kernel 3.5 di Linux. Tuttavia, quando inserisco FreeBSD 9 in un ambiente KVM sopra Ubuntu il ridimensionamento della frequenza non funziona. Il guest (quindi FreeBSD) non rileva le frequenze minima e massima e quindi non scala nulla quando l'occupazione della CPU aumenta. Sull'host (quindi Ubuntu) il processo KVM utilizza tra l'80 e il 140% della risorsa CPU ma non si verifica alcun ridimensionamento di frequenza, la frequenza rimane a 800 MHz, anche se quando eseguo qualsiasi altro processo sullo stesso box Ubuntu, il governatore ondemand rapidamente ridimensiona la frequenza a 1500 MHz!

Preoccupazione e domanda:
non capisco come la CPU sia forse virtualizzata e se spetta al guest eseguire il corretto ridimensionamento. Richiede che alcune funzionalità della CPU siano esposte al guest affinché funzioni?

Appendice:
La seguente nota di rilascio di Red Hat tende a suggerire che il ridimensionamento della frequenza funzioni anche in un ambiente virtualizzato (vedere i capitoli 6.2.2 e 6.2.3), ritenendo che la nota non riesca ad affrontare con quale tecnologia di virtualizzazione funziona (kvm, xen , eccetera.?)

Per informazione, l' cpufreq-infooutput su Ubuntu è:

$ cpufreq-info
cpufrequtils 007: cpufreq-info (C) Dominik Brodowski 2004-2009
Report errors and bugs to cpufreq@vger.kernel.org, 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)

Il motivo per cui voglio che questa funzione funzioni è: risparmiare energia, correre più tranquillo (meno caldo) e anche semplice curiosità per capire meglio perché non funziona e come farlo funzionare.


1
Quel Microserver supporta solo Windows e RHEL, vedi le specifiche.

eseguito cpufreq-infosul sistema operativo host, probabilmente si lamenterà che non è disponibile alcun driver.
Chris S

Supporta ufficialmente Windows e RHEL. Non voglio dire che altri sistemi operativi non funzioneranno su di esso. Nota che il ridimensionamento della CPU funziona perfettamente su Ubuntu e FreeBSD quando sono installati sul bare metal (quindi non attraverso la virtualizzazione). Inoltre, se installati su bare metal entrambi i sistemi operativi funzionano perfettamente, non mancano driver o comportamenti strani. Infine, cpufreq-infonon si lamenta e genera informazioni adeguate, quindi la CPU è pienamente supportata (ovviamente in un certo senso!). Il driver utilizzato è powernow-k8 che è anche logico.
Huygens,

@ChrisS Ho aggiunto le informazioni cpufreq-info alla domanda originale.
Huygens,

Se non hai davvero bisogno del ridimensionamento di frequenza, puoi sempre disabilitarlo.
Michael Hampton,

Risposte:


10

Ho trovato la soluzione grazie al suggerimento dato da Nils e un bell'articolo .

Ottimizzazione del regolatore DVFS CPU ondemand

Il governatore ondemand ha una serie di parametri da controllare quando sta scalando il ridimensionamento dinamico della frequenza (o DVFS per il ridimensionamento dinamico della tensione e della frequenza). Tali parametri si trovano sotto l'albero sysfs:/sys/devices/system/cpu/cpufreq/ondemand/

Uno di questi parametri è up_thresholdche, come suggerisce il nome, è una soglia (l'unità è% di CPU, non ho scoperto però se questo è per core o core uniti) al di sopra del quale il governatore della ondemand interviene e inizia a cambiare dinamicamente la frequenza.

Modificarlo al 50% (ad esempio) usando sudo è semplice:
sudo bash -c "echo 50 > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold"

Se sei root, è possibile un comando ancora più semplice:
echo 50 > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold

Nota: tali modifiche andranno perse dopo il successivo riavvio dell'host. Dovresti aggiungerli a un file di configurazione che viene letto durante l'avvio, come /etc/init.d/rc.localsu Ubuntu.

Ho scoperto che la mia VM guest, sebbene consumando molta CPU (80-140%) sull'host distribuisse il carico su entrambi i core, quindi nessun singolo core era superiore al 95%, quindi la CPU, per mia esasperazione, era rimanendo a 800 MHz. Ora con la patch di cui sopra, la CPU cambia dinamicamente la sua frequenza per core molto più velocemente, il che si adatta meglio alle mie esigenze, il 50% sembra una soglia migliore per l'utilizzo dei miei ospiti, il tuo chilometraggio può variare.

Facoltativamente, verificare se si sta utilizzando HPET

È possibile che alcuni DVP applicabili possano implementare in modo errato i timer. Questo può essere un problema nell'host e / o nell'ambiente guest, anche se l'host può avere un algoritmo contorto per provare a minimizzarlo. Tuttavia, la CPU moderna ha un TSC (Time Stamp Counter) più recente che è indipendente dalla frequenza corrente CPU / core, ovvero: costante (constant_tsc), invariante (invariant_tsc) o non-stop (nonstop_tsc), vedi questo articolo di Chromium sulla risincronizzazione TSC per ulteriori informazioni su ciascuno. Pertanto, se la CPU è dotata di uno di questi TSC, non è necessario forzare HPET. Per verificare se la tua CPU host li supporta, usa un comando simile (cambia il parametro grep nella corrispondente funzione CPU, qui testiamo il TSC costante):

$ grep constant_tsc /proc/cpuinfo

Se non disponi di uno di questi moderni TSC, dovresti:

  1. HPET attivo, questo è descritto qui di seguito;
  2. Non utilizzare CPU DVFS se nella VM sono presenti applicazioni che si basano su un timing preciso, che è quello raccomandato da Red Hat .

Una soluzione sicura è quella di abilitare i timer HPET (vedi sotto per maggiori dettagli), sono più lenti da interrogare rispetto a quelli TSC (TSC sono nella CPU, rispetto a HPET nella scheda madre) e forse non hanno una precisione (HPET> 10MHz; TSC spesso il clock massimo della CPU) ma sono molto più affidabili soprattutto in una configurazione DVFS in cui ogni core potrebbe avere una frequenza diversa. Linux è abbastanza intelligente da usare il miglior timer disponibile, si affiderà prima al TSC, ma se trovato troppo inaffidabile, userà quello HPET. Questo funziona bene su sistemi host (bare metal), ma a causa della non tutte le informazioni correttamente esportate dall'hypervisor, questa è una sfida più grande per la VM guest per rilevare TSC che si comportano male. Il trucco è quindi forzare l'uso di HPET nell'ospite, anche se sarebbe necessario l'hypervisor per rendere disponibile questa sorgente di clock agli ospiti!

Di seguito puoi trovare come configurare e / o abilitare HPET su Linux e FreeBSD.

Configurazione HPET Linux

HPET, o timer per eventi ad alta precisione, è un timer hardware che puoi trovare nella maggior parte dei PC di consumo dal 2005. Questo timer può essere usato in modo efficiente dai moderni sistemi operativi (il kernel Linux lo supporta dal 2.6, supporto stabile su FreeBSD dall'ultimo 9.x ma è stato introdotto in 6.3 ) per fornire un tempismo coerente invariabilmente alla gestione della potenza della CPU. Consente di realizzare implementazioni di scheduler senza tick anche più semplici .

Fondamentalmente HPET è come una barriera di sicurezza che, anche se l'host ha DVFS attivo, gli eventi di temporizzazione dell'ospite e dell'ospite saranno meno colpiti.

C'è un buon articolo di IBM relativo all'abilitazione di HPET , spiega come verificare quale timer hardware sta usando il kernel e quali sono disponibili. Fornisco qui un breve riassunto:

Verifica dei timer hardware disponibili:
cat /sys/devices/system/clocksource/clocksource0/available_clocksource

Verifica del timer attivo corrente:
cat /sys/devices/system/clocksource/clocksource0/current_clocksource

Il modo più semplice per forzare l'uso di HPET se è disponibile è quello di modificare il boot loader per chiedere di abilitarlo (dal kernel 2.6.16). Questa configurazione dipende dalla distribuzione, quindi fare riferimento alla propria documentazione di distribuzione per impostarla correttamente. Dovresti abilitare hpet=enableo clocksource=hpetsulla linea di avvio del kernel (questo dipende ancora dalla versione o dalla distribuzione del kernel, non ho trovato alcuna informazione coerente).
Questo assicura che il guest stia utilizzando il timer HPET.

Nota: sul mio kernel 3.5, Linux sembra raccogliere automaticamente il timer hpet.

Configurazione HPET guest di FreeBSD

Su FreeBSD puoi verificare quali timer sono disponibili eseguendo:
sysctl kern.timecounter.choice

Il timer attualmente selezionato può essere verificato con:
sysctl kern.timecounter.hardware

FreeBSD 9.1 sembra preferire automaticamente HPET rispetto ad altri provider di timer.

Todo: come forzare HPET su FreeBSD.

Esportazione HPET hypervisor

KVM sembra esportare automaticamente HPET quando l'host ne ha il supporto. Tuttavia, per i guest Linux preferiranno l'altro clock esportato automaticamente che è kvm-clock (una versione paravirtualizzata dell'host TSC). Alcune persone segnalano problemi con l'orologio preferito, il chilometraggio può variare. Se si desidera forzare HPET nel guest, fare riferimento alla sezione precedente.

VirtualBox non esporta l'orologio HPET nel guest per impostazione predefinita, e non c'è alcuna opzione per farlo nella GUI. È necessario utilizzare la riga di comando e assicurarsi che la VM sia spenta. il comando è:

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

Se il guest continua a selezionare un'altra fonte diversa da HPET dopo la modifica precedente, fare riferimento alla sezione precedente su come forzare il kernel a utilizzare HPET clock come sorgente.


c'è una vera applicazione per questo, o è solo un trucco una tantum?
ewwhite,

@ewwhite cosa intendi con un trucco una tantum? La scoperta è che DVFS (ridimensionamento dinamico di tensione e frequenza) sta effettivamente lavorando con KVM e un host Linux. L'utilizzo della CPU di processo dell'80-140% è stato probabilmente distribuito uniformemente su entrambi i core, quindi nessun core stava raggiungendo la soglia predefinita del 95% che avrebbe portato al ridimensionamento della frequenza. Senza cambiare nulla, se creo davvero un processo a thread singolo che utilizza il 100% di un core nella VM, allora il ridimensionamento di freq viene espulso, quindi non lo vedevo. Per quanto riguarda l'applicazione reale di DVFS, si tratta di risparmiare energia e ridurre la temperatura.
Huygens,

@ewwhite Intendi "c'è un'applicazione che sintonizza questo valore per me?" Penso che la risposta sia no. Altrimenti qualcuno avrebbe già inserito un default ragionevole . 95 non è assolutamente sensato qui.
Michael Hampton,

No, esiste un'applicazione (motivo) per volerlo usare in una configurazione virtualizzata?
ewwhite,

Motivo: non voglio che la CPU funzioni alla massima velocità per diversi motivi: il consumo di energia è più elevato, la temperatura è più alta, l'usura più veloce, la VENTOLA gira più velocemente (più potenza e più veloce), richiede una batteria UPS più grande.
Huygens,

4

Non è l'ospite che attiva l'upscaling: l'host deve farlo. Quindi devi abbassare il livello di trigger corrispondente sull'host.


Interessante, ti capita di saperlo fare?
Huygens,

@Huygens Normalmente questo viene fatto tramite una specie di demone cpufrequency. Esiste un file di configurazione per quel demone in cui è possibile modificarne il comportamento e i valori up / downscale. Non sono sicuro di dove si trovi esattamente questo su Ubuntu.
Nils,

L'hai risolto, per impostazione predefinita (almeno su Ubuntu) la soglia è del 95%, ma non sono sicuro che sia per CPU. Abbassandolo al 50% ho il comportamento previsto! Su Ubuntu lo faresti in questo modo: sudo bash -c "echo 50 > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold"Fonte: ivanlam.info/blog/2012/04/26/…
Huygens

1
@Huygens Ho avuto questo problema su CentOS - lì il file di configurazione per cpuspeedsi trova in / etc / sysconfig / cpuspeed per rendere permanente tale modifica. Nel mio caso avevo un VBox-VM con una sola CPU (fisicamente dual-core). Ho dovuto abbassare il livello al 45% per ottenere l'effetto di alto livello nella VM.
Nils,

2

sull'host, una CPU kvm sembra un processo. Il meccanismo di ridimensionamento non controlla i processi, ma solo il consumo complessivo di CPU.

ed è generalmente buona pratica disabilitare il ridimensionamento della CPU / throttling / etc durante l'esecuzione di VM


Stranamente, quando ottengo il massimo sull'host posso vedere che il consumo complessivo della CPU è di circa l'80-130% (tra tutti quelli consumati dai processi kvm e ksm) ma non il ridimensionamento della frequenza. Quando eseguo altri processi che consumano CPU, il governatore ondemand si avvia rapidamente! L'unica differenza che presumo è che il processo kvm utilizza una tecnologia di virtualizzazione (nel mio caso AMD svm) che potrebbe impedire al governatore dell'host di reagire. E l'ospite non riesce a richiedere il ridimensionamento dell'hw sottostante, anche se su bare metal ha funzionato.
Huygens,

Potresti riferirti a un articolo che spiega perché il ridimensionamento di frequenza non è una buona pratica quando si eseguono VM? Sono curioso di capire perché. Red Hat sembra supportare questo, vedi capitolo 6.2.4 (c'era un problema nella versione precedente rispetto a RHEL 5.3) access.redhat.com/knowledge/docs/en-US/Red_Hat_Enterprise_Linux/…
Huygens

Non ho articoli utili, ma pensa a cosa serve la virtualizzazione e come funziona. Stai pianificando di utilizzare una macchina sottoutilizzata caricandola con macchine virtuali. Le macchine virtuali dovrebbero essere stabili e prevedibili. Pensi che una regolazione della frequenza della CPU sotto le macchine virtuali ti aiuterà? E parlando delle migliori pratiche, Ubuntu come host virt non è una buona idea nella mia esperienza
dyasny,

È possibile migrare VM tra host diversi, a volte con frequenza diversa. La cosa che dovrebbe essere stabile in questo caso sono le funzionalità esposte dalla CPU dall'host, in modo che se SSE4 è esposto e l'applicazione ne fa uso, una volta eseguita la migrazione a una CPU che non la supporta, la VM non lo fa bloccarsi. Quindi il ridimensionamento di frequenza, che è un fattore determinante per mitigare il consumo energetico, non dovrebbe costituire un problema. L'ho cercato su Google e non ho trovato nessun articolo che lo menzionasse.
Huygens,

1
Per quanto riguarda la distribuzione, ho menzionato Ubuntu come problematico perché lo è. Sia su SF che su altri siti, continuo a vedere persone che segnalano problemi relativi a KVM che non riesco mai a riprodurre su Fedora o RHEL. Sentiti libero di non essere d'accordo, non sto continuando in una guerra di fiamma qui.
dyasny,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.