La CPU del host no escala la frecuencia cuando el huésped KVM lo necesita

8

Observación:
Tengo un servidor HP con una CPU AMD de doble núcleo (Turion II Neo N40L) que puede escalar frecuencias de 800 a 1500 MHz. La escala de frecuencia funciona bajo FreeBSD 9 y bajo Ubuntu 12.04 con el kernel 3.5 de Linux. Sin embargo, cuando coloco FreeBSD 9 en un entorno KVM encima de Ubuntu, la escala de frecuencia no funciona. El invitado (por lo tanto, FreeBSD) no detecta las frecuencias mínima y máxima y, por lo tanto, no escala nada cuando la ocupación de la CPU aumenta. En el host (por lo tanto, Ubuntu), el proceso KVM utiliza entre el 80 y el 140% de los recursos de la CPU, pero no ocurre escala de frecuencia, la frecuencia se mantiene en 800 MHz, aunque cuando ejecuto cualquier otro proceso en el mismo cuadro de Ubuntu, el gobernador a pedido rápidamente ¡escala la frecuencia a 1500 MHz!

Preocupación y pregunta:
no entiendo cómo la CPU está quizás virtualizada, y si depende del huésped realizar el escalado adecuado. ¿Requiere que algunas características de la CPU estén expuestas al huésped para que esto funcione?

Apéndice:
La siguiente nota de lanzamiento de Red Hat tiende a sugerir que la escala de frecuencia funciona incluso en un entorno virtualizado (consulte el capítulo 6.2.2 y 6.2.3), aunque la nota no aborda con qué tecnología de virtualización funciona (kvm, xen , etc.?)

Para información, el cpufreq-inforesultado en Ubuntu es:

$ 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)

La razón por la que quiero que esta característica funcione es: ahorrar energía, correr más silenciosamente (menos calor) y también simple curiosidad para comprender mejor por qué esto no funciona y cómo hacerlo funcionar.

Huygens
fuente
1
Ese Microserver solo es compatible con Windows y RHEL, consulte las especificaciones rápidas.
ejecutado cpufreq-infoen el sistema operativo host, probablemente se quejará de que no hay un controlador disponible.
Chris S
Oficialmente es compatible con Windows y RHEL. No quiero decir que otro sistema operativo no se ejecute encima de él. Tenga en cuenta que el escalado de la CPU funciona perfectamente en Ubuntu y FreeBSD cuando se instalan en el metal desnudo (por lo tanto, no a través de la virtualización). Además, cuando se instala en metal desnudo, ambos sistemas operativos funcionan perfectamente, no faltan controladores ni tienen un comportamiento extraño. Finalmente, cpufreq-infono se queja y muestra información adecuada, por lo que la CPU es totalmente compatible (¡por supuesto, de alguna manera! El controlador utilizado es powernow-k8, que también es lógico.
Huygens
@ChrisS He agregado la información cpufreq-info a la pregunta original.
Huygens
Si realmente no necesita escalado de frecuencia, siempre puede deshabilitarlo.
Michael Hampton

Respuestas:

10

He encontrado la solución gracias a la sugerencia dada por Nils y un buen artículo .

Ajuste del gobernador de CPU DVFS bajo demanda

El gobernador bajo demanda tiene un conjunto de parámetros para controlar cuando está activando la escala de frecuencia dinámica (o DVFS para la escala de frecuencia y voltaje dinámico). Esos parámetros se encuentran debajo del árbol sysfs:/sys/devices/system/cpu/cpufreq/ondemand/

Uno de estos parámetros es up_thresholdque, como su nombre indica, es un umbral (la unidad es el% de CPU, aunque no he descubierto si es por núcleo o núcleos fusionados) por encima del cual el gobernador bajo demanda se activa y comienza a cambiar dinámicamente la frecuencia.

Cambiarlo al 50% (por ejemplo) usando sudo es simple:
sudo bash -c "echo 50 > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold"

Si eres root, es posible un comando aún más simple:
echo 50 > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold

Nota: esos cambios se perderán después del próximo reinicio del host. Debe agregarlos a un archivo de configuración que se lee durante el arranque, como /etc/init.d/rc.localen Ubuntu.

Descubrí que mi máquina virtual invitada, aunque consumía una gran cantidad de CPU (80-140%) en el host, estaba distribuyendo la carga en ambos núcleos, por lo que ningún núcleo individual estaba por encima del 95%, por lo que la CPU, para mi exasperación, era quedándose a 800 MHz. Ahora con el parche anterior, la CPU cambia dinámicamente su frecuencia por núcleo mucho más rápido, lo que se adapta mejor a mis necesidades, el 50% parece un mejor umbral para el uso de mis invitados, su kilometraje puede variar.

Opcionalmente, verifique si está utilizando HPET

Es posible que algunos de los aplicables que implementan temporizadores incorrectamente puedan verse afectados por DVFS. Esto puede ser un problema en el entorno host y / o invitado, aunque el host puede tener algún algoritmo complicado para intentar minimizar esto. Sin embargo, la CPU moderna tiene un TSC (Contador de sello de tiempo) más nuevo que es independiente de la frecuencia actual de CPU / núcleo, que son: constante (constant_tsc), invariante (invariant_tsc) o sin parar (nonstop_tsc), consulte este artículo de Chromium sobre la resincronización de TSC Para más información sobre cada uno. Entonces, si su CPU está equipada con uno de estos TSC, no necesita forzar HPET. Para verificar si su CPU host los admite, use un comando similar (cambie el parámetro grep a la función de CPU correspondiente, aquí probamos el TSC constante):

$ grep constant_tsc /proc/cpuinfo

Si no tiene uno de estos TSC modernos, debe:

  1. HPET activo, esto se describe aquí después;
  2. No use CPU DVFS si tiene alguna aplicación en la VM que se base en una sincronización precisa, que es la recomendada por Red Hat .

Una solución segura es habilitar los temporizadores HPET (consulte a continuación para obtener más detalles), son más lentos para consultar que los TSC (TSC están en la CPU, frente a HPET en la placa base) y tal vez no tienen precisión (HPET> 10MHz; TSC a menudo el reloj máximo de la CPU), pero son mucho más confiables, especialmente en una configuración DVFS donde cada núcleo podría tener una frecuencia diferente. Linux es lo suficientemente inteligente como para usar el mejor temporizador disponible, dependerá primero del TSC, pero si se encuentra poco confiable, usará el HPET. Esto funciona bien en los sistemas host (bare metal), pero debido a que no toda la información exportada correctamente por el hipervisor, esto es más un desafío para la máquina virtual invitada para detectar TSC de mal comportamiento. El truco consiste en forzar el uso de HPET en el invitado, ¡aunque necesitaría el hipervisor para que esta fuente de reloj esté disponible para los invitados!

A continuación puede encontrar cómo configurar y / o habilitar HPET en Linux y FreeBSD.

Configuración de Linux HPET

HPET, o temporizador de eventos de alta precisión, es un temporizador de hardware que puede encontrar en la mayoría de las PC desde 2005. Este sistema operativo moderno puede usar este temporizador de manera eficiente (el kernel de Linux lo admite desde 2.6, soporte estable en FreeBSD desde la última versión 9.x) pero se introdujo en 6.3 ) para proporcionar un tiempo constante invariablemente a la administración de energía de la CPU. Permite construir también implementaciones de planificador sin tick más fáciles .

