Windows VM Travando no Proxmox? A Anatomia do Gargalo de IO
Seu Windows congela durante backups ou updates? Entenda a interação entre VirtIO, iothreads e Cache no QEMU/KVM e elimine a latência.
Você acabou de instalar uma VM Windows Server ou Windows 10/11 no Proxmox. A instalação foi rápida. O boot foi rápido. Mas no momento em que você inicia o Windows Update ou tenta copiar um arquivo grande, a interface congela. O cursor do mouse via VNC/SPICE começa a "pular" ou para totalmente. O Task Manager dentro da VM mostra uso de disco em 100%, mas o throughput é ridículo (alguns MB/s).
Se você já viveu isso, pare de jogar memória RAM no problema. O sintoma é visual, mas a causa é arquitetural.
Como engenheiros de performance, não lidamos com "o sistema está lento". Lidamos com latência, filas e bloqueios. O comportamento de "travamento" do Windows virtualizado no KVM/QEMU (a base do Proxmox) é quase sempre um problema de serialização de I/O no loop principal do emulador.
Vamos dissecar o caminho do dado, do NTFS até o ZFS/LVM, e entender onde a física está colidindo com a configuração padrão.
O Sintoma não é o Problema: CPU Wait vs. IO Wait
O primeiro erro de diagnóstico é olhar para o gráfico de CPU do Proxmox e ver um pico, assumindo que a VM precisa de mais vCPUs.
Quando o Windows trava durante uma gravação de disco, o que você vê muitas vezes não é processamento real. É iowait ou tempo de interrupção. O Windows está gastando ciclos de CPU apenas esperando que o disco diga "estou pronto para a próxima instrução".
Dentro do Windows (Guest), abra o Monitor de Recursos. Se a Fila de Disco (Disk Queue Length) está alta (acima de 2 ou 3 consistentemente) e a Latência (Avg. Disk sec/Transfer) passa de 20-30ms, o sistema operacional entra em estado de estagnação. Ele bloqueia a UI porque o kernel está ocupado lidando com chamadas de sistema pendentes que o hypervisor ainda não entregou.
A Taxa de Tradução: A Morte pelo IDE/SATA
Se a sua VM está configurada com disco do tipo IDE ou SATA, você está cometendo um crime contra a performance.
Dispositivos IDE e SATA no KVM são emulados. Isso significa que cada vez que o Windows quer gravar um bit, o QEMU precisa interceptar essa instrução, fingir ser um controlador de hardware antigo, traduzir isso para uma chamada de sistema Linux, executar e devolver a resposta. Isso gera um overhead massivo de context switching (troca de contexto) na CPU do host.
A Solução: Use sempre VirtIO. O VirtIO não é uma emulação de hardware físico; é um driver paravirtualizado. O Windows (com os drivers VirtIO instalados) "sabe" que está em uma VM e joga os dados diretamente num anel de memória compartilhada que o Proxmox lê. Sem fingimento, sem tradução desnecessária.
O Bloqueio do Main Loop: Por que o Mouse Trava?
Aqui está a razão técnica pela qual uma cópia de arquivo (disco) faz o mouse (interface) travar.
Por padrão, o processo do QEMU que roda sua VM é single-threaded para a maioria das operações de I/O e gerenciamento de dispositivos. Existe algo chamado QEMU Main Loop. Esse loop é responsável por:
Atualizar a tela (VNC/SPICE).
Processar movimentos de mouse/teclado.
Gerenciar timers.
Processar I/O de disco (se mal configurado).
Quando você manda o Windows gravar 10GB de dados e não usa a configuração correta, o processamento desse I/O compete pelo mesmo ciclo de CPU que desenha o seu mouse. Se o disco engasga, o loop espera. Se o loop espera, o mouse não mexe.
Figura: O Efeito Gargalo: Sem iothreads, uma gravação pesada bloqueia o processo principal do QEMU, congelando até o movimento do mouse via VNC.
A Solução: IO Thread
No Proxmox, nas opções avançadas do disco, existe um checkbox chamado IO Thread.
Ao marcar essa opção, o QEMU cria uma thread separada dedicada exclusivamente para processar as requisições daquele disco virtual. O "Main Loop" fica livre para cuidar da interface e dos timers, enquanto o "IO Thread" sua a camisa gravando dados no storage.
Resultado prático: O disco pode estar saturado em 100%, mas o mouse continua fluido e o Windows responde aos cliques.
A Ilusão do Cache: Onde seus dados realmente estão?
A configuração de cache no Proxmox define a fronteira entre performance e segurança de dados. O Windows acha que gravou o arquivo, mas onde o dado está fisicamente?
1. No Cache (Default/O_DIRECT)
O dado sai do Windows, passa pelo QEMU, vai para o kernel do Linux e é enviado para o disco físico. O Proxmox só diz "OK, gravado" para o Windows quando o disco físico confirma.
Prós: Segurança máxima. Consistência de dados.
Contras: Lento se o storage físico for lento (HDDs mecânicos sem cache de gravação). Latência alta.
2. Writeback (A Mentira Útil)
O dado sai do Windows e chega na memória RAM do Host (Page Cache do Linux). O Proxmox diz imediatamente para o Windows: "OK, gravado!". O Windows fica feliz e manda o próximo bloco. O Linux grava no disco físico quando der (assincronamente).
Figura: A Mentira Útil: Como o modo 'Writeback' engana o Windows para performance, e o risco que você corre se a energia cair antes do flush.
Isso melhora drasticamente a percepção de velocidade e responsividade do Windows, pois a latência de gravação cai de milissegundos (disco) para nanossegundos (RAM).
O Risco: Se a energia cair e o servidor desligar antes do Linux esvaziar a RAM para o disco, você perde dados ou corrompe o sistema de arquivos NTFS.
O Veredito: Use Writeback apenas se você tiver um no-break (UPS) confiável e monitorado, ou se estiver usando um controlador RAID de hardware com bateria (BBU). Se estiver usando ZFS local com SSDs enterprise (que possuem capacitores de proteção contra perda de energia - PLP), o risco é mitigado, mas ainda existe no nível do SO.
Direct Sync: Uma alternativa para bancos de dados. Ignora o cache do host (como o 'No Cache'), mas garante que o dado esteja no prato do disco antes de retornar. É o mais lento, mas o único aceitável para SQL Server em produção crítica.
Protocolos: VirtIO-Block vs. VirtIO-SCSI
Você verá duas opções principais de barramento VirtIO:
VirtIO Block: Mais simples, menor overhead histórico.
VirtIO SCSI: Mais robusto, suporta mais comandos padrão SCSI.
Para Windows moderno sobre ZFS ou SSDs, a escolha deve ser VirtIO SCSI.
Por que? TRIM/Discard. O NTFS do Windows precisa informar ao storage subjacente quando um arquivo é deletado. Isso é feito via comando TRIM (ou UNMAP no mundo SCSI).
Se você não passar o comando TRIM, o ZFS (ou o SSD) acha que aqueles blocos ainda estão em uso.
Resultado: O arquivo de imagem da VM (zvol ou qcow2) cresce indefinidamente, a fragmentação aumenta e a performance de gravação degrada com o tempo.
O VirtIO SCSI tem suporte nativo e estável para passar comandos UNMAP do Windows para o Host. No Proxmox, marque a caixa Discard nas opções do disco. Sem isso, seu storage vira um cemitério de dados fantasmas.
Diagnóstico Prático: Medindo a Realidade
Como provar que o problema é I/O e não o Proxmox "sendo ruim"? Precisamos correlacionar métricas.
No Windows (Guest)
Abra o PowerShell como Admin e use o typeperf para uma amostragem rápida sem abrir interface gráfica pesada:
typeperf "\Disco Físico(_Total)\Comprimento Médio da Fila de Disco" "\Disco Físico(_Total)\Média de s/gravação" -sc 10
Comprimento da Fila (Queue Length): Se estiver acima de 1 por longos períodos, o storage não está acompanhando.
Média de s/gravação (Latency):
- < 0.010s (10ms): Excelente.
- 0.010s - 0.020s: Aceitável para carga pesada.
0.050s (50ms): Gargalo severo. O Windows vai começar a travar a interface.
No Proxmox (Host)
Se o Windows diz que a latência é alta, verifique se o Host concorda. Use o iostat (do pacote sysstat) para ver a latência real dos discos físicos:
# Observe a coluna w_await (wait time for writes)
iostat -x 1
Se o w_await no host for baixo (ex: 2ms), mas a latência no Windows for alta (ex: 100ms), o problema está na virtualização (falta de VirtIO, falta de IO Thread ou configuração de cache errada). Se o w_await no host for alto, seu disco físico atingiu o limite físico; nenhum ajuste de software resolverá isso.
Resumo da Configuração "Gold" para Windows
Para evitar o travamento da VM e garantir performance consistente, esta é a configuração base recomendada, assumindo que você possui proteção de energia (UPS):
| Parâmetro | Configuração Recomendada | Porquê |
|---|---|---|
| Bus/Device | VirtIO SCSI Single | Suporte melhor a TRIM/UNMAP e escalabilidade. |
| Cache | Writeback | Performance fluida de desktop. (Requer UPS/Bateria). |
| Discard | ON (Checked) | Permite ao Windows limpar blocos apagados no ZFS/SSD. |
| IO Thread | ON (Checked) | Evita que gravações travem o mouse/interface. |
| Async IO | io_uring (Kernel 5.13+) | API de I/O assíncrono mais moderna e rápida que native ou threads. |
Não aceite "travadinhas" como algo normal da virtualização. Elas são sintomas de um gargalo de I/O que pode e deve ser resolvido na arquitetura.
Elena Kovacs
Arquiteta de Cloud Infrastructure
Focada em NVMe-oF e storage definido por software. Projeta clusters de petabytes para grandes provedores de nuvem.