A CPU host não escala a frequência quando o convidado KVM precisa dela

8

Observação:
Eu tenho um servidor HP com uma CPU AMD dual core (Turion II Neo N40L) que pode escalar frequências de 800 a 1500 MHz. O escalonamento de frequência funciona no FreeBSD 9 e no Ubuntu 12.04 com o kernel Linux 3.5. No entanto, quando coloco o FreeBSD 9 em um ambiente KVM em cima do Ubuntu, o escalonamento de frequência não funciona. O convidado (portanto FreeBSD) não detecta as frequências mínima e máxima e, portanto, não escala nada quando a ocupação da CPU aumenta. No host (portanto, Ubuntu), o processo KVM usa entre 80 e 140% do recurso da CPU, mas não ocorre escala de frequência, a frequência permanece em 800 MHz, embora quando eu execute qualquer outro processo na mesma caixa do Ubuntu, o governador da ondemand rapidamente escala a frequência para 1500 MHz!

Preocupação e pergunta:
não entendo como a CPU talvez seja virtualizada e se cabe ao convidado executar o dimensionamento adequado. Requer que alguns recursos da CPU sejam expostos ao convidado para que isso funcione?

Apêndice:
A seguinte nota de lançamento da Red Hat tende a sugerir que a escalabilidade da frequência funcione mesmo em um ambiente virtualizado (consulte os capítulos 6.2.2 e 6.2.3), apesar de a nota falhar em abordar com qual tecnologia de virtualização funciona (kvm, xen etc.?)

Para informações, a cpufreq-infosaída no 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)

O motivo pelo qual desejo que esse recurso funcione é: economizar energia, ficar mais silencioso (menos quente) e também uma simples curiosidade para entender melhor por que isso não está funcionando e como fazê-lo funcionar.

Huygens
fonte
1
Como o Microserver suporta apenas Windows e RHEL, consulte os quickspecs.
executado cpufreq-infono sistema operacional host, provavelmente reclamará que não há driver disponível.
Chris S
Ele oficialmente suporta Windows e RHEL. Não quero dizer que outro sistema operacional não funcione em cima dele. Observe que o dimensionamento da CPU está funcionando perfeitamente no Ubuntu e no FreeBSD quando eles são instalados no bare metal (portanto, não através da virtualização). Além disso, quando instalado no bare metal, ambos os sistemas operacionais estão funcionando perfeitamente, sem nenhum driver ausente ou comportamento estranho. Finalmente, cpufreq-infonão reclama e gera informações adequadas, portanto a CPU é totalmente suportada (é claro, de certa forma!). O driver usado é o powernow-k8, que também é lógico.
Huygens
@ Chrishr Adicionei as informações do cpufreq-info à pergunta original.
Huygens
Se você realmente não precisa de escala de frequência, sempre pode desativá-lo.
Michael Hampton

Respostas:

10

Encontrei a solução graças à dica dada por Nils e a um bom artigo .

Ajustando o governador da CPU ondemand DVFS

O governador ondemand possui um conjunto de parâmetros para controlar quando está chutando a escala de frequência dinâmica (ou DVFS para tensão dinâmica e escala de frequência). Esses parâmetros estão localizados na árvore sysfs:/sys/devices/system/cpu/cpufreq/ondemand/

Um desses parâmetros é up_thresholdque, como o nome sugere, é um limite (a unidade é% da CPU, ainda não descobri se é por núcleo ou núcleos mesclados) acima dos quais o governador ondemand entra em ação e começa a mudar dinamicamente a frequência.

Mudar para 50% (por exemplo) usando o sudo é simples:
sudo bash -c "echo 50 > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold"

Se você é root, é possível um comando ainda mais simples:
echo 50 > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold

Nota: essas alterações serão perdidas após a próxima reinicialização do host. Você deve adicioná-los a um arquivo de configuração que é lido durante a inicialização, como /etc/init.d/rc.localno Ubuntu.

Descobri que minha VM convidada, apesar de consumir muita CPU (80-140%) no host, estava distribuindo a carga nos dois núcleos; portanto, nenhum núcleo estava acima de 95%; portanto, a CPU, para minha exasperação, era permanecendo em 800 MHz. Agora, com o patch acima, a CPU altera dinamicamente sua frequência por núcleo muito mais rapidamente, o que melhor se adapta às minhas necessidades, 50% parece um limite melhor para o uso de meus hóspedes, sua milhagem pode variar.

Opcionalmente, verifique se você está usando o HPET

É possível que alguns aplicáveis ​​que implementam temporizadores incorretamente sejam afetados pelo DVFS. Isso pode ser um problema no ambiente host e / ou convidado, embora o host possa ter algum algoritmo complicado para tentar minimizar isso. No entanto, a CPU moderna possui um TSC (Time Stamp Counter) mais recente, independente da freqüência atual da CPU / núcleo, que são: constante (constante_tsc), invariante (invariant_tsc) ou sem interrupção (nonstop_tsc), consulte este artigo do Chromium sobre ressincronização TSC para mais informações sobre cada um. Portanto, se sua CPU estiver equipada com um desses TSC, você não precisará forçar o HPET. Para verificar se a CPU do host os suporta, use um comando semelhante (altere o parâmetro grep para o recurso de CPU correspondente, aqui testamos o TSC constante):

