A AMD publicou uma série de patches (v2, 0/4) para o amdkfd que mira diretamente um gargalo clássico de virtualização: o custo de registrar milhares de pedaços de memória espalhados, um por um, dentro de um guest KVM.
Nos números reportados na própria série, a mudança sai de um cenário em que a performance despenca para ~80.000 pontos (vs ~200.000 no bare metal) e chega a 160.000–190.000, recuperando até 95% do desempenho “quase nativo”. O ganho declarado fica entre 2x e 2,4x contra a solução alternativa em userspace.
Entenda em 90 segundos
Em VMs, o padrão de alocação de memória costuma ficar mais “quebrado”: em vez de um bloco grande e contínuo, a aplicação frequentemente termina com milhares de ranges não contíguos de VA da CPU.
No método antigo (workaround em userspace), cada pedaço exigia uma “viagem” separada ao kernel para registrar o range via IOCTL, repetindo o custo de syscalls.
A analogia visual: imagine um correio entregando 1000 cartas, indo e voltando uma por uma (approach antigo), versus entregar um malote consolidado com tudo de uma vez (approach batch no kernel). O conteúdo é o mesmo, o custo logístico não.
O problema na prática: syscall hell
A própria descrição do patch aponta um padrão comum em workloads modernos: alocações “scattered” vindas de malloc() podem gerar de 2 até 4000+ ranges.
Quando o processo tenta registrar esses ranges individualmente no guest KVM usando múltiplas chamadas à IOCTL existente AMDKFD_IOC_ALLOC_MEMORY_OF_GPU, o custo acumulado de syscalls vira o gargalo.
Os números compartilhados a lista do kernel resumem bem o impacto:
- Bare metal (baseline): ~200.000
- Workaround em userspace (múltiplas IOCTLs): ~80.000
- Perda reportada: 60% de degradação
- Com batch no kernel: 160.000–190.000
- Recuperação: 80%–95% do bare metal
Deep dive técnico: HMM vs. pinning
A v2 é, por intenção, um “reset” conceitual em relação à v1. A primeira tentativa tentou resolver via SVM e acabou esbarrando em consequências indesejadas para paginação e gerenciamento de memória.
Por que a v1 falhou, segundo a própria série
A v1 propunha:
- Nova IOCTL:
AMDKFD_IOC_SVM_RANGES - Atributo:
KFD_IOCTL_SVM_ATTR_MAPPEDpara VMA especial - Fixação de páginas:
pin_user_pages_fast()
E lista problemas diretos desse caminho:
- O pinning “derrotava” o propósito de SVM com HMM, que depende de paginação sob demanda.
- Bloqueava oversubscription e migração dinâmica.
- Podia gerar pressão de memória por páginas travadas.
- Interferia com otimizações de NUMA e migração.
O que a v2 faz diferente
A v2 desloca a solução para a infraestrutura já existente de userptr, estendendo o caminho de ALLOC_MEMORY_OF_GPU em vez de mexer no SVM, e introduz a nova IOCTL:
AMDKFD_IOC_ALLOC_MEMORY_OF_GPU_BATCH
A promessa técnica central é: “sem pinning”. Em vez de travar páginas, a v2 usa HMM para rastrear e validar páginas, mantendo a capacidade de páginas serem swapadas ou migradas quando não estão em uso.
Os pontos de implementação destacados no texto-fonte:
- Um
mmu_interval_notifierpor range de CPU VA, para invalidação por intervalo. - Todos os ranges são validados em conjunto e mapeados para um GPU VA contíguo.
- Um único objeto
kgd_mem, contendo um array deuser_range_info, para rastrear múltiplos ranges em uma alocação. - Caminho unificado de eviction/restore para o batch.
Modelo mental: muitos VAs de CPU viram um VA de GPU
A série descreve exatamente este remapeamento como o “encaixe” do userptr:
- Entrada: vários ranges de CPU VA não contíguos.
- Saída: um único range de GPU VA contíguo.
Em outras palavras, a GPU enxerga uma janela linear, enquanto a CPU continua vivendo com o layout fragmentado típico do processo no guest. O batch serve para registrar esse “mosaico” sem pagar a tarifa de syscall em cada ladrilho.
Contexto de mercado e workloads
O texto-fonte posiciona a mudança como relevante para cenários de IA em virtualização, incluindo workloads e testes específicos:
- Stable Diffusion e ComfyUI em ambientes virtualizados
- Inferência de LLMs 3B–7B com HuggingFace transformers
- OpenCL CTS e HIP catch tests em KVM guest
Há também um ponto arquitetural importante para infraestrutura: ao evitar pinning e usar HMM, a abordagem preserva propriedades necessárias para ambientes com pressão de memória, como eviction/restore e a possibilidade de páginas serem migradas.
O texto-fonte conecta isso diretamente a um objetivo operacional: evitar que a otimização de GPU em VM force páginas a ficarem permanentemente travadas, algo que dificultaria oversubscription e migração dinâmica.
O que muda para quem usa
Se você roda workloads de GPU em guest KVM, a série descreve impactos práticos na forma como o registro de memória “scattered” pode ser feito:
- Reduz o overhead de syscalls ao registrar ranges não contíguos em batch via
AMDKFD_IOC_ALLOC_MEMORY_OF_GPU_BATCH. - Recupera performance em virtualização, nos números reportados, para a faixa de 80%–95% do bare metal.
- Evita pinning de memória, mantendo páginas swapáveis/migráveis sob HMM.
- Unifica o gerenciamento de múltiplos ranges em um único
kgd_memcomuser_range_info. - Mantém invalidação por range via
mmu_interval_notifier, alinhada ao modelo de consistência do userptr.
Pontos explícitos que não aparecem na fonte e, portanto, ficam fora do escopo factual:
- Requisitos de configuração específicos (QEMU, VFIO, passthrough, flags): [NÃO INFORMADO NA FONTE]
- GPUs e SKUs impactadas, ou versões mínimas de ROCm/kernel necessárias: [NÃO INFORMADO NA FONTE]
- Prazo de merge, árvore alvo, ou presença em releases do kernel: [NÃO INFORMADO NA FONTE]
Mini-glossário
- Userptr: modelo em que o driver trabalha com ponteiros para endereços do espaço de usuário, permitindo remapeamento de VA de CPU para VA de GPU.
- HMM (Heterogeneous Memory Management): infraestrutura do kernel para rastreamento e integração de memória entre CPU e dispositivos, apoiando paginação sob demanda.
- IOCTL: chamada de controle entre userspace e kernel para executar operações específicas de um driver.
- Syscall overhead: custo de transição userspace→kernel, que se torna relevante quando repetido milhares de vezes.
- KVM guest: sistema operacional convidado rodando sob o hypervisor KVM.