Básicamente, HPET es como una barrera de seguridad que, incluso si el host tiene DVFS activo, los eventos de temporización del host y el invitado se verán menos afectados.

Hay un buen artículo de IBM sobre la habilitación de HPET , explica cómo verificar qué temporizador de hardware está usando su núcleo y cuáles están disponibles. Proporciono aquí un breve resumen:

Comprobación de los temporizadores de hardware disponibles:
cat /sys/devices/system/clocksource/clocksource0/available_clocksource

Comprobación del temporizador activo actual:
cat /sys/devices/system/clocksource/clocksource0/current_clocksource

Una forma más sencilla de forzar el uso de HPET si lo tiene disponible es modificar su gestor de arranque para solicitar habilitarlo (desde el kernel 2.6.16). Esta configuración depende de la distribución, por lo tanto, consulte su propia documentación de distribución para configurarla correctamente. Debe habilitar hpet=enableo clocksource=hpeten la línea de arranque del kernel (esto nuevamente depende de la versión o distribución del kernel, no encontré ninguna información coherente).
Esto asegura que el invitado esté usando el temporizador HPET.

Nota: en mi kernel 3.5, Linux parece recoger automáticamente el temporizador hpet.

Configuración de HPET invitado de FreeBSD

En FreeBSD se puede verificar qué temporizadores están disponibles ejecutando:
sysctl kern.timecounter.choice

El temporizador elegido actualmente se puede verificar con:
sysctl kern.timecounter.hardware

FreeBSD 9.1 parece preferir automáticamente HPET a otro proveedor de temporizadores.

Todo: cómo forzar HPET en FreeBSD.

Exportación de hipervisor HPET

KVM parece exportar HPET automáticamente cuando el host lo admite. Sin embargo, para los invitados de Linux, preferirán el otro reloj exportado automáticamente, que es kvm-clock (una versión paravirtualizada del TSC del host). Algunas personas informan problemas con el reloj preferido, su millaje puede variar. Si desea forzar HPET en el invitado, consulte la sección anterior.

VirtualBox no exporta el reloj HPET al invitado de forma predeterminada, y no hay ninguna opción para hacerlo en la GUI. Debe usar la línea de comando y asegurarse de que la VM esté apagada. el comando es:

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

Si el invitado continúa seleccionando otra fuente que no sea HPET después del cambio anterior, consulte la sección anterior sobre cómo obligar al núcleo a usar el reloj HPET como fuente.