$ grep constant_tsc /proc/cpuinfo

Se você não possui um desses TSC modernos, deve:

  1. HPET ativo, isso é descrito aqui depois;
  2. Não use CPU DVFS se você tiver aplicativos na VM que dependam de tempo preciso, que é o recomendado pela Red Hat .

Uma solução segura é habilitar os temporizadores HPET (veja abaixo para obter mais detalhes), eles são mais lentos do que os TSC (os TSC estão na CPU e os HPET na placa-mãe) e talvez não sejam precisos (HPET> 10MHz; TSC geralmente o clock máximo da CPU), mas eles são muito mais confiáveis, especialmente em uma configuração DVFS em que cada núcleo pode ter uma frequência diferente. O Linux é inteligente o suficiente para usar o melhor cronômetro disponível; ele dependerá primeiro do TSC, mas se for considerado pouco confiável, utilizará o HPET. Isso funciona bem em sistemas host (bare metal), mas devido a nem todas as informações exportadas corretamente pelo hipervisor, é mais um desafio para a VM convidada detectar o TSC com comportamento inadequado. O truque é forçar o uso do HPET no convidado, embora você precise do hipervisor para disponibilizar essa fonte de relógio para os convidados!

Abaixo, você encontra como configurar e / ou ativar o HPET no Linux e FreeBSD.

Configuração Linux HPET

HPET, ou timer de eventos de alta precisão, é um timer de hardware que você pode encontrar na maioria dos PCs comuns desde 2005. Esse timer pode ser usado com eficiência pelo sistema operacional moderno (o kernel Linux suporta desde 2.6, suporte estável no FreeBSD desde a versão 9.x mais recente). mas foi introduzido na versão 6.3 ) para fornecer um tempo consistente invariavelmente ao gerenciamento de energia da CPU. Ele permite criar implementações também mais fáceis de agendador sem marcadores .

Basicamente, o HPET é como uma barreira de segurança que, mesmo que o host tenha o DVFS ativo, os eventos de temporização do host e do convidado serão menos afetados.

Há um bom artigo da IBM sobre a ativação do HPET , que explica como verificar qual cronômetro de hardware está sendo usado pelo kernel e quais estão disponíveis. Apresento aqui um breve resumo:

Verificando os cronômetros de hardware disponíveis:
cat /sys/devices/system/clocksource/clocksource0/available_clocksource

Verificando o cronômetro ativo atual:
cat /sys/devices/system/clocksource/clocksource0/current_clocksource

A maneira mais simples de forçar o uso do HPET, se você o tiver disponível, é modificar o seu carregador de inicialização para pedir para habilitá-lo (desde o kernel 2.6.16). Essa configuração depende da distribuição; portanto, consulte a sua própria documentação de distribuição para configurá-la corretamente. Você deve ativar hpet=enableou clocksource=hpetna linha de inicialização do kernel (isso depende novamente da versão ou distribuição do kernel, não encontrei nenhuma informação coerente).
Verifique se o convidado está usando o cronômetro HPET.

Nota: no meu kernel 3.5, o Linux parece pegar automaticamente o hpet timer.

Configuração de HPET convidado do FreeBSD

No FreeBSD pode-se verificar quais timers estão disponíveis executando:
sysctl kern.timecounter.choice

O cronômetro escolhido atualmente pode ser verificado com:
sysctl kern.timecounter.hardware

O FreeBSD 9.1 parece preferir automaticamente o HPET a outro provedor de timer.

Todo: como forçar o HPET no FreeBSD.

Exportação HPET do hipervisor

O KVM parece exportar o HPET automaticamente quando o host tiver suporte para ele. No entanto, para o convidado Linux, eles preferem o outro relógio exportado automaticamente, que é o kvm-clock (uma versão paravirtualizada do TSC host). Algumas pessoas relatam problemas com o relógio preferido, sua milhagem pode variar. Se você deseja forçar o HPET no convidado, consulte a seção acima.

O VirtualBox não exporta o relógio HPET para o convidado por padrão, e não há opção para fazer isso na GUI. Você precisa usar a linha de comando e verificar se a VM está desligada. o comando é:

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

Se o convidado continuar selecionando outra fonte que não o HPET após a alteração acima, consulte a seção acima como forçar o kernel a usar o relógio HPET como fonte.

