Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
O gerenciamento de buffer é um recurso que permite que os drivers de cliente da placa de interface de rede (NIC) e o sistema operacional trabalhem juntos ao alocar buffers de dados de pacotes da memória do sistema para os caminhos de dados de transmissão (Tx) e receção (Rx). Isso pode resultar em um desempenho mais rápido para a NIC, gerenciamento mais fácil do tempo de vida da memória para o driver cliente da NIC e mais controle para o sistema sobre a memória.
Os benefícios do gerenciamento de buffer no NetAdapterCx
A escolha de onde os buffers de dados são alocados da memória do sistema para cargas úteis de pacotes é crítica para o desempenho do caminho de dados. No NetAdapterCx, o modelo de gerenciamento de buffer é otimizado para hardware NIC compatível com DMA, e a melhor maneira de os drivers de cliente aproveitarem isso é permitir que o sistema aloque buffers de dados em seu nome para os caminhos Tx e Rx. No entanto, os drivers de cliente ainda podem influenciar onde e como o sistema aloca os buffers de dados para que eles possam ser facilmente consumidos pelo hardware do cliente.
Considere uma placa de rede típica compatível com DMA, por exemplo. Há vários benefícios nesta abordagem:
- Os buffers de dados são alocados e liberados pelo sistema. Portanto, o controlador do cliente é libertado do fardo da gestão do ciclo de vida da memória.
- O sistema assegura que os buffers de dados alocados estejam preparados para DMA no hardware da NIC, com base nas capacidades declaradas pelo driver cliente. Em seguida, o driver do cliente pode simplesmente programar os buffers de dados no hardware do cliente as-is sem executar quaisquer operações adicionais de mapeamento de DMA.
- O sistema pode levar em consideração as necessidades dos aplicativos de camada superior ao alocar os buffers de dados, para que possa decidir otimizar para desempenho global de ponta a ponta em vez de apenas desempenho local de ponta a ponta.
Para NICs não compatíveis com DMA, como um dongle de rede baseado em USB, ou para outras NICs avançadas/de software, o modelo de gerenciamento de buffer também fornece uma opção para deixar o gerenciamento de buffer de dados completamente para o driver do cliente.
Como aproveitar o gerenciamento de buffer
Importante
Se o hardware for compatível com DMA, você precisará criar um objeto WDFDMAENABLER antes de definir os recursos Rx e Tx. Ao configurar seu objeto WDFDMAENABLER com a estrutura WDF_DMA_ENABLER_CONFIG , certifique-se de definir o membro WdmDmaVersionOverride como 3 para especificar DMA versão 3.
Para aceitar o gerenciamento de buffer, siga estas etapas:
- Ao iniciar o adaptador de rede, mas antes de chamar NetAdapterStart, informe o sistema sobre os recursos e restrições do buffer de dados do hardware usando a estrutura de dados NET_ADAPTER_RX_CAPABILITIES e NET_ADAPTER_TX_CAPABILITIES para o caminho Rx e Tx, respectivamente.
- Inicialize as duas estruturas de recursos chamando uma das funções de inicialização. Por exemplo, um driver de cliente NIC compatível com DMA usaria NET_ADAPTER_TX_CAPABILITIES_INIT_FOR_DMA e NET_ADAPTER_RX_CAPABILITIES_INIT_SYSTEM_MANAGED_DMA para declarar suas capacidades de DMA de hardware e instruir o sistema a gerenciar totalmente os buffers de dados em seu nome.
- Passe as estruturas de recursos Tx e Rx inicializadas para o método NetAdapterSetDatapathCapabilities .
Exemplo
O exemplo a seguir ilustra as etapas básicas descritas na seção anterior sobre como começar a usar o gerenciador de buffer no driver do cliente NIC. O exemplo usa DMA para Tx e Rx, portanto, ele criou anteriormente um objeto WDFDMAENABLER que armazenou em seu espaço de contexto do dispositivo.
Observe que o exemplo também define algumas dicas sobre seus buffers de fragmento depois de inicializar as estruturas de recursos Tx e Rx. Essas dicas podem ser usadas pelo NetAdapterCx e drivers de protocolo para melhorar o desempenho.
O tratamento de erros foi deixado de lado por uma questão de clareza.
VOID
MyAdapterSetDatapathCapabilities(
_In_ NETADAPTER Adapter
)
{
// Get the device context
PMY_DEVICE_CONTEXT deviceContext = GetMyContextFromDevice(Adapter);
// Set various capabilities such as link layer MTU size, link layer capabilities, and power capabilities
...
// Initialize the Tx DMA capabilities structure
NET_ADAPTER_DMA_CAPABILITIES txDmaCapabilities;
NET_ADAPTER_DMA_CAPABILITIES_INIT(&txDmaCapabilities,
deviceContext->dmaEnabler);
// Set Tx capabilities
NET_ADAPTER_TX_CAPABILITIES txCapabilities;
NET_ADAPTER_TX_CAPABILITIES_INIT_FOR_DMA(&txCapabilities,
&txDmaCapabilities,
1);
txCapabilities.FragmentRingNumberOfElementsHint = deviceContext->NumTransmitControlBlocks * MAX_PHYS_BUF_COUNT;
txCapabilities.MaximumNumberOfFragments = MAX_PHYS_BUF_COUNT;
// Initialize the Rx DMA capabilities structure
NET_ADAPTER_DMA_CAPABILITIES rxDmaCapabilities;
NET_ADAPTER_DMA_CAPABILITIES_INIT(&rxDmaCapabilities,
deviceContext->dmaEnabler);
// Set Rx capabilities
NET_ADAPTER_RX_CAPABILITIES rxCapabilities;
NET_ADAPTER_RX_CAPABILITIES_INIT_SYSTEM_MANAGED_DMA(&rxCapabilities,
&rxDmaCapabilities,
MAX_PACKET_SIZE + FRAME_CRC_SIZE + RSVD_BUF_SIZE,
1);
rxCapabilities.FragmentBufferAlignment = 64;
rxCapabilities.FragmentRingNumberOfElementsHint = deviceContext->NumReceiveBuffers;
// Set the adapter's datapath capabilities
NetAdapterSetDatapathCapabilities(Adapter,
&txCapabilities,
&rxCapabilities);
}