O IOMMU é muito útil porque fornece um conjunto de registos de mapeamento.Ele pode fazer com que qualquer memória física apareça dentro do intervalo de endereços acessível por um dispositivo e também pode fazer com que buffers fisicamente dispersos pareçam contíguos aos dispositivos.Isso não é bom para placas PCI/PCI-Express de terceiros ou máquinas remotas que tentam acessar o deslocamento físico bruto de uma GPU nVidia, pois isso pode resultar em não na verdade acessar as regiões de memória pretendidas ou inibir/restringir tais acessos por cartão pela unidade IOMMU.Isso deve ser desabilitado, então, porque
"RDMA para GPUDirect atualmente depende de todas as moradas físicas a serem o mesmo do ponto de vista dos dispositivos PCI."
Quando os drivers tentam utilizar a MMU da CPU e mapear regiões de E/S mapeada de memória (MMIO) para uso no espaço do kernel, eles normalmente mantêm o endereço retornado do mapeamento de memória para si mesmos.Como cada driver opera dentro de seu próprio contexto ou namespace, a troca desses mapeamentos entre os drivers da nVidia e os drivers de outros fornecedores terceirizados que desejam suportar rDMA+GPUDirect seria muito difícil e resultaria em uma solução específica do fornecedor (possivelmente até mesmo produto -específico se os drivers variarem muito entre produtos de terceiros).Além disso, os sistemas operacionais atuais não têm nenhuma boa solução para a troca de mapeamentos MMIO entre drivers, portanto, a nVidia exporta várias funções que permitem que drivers de terceiros acessem facilmente essas informações a partir do próprio espaço do kernel.
A nVidia impõe o uso de “endereçamento físico” para acessar cada placa via rDMA para GPUDirect.Isto simplifica muito o processo de movimentação de dados de um computador para um barramento PCI-Express de um sistema remoto, usando o esquema de endereçamento físico dessa máquina sem ter que se preocupar com problemas relacionados ao endereçamento virtual (por exemplo,resolução de endereços virtuais para físicos).Cada cartão possui um endereço físico no qual reside e pode ser acessado nesse deslocamento;apenas um pequeno pedaço de lógica deve ser adicionado ao driver de terceiros que tenta executar operações rDMA.Além disso, esses registradores de endereço base de 32 ou 64 bits fazem parte do espaço de configuração PCI padrão, portanto, o endereço físico da placa pode ser facilmente obtido simplesmente lendo seus BARs, em vez de ter que obter um endereço mapeado obtido pelo driver da nVidia. ao anexar ao cartão.O Universal Virtual Addressing (UVA) da nVidia cuida dos mapeamentos de endereços físicos mencionados acima para uma região de memória aparentemente contígua para espaço do usuário aplicativos, assim:
Essas regiões de memória são divididas em três tipos:CPU, GPU e FREE, todos documentados aqui.
Porém, voltando ao seu caso de uso:já que você está em espaço do usuário, você não tem acesso direto ao espaço de endereço físico do sistema e os endereços que está usando provavelmente são endereços virtuais fornecidos pelo UVA da nVidia.Supondo que nenhuma alocação anterior tenha sido feita, sua alocação de memória deve residir no deslocamento +0x00000000, o que resultaria na visualização do mesmo deslocamento da própria GPU.Se você alocasse um segundo buffer, imagino que veria esse buffer iniciar imediatamente após o final do primeiro buffer (no deslocamento +0x00100000 da base endereço virtual da GPU no seu caso de alocações de 1 MB).
Se você estivesse em espaço do kernel, no entanto, e estivesse escrevendo um driver para a placa da sua empresa para utilizar rDMA para GPUDirect, você usaria os endereços físicos de 32 ou 64 bits atribuídos à GPU pelo BIOS e/ou sistema operacional do sistema para dados rDMA diretamente de e para o GPU em si.
Além disso, pode ser interessante notar que nem todos os mecanismos DMA realmente suportam endereços virtuais para transferências - na verdade, a maioria requer endereços físicos, como o tratamento de endereçamento virtual de um mecanismo DMA pode ficar complexo (página 7), portanto, muitos mecanismos DMA não têm suporte para isso.
Para responder à pergunta do título da sua postagem:Atualmente, a nVidia suporta apenas endereçamento físico para rDMA+GPUDirect no espaço do kernel.Para espaço do usuário aplicativos, você sempre usará o endereço virtual da GPU fornecido pelo UVA da nVidia, que está no espaço de endereço virtual da CPU.
Em relação ao seu aplicativo, aqui está um detalhamento simplificado do processo que você pode executar para operações rDMA:
- Seu espaço do usuário O aplicativo cria buffers, que estão no escopo do espaço de endereçamento virtual unificado que a nVidia fornece (endereços virtuais).
- Faça uma chamada para
cuPointerGetAttribute(...)
para obter tokens P2P;esses tokens pertencem à memória dentro do contexto do CUDA. - Envie todas essas informações para espaço do kernel de alguma forma (por ex.IOCTL, leitura/gravação em seu driver, etc).No mínimo, você vai querer que essas três coisas acabem em seu espaço do kernel motorista:
- Token(s) P2P retornado(s) por
cuPointerGetAttribute(...)
- Endereço(s) virtual(es) UVA do(s) buffer(s)
- Tamanho do(s) buffer(es)
- Token(s) P2P retornado(s) por
- Agora traduza esses endereços virtuais para seus endereços físicos correspondentes chamando as funções de espaço do kernel da nVidia, já que esses endereços são mantidos nas tabelas de páginas da nVidia e podem ser acessados com as funções exportadas da nVidia, como:
nvidia_p2p_get_pages(...)
,nvidia_p2p_put_pages(...)
, envidia_p2p_free_page_table(...)
. - Use esses endereços físicos adquiridos na etapa anterior para inicializar seu mecanismo DMA que manipulará esses buffers.
Uma explicação mais aprofundada deste processo pode ser encontrada aqui.