Huygens
fonte
existe uma aplicação real para isso ou é apenas um truque único?
ewwhite
@whwhite o que você quer dizer com um truque único? A descoberta é que o DVFS (tensão dinâmica e escala de frequência) está realmente trabalhando com o KVM e um host Linux. A utilização da CPU do processo de 80-140% provavelmente foi distribuída igualmente nos dois núcleos, de modo que nenhum núcleo estava atingindo o limite padrão de 95%, o que levaria ao escalonamento de frequência. Sem alterar nada, se eu realmente criar um processo de thread único que use 100% de um núcleo na VM, o escalonamento de frequência será acionado, então eu simplesmente não estava vendo. Quanto à aplicação real do DVFS, trata-se de economizar energia e diminuir a temperatura.
Huygens
@ewwhite Você quer dizer "existe um aplicativo que ajusta esse valor para mim?" Eu acho que a resposta é não. Caso contrário, alguém já teria colocado um padrão sensato . Definitivamente, aqui não é sensato.
Michael Hampton
Não, existe um aplicativo (motivo) para querer usá-lo em uma instalação virtualizada?
ewwhite
Razão: eu não quero que a CPU funcione a toda velocidade por vários motivos: o consumo de energia é mais alto, a temperatura é mais alta, o desgaste é mais rápido, os ventiladores estão girando mais rapidamente (mais energia e mais desgaste), requer uma bateria UPS maior.
Huygens
4

Não é o convidado que aciona o upscale - o host deve fazer isso. Portanto, você deve abaixar o nível de acionador correspondente no host.

Nils
fonte
Interessante, você saberia como fazer isso?
Huygens
@ Huygens Normalmente, isso é feito através de algum tipo de cpufrequency-daemon. Há um arquivo de configuração para esse daemon em que você pode alterar o comportamento e os valores para cima / baixo da escala. Não tenho certeza de onde exatamente isso está localizado no Ubuntu.
Nils
Você resolveu, por padrão (no Ubuntu, pelo menos) o limite é de 95%, mas não tenho certeza se é por CPU. Ao diminuir para 50%, tenho o comportamento esperado! No Ubuntu, você faria assim: sudo bash -c "echo 50 > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold"Fonte: ivanlam.info/blog/2012/04/26/…
Huygens
1
@ Huygens Eu tive esse problema no CentOS - o arquivo de configuração cpuspeedestá localizado em / etc / sysconfig / cpuspeed para tornar essa alteração permanente. No meu caso, eu tinha uma VM VBox com apenas uma CPU (fisicamente dual-core). Eu tive que abaixar o nível para 45% para obter o efeito de upscale na VM.
Nils
2

no host, uma kvm cpu parece um processo. O mecanismo de dimensionamento não observa processos, apenas o consumo geral da CPU.

e geralmente é uma boa prática desabilitar o dimensionamento / otimização da CPU / etc ao executar VMs

dyasny
fonte
Estranhamente, quando estou no topo do host, vejo que o consumo geral da CPU é de cerca de 80 a 130% (entre todos consumidos pelos processos kvm e ksm), mas não a escala de frequência. Quando eu executo outros processos que consomem CPUs, o governador ondemand está rapidamente entrando em ação! A única diferença que assumo é que o processo kvm está usando alguma tecnologia de virtualização (AMD svm no meu caso), o que pode fazer com que o governador do host não reaja. E o convidado não consegue solicitar o hw subjacente à escala, eu acho, embora no bare metal tenha funcionado.
Huygens
Você poderia consultar um artigo detalhando por que o dimensionamento de frequência não é uma prática recomendada ao executar VMs? Estou curioso para entender o porquê. A Red Hat parece apoiar isso, consulte o capítulo 6.2.4 (houve um problema na versão anterior ao RHEL 5.3) access.redhat.com/knowledge/docs/en-US/Red_Hat_Enterprise_Linux/…
Huygens
Não tenho artigos à mão, mas pense sobre o que é a virtualização e como ela funciona. Você planeja utilizar uma máquina subutilizada carregando-a com VMs. As VMs devem ser estáveis ​​e previsíveis. Você acha que um ajuste de frequência da CPU sob as VMs ajudará nisso? E por falar em melhores práticas, ubuntu como um anfitrião virt não é uma boa ideia na minha experiência
dyasny
Você pode migrar VMs entre host diferente, às vezes com frequência diferente. O que deve ser estável nesse caso são os recursos expostos pela CPU a partir do host, para que, se o SSE4 for exposto e seu aplicativo faça uso dele, depois de migrar para uma CPU que não a suporta, sua VM não batida. Portanto, a escala de frequência, que é um grande fator para reduzir o consumo de energia, não deve ser um problema. Eu pesquisei no Google e não encontrei nenhum artigo mencionando isso.
Huygens
1
Quanto à distribuição, mencionei o Ubuntu como problemático, porque é. Tanto no SF quanto em outros sites, continuo vendo pessoas relatando problemas relacionados ao KVM que nunca consigo reproduzir no Fedora ou RHEL. Por favor, sinta-se livre para discordar, não continuarei em uma guerra de fogo aqui.
dyasny