Huygens
fuente
¿Existe una aplicación real para esto, o es solo un truco único?
ewwhite
@ewwhite, ¿qué quieres decir con un truco único? El hallazgo es que DVFS (escala dinámica de voltaje y frecuencia) en realidad está trabajando con KVM y un host Linux. El proceso de utilización de la CPU del 80-140% probablemente se distribuyó en ambos núcleos de manera uniforme, por lo que ninguno de los núcleos estaba alcanzando el umbral predeterminado del 95%, lo que conduciría a una escala de frecuencia. Sin cambiar nada, si realmente creo un proceso de subproceso único que utiliza el 100% de un núcleo en la máquina virtual, entonces la escala de frecuencia se inicia, por lo que simplemente no lo estaba viendo. En cuanto a la aplicación real de DVFS, se trata de ahorrar energía y disminuir la temperatura.
Huygens
@ewwhite ¿Quiere decir "hay una aplicación que ajuste este valor para mí?" Creo que la respuesta es no. De lo contrario, alguien ya habría establecido un incumplimiento razonable . 95 definitivamente no es sensible aquí.
Michael Hampton
No, ¿hay una aplicación (razón) para querer usar esto en una configuración virtualizada?
ewwhite
Motivo: No quiero que la CPU funcione a toda velocidad por varias razones: el consumo de energía es más alto, la temperatura es más alta, se desgasta más rápido, el VENTILADOR gira más rápido (más potencia y más rápido desgaste), requiere una batería UPS más grande.
Huygens
4

No es el invitado el que desencadena el exclusivo; el host debe hacer esto. Por lo tanto, debe reducir el nivel de activación correspondiente en el host.

Nils
fuente
Interesante, ¿sabrías cómo hacer esto?
Huygens
@Huygens Normalmente esto se hace a través de algún tipo de demonio cpufrequency. Hay un archivo de configuración para ese demonio en el que puede cambiar su comportamiento y valores ascendentes / descendentes. No estoy seguro de dónde se encuentra exactamente esto en Ubuntu.
Nils
Lo resolvió, de manera predeterminada (al menos en Ubuntu) el umbral es del 95%, aunque no estoy seguro de si es por CPU. ¡Bajándolo al 50% tengo el comportamiento esperado! En Ubuntu lo haría así: sudo bash -c "echo 50 > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold"Fuente: ivanlam.info/blog/2012/04/26/…
Huygens
1
@Huygens Tuve este problema en CentOS: allí el archivo de configuración cpuspeedse encuentra en / etc / sysconfig / cpuspeed para que dicho cambio sea permanente. En mi caso, tenía un VBox-VM con solo una CPU (físicamente dual-core). Tuve que bajar el nivel al 45% para obtener el efecto exclusivo en la VM.
Nils
2

En el host, una CPU KVM parece un proceso. El mecanismo de escala no observa los procesos, solo el consumo general de la CPU.

y generalmente es una buena práctica deshabilitar el escalado / aceleración de la CPU / etc. cuando se ejecutan máquinas virtuales

dyasny
fuente
Curiosamente, cuando llego a la cima en el host, puedo ver que el consumo total de CPU es de aproximadamente 80-130% (por cierto, todo lo que consumen los procesos kvm y ksm), pero no la escala de frecuencia. Cuando ejecuto otros procesos que consumen CPU, ¡el gobernador bajo demanda se activa rápidamente! La única diferencia que supongo es que el proceso de kvm está utilizando alguna tecnología de virtualización (AMD svm en mi caso) que podría hacer que el gobernador del host no reaccione. Y supongo que el invitado no logra solicitar el hw subyacente para escalar, aunque en metal desnudo funcionó.
Huygens
¿Podría referirse a un artículo que detalla por qué el escalado de frecuencia no es una mejor práctica cuando se ejecutan máquinas virtuales? Tengo curiosidad por entender por qué. Red Hat parece apoyar esto, vea el capítulo 6.2.4 (hubo un problema en una versión anterior a RHEL 5.3) access.redhat.com/knowledge/docs/en-US/Red_Hat_Enterprise_Linux/…
Huygens
No tengo ningún artículo a mano, pero piense para qué sirve la virtualización y cómo funciona. Está planeando utilizar una máquina subutilizada cargándola con máquinas virtuales. Las máquinas virtuales deben ser estables y predecibles. ¿Crees que los ajustes de frecuencia de la CPU debajo de las máquinas virtuales ayudarán con eso? Y hablando de las mejores prácticas, ubuntu como un host virtual no es una buena idea en mi experiencia
dyasny
Puede migrar máquinas virtuales entre diferentes hosts, a veces con diferente frecuencia. Lo que debería ser estable en este caso son las características expuestas por la CPU desde el host, de modo que si SSE4 está expuesto y su aplicación lo utiliza, una vez que migra a una CPU que no lo admite, su VM no choque. Por lo tanto, el escalado de frecuencia, que es un factor importante para mitigar el consumo de energía, no debería ser un problema. Lo busqué en Google y no encontré ningún artículo que mencionara eso.
Huygens
1
En cuanto a la distribución, mencioné Ubuntu como problemático porque lo es. Tanto en SF como en otros sitios, sigo viendo personas que informan sobre problemas relacionados con KVM que nunca logro reproducir en Fedora o RHEL. Por favor, siéntase libre de estar en desacuerdo, no voy a continuar una guerra de llamas aquí.
dyasny