Descritores de pacote e extensões
No NetAdapterCx, os descritores de pacote são estruturas pequenas, compactas e extensíveis de runtime que descrevem um pacote de rede. Cada pacote requer o seguinte:
- Um descritor principal
- Um ou mais descritores de fragmento
- Zero ou mais extensões de pacote
O descritor principal do pacote é a estrutura NET_PACKET . Ele contém apenas os metadados mais básicos aplicáveis a todos os pacotes, como o layout de enquadramento de um determinado pacote e o índice para o primeiro descritor de fragmento do pacote.
Cada pacote também deve ter um ou mais descritores de fragmento, ou estruturas NET_FRAGMENT , que descrevem o local na memória do sistema onde residem os dados do pacote.
As extensões são opcionais e mantêm metadados por pacote ou por fragmento para recursos específicos do cenário. Por exemplo, as extensões de pacote podem conter informações de descarregamento para soma de verificação, LSO (descarregamento de envio grande) e RSC (coalescência de segmento) ou podem conter detalhes específicos do aplicativo. Extensões de fragmento podem conter informações de endereço virtual, informações de endereço DMA lógico ou outras informações para o fragmento.
Juntos, esses descritores e extensões mantêm todos os metadados sobre um pacote de rede. Aqui estão dois exemplos de como eles descrevem um pacote. A primeira figura mostra um cenário em que todo o pacote é armazenado dentro de um único fragmento de memória e o descarregamento de soma de verificação foi ativado.
A segunda figura mostra um pacote armazenado em dois fragmentos de memória, com RSC e descarregamento de soma de verificação habilitados.
Armazenamento e acesso do descritor de pacotes
Descritores de pacote e descritores de fragmento são armazenados em estruturas de NET_RING . Um driver de cliente NIC acessa os anéis de rede e executa operações neles chamando para a Interface do Iterador net ring, que permite que o driver trabalhe com NetAdapterCx para postar dados de rede no hardware e esvaziar os dados concluídos de volta para o sistema operacional.
Para obter mais informações sobre anéis de rede e a Interface do Iterador net ring, consulte Introdução aos anéis de rede.
Extensibilidade do descritor de pacote
Extensibilidade é um recurso principal do descritor de pacotes NetAdapterCx, formando a base para a capacidade de versão e o desempenho do descritor. Em runtime, o sistema operacional aloca todos os descritores de pacotes para cada fila de pacotes em um bloco contíguo, juntamente com quaisquer extensões avaiveis. Cada bloco de extensão está imediatamente atrás do descritor principal, conforme mostrado na figura a seguir:
Os drivers de cliente NIC não têm permissão para codificar o deslocamento para qualquer bloco de extensão. Em vez disso, eles devem consultar em runtime o deslocamento para qualquer extensão específica. Por exemplo, um driver pode consultar o deslocamento para a Extensão B e obter de volta 70 bytes, como na figura a seguir:
Depois que uma fila de pacotes e seus descritores são criados, todos os deslocamentos de extensão são garantidos pelo sistema como constantes, para que os drivers não precisem consultar novamente os deslocamentos com frequência. Além disso, como todas as extensões são pré-alocadas pelo sistema em um bloco no momento em que a fila de pacotes é inicializada, não há necessidade de alocação de runtime de blocos, pesquisando uma lista para um descritor específico ou precisando armazenar ponteiros para cada extensão de pacote.
Capacidade de versão do descritor de pacote
O descritor de pacote principal do NetAdapterCx pode ser facilmente estendido em versões futuras adicionando novos campos ao final, como na figura a seguir:
Drivers de cliente mais recentes que sabem sobre os campos V2 podem acessá-los, enquanto os drivers V1 mais antigos usarão deslocamentos de extensão para ignorar os campos V2 para que possam acessar os campos que eles entendem. Além disso, cada extensão pode ser versão da mesma maneira, como mostra a figura a seguir:
Um driver de cliente que entende a nova extensão pode usá-la. Outros drivers de cliente podem ignorar os novos campos. Isso permite que diferentes partes do descritor de pacote sejam versão independentemente.
Descritores de pacote e desempenho de datapath
O recurso de extensibilidade descrito anteriormente oferece benefícios para ajudar os drivers cliente a atender aos requisitos de desempenho de NICs que são capabáveis de centenas de gigabits por segundo, com milhares de filas:
- Os descritores de pacote são mantidos o mais compactos possível para melhorar as ocorrências de cache de CPU, pois recursos e extensões que não são usados ocupam 0 bytes de espaço nos descritores.
- Não há desreferenciamento de ponteiro, apenas deslocamento aritmético porque as extensões estão em linha, o que não só economiza espaço, mas também ajuda com ocorrências de cache de CPU.
- As extensões são alocadas no momento da criação da fila, para que os drivers não precisem alocar e desalocar memória no caminho de dados ativo ou lidar com listas lookaside de blocos de contexto.
Usando extensões de pacote
Importante
Atualmente, os drivers de cliente estão limitados a extensões de pacote pré-existentes definidas pelo sistema operacional.
Registrando extensões de pacote
A primeira etapa para trabalhar com extensões de pacote no driver do cliente NIC é declarar seus descarregamentos de hardware com suporte. Quando você anuncia suporte para descarregamentos como soma de verificação e LSO, o NetAdapterCx registra automaticamente as extensões de pacote associadas em seu nome.
Para obter um exemplo de código de descarregamentos de hardware de publicidade, consulte Introdução aos descarregamentos de hardware.
Consultando deslocamentos de extensão de pacote para filas de datapath
Depois de registrar extensões de pacote declarando o suporte ao descarregamento de hardware, você precisará dos deslocamentos de extensão para acessar cada uma delas enquanto processa seus pacotes. Para reduzir as chamadas do driver e melhorar o desempenho, você pode consultar os deslocamentos das extensões durante a função de retorno de chamada EvtNetAdapterCreateTx(Rx)Queue e armazenar as informações de deslocamento no contexto da fila.
Para obter um exemplo de como consultar deslocamentos de extensão e armazená-los no contexto da fila, consulte Transmitir e receber filas.
Obtendo extensões de pacote em runtime
Depois de armazenar deslocamentos de extensão no contexto da fila, você pode usá-los sempre que precisar de informações em uma extensão. Por exemplo, você pode chamar o método NetExtensionGetPacketChecksum enquanto programa descritores para hardware para uma fila de transmissão:
// Get the extension offset from the device context
PMY_TX_QUEUE_CONTEXT queueContext = GetMyTxQueueContext(txQueue);
NET_EXTENSION checksumExtension = queueContext->ChecksumExtension;
// Get the checksum info for this packet
NET_PACKET_CHECKSUM* checksumInfo = NetExtensionGetPacketChecksum(checksumExtension, packetIndex);
// Do work with the checksum info
if (packet->Layout.Layer3Type == NET_PACKET_LAYER3_TYPE_IPV4_NO_OPTIONS ||
packet->Layout.Layer3Type == NET_PACKET_LAYER3_TYPE_IPV4_WITH_OPTIONS ||
packet->Layout.Layer3Type == NET_PACKET_LAYER3_TYPE_IPV4_UNSPECIFIED_OPTIONS)
{
if(checksumInfo->Layer4 == NET_PACKET_TX_CHECKSUM_REQUIRED)
{
...
}
}
...
Constantes de extensão de pacote predefinidas e métodos auxiliares
NetAdapterCx fornece definições para constantes de extensão de pacote conhecidas.
Constante | Definição |
---|---|
NET_PACKET_EXTENSION_INVALID_OFFSET | Protege contra tamanhos de deslocamento inválidos. |
NET_PACKET_EXTENSION_CHECKSUM_NAME NET_PACKET_EXTENSION_CHECKSUM_VERSION_1 | O nome e a versão da extensão de pacote de soma de verificação. |
NET_PACKET_EXTENSION_LSO_NAME NET_PACKET_EXTENSION_LSO_VERSION_1 | O nome e a versão da extensão de pacote de envio grande (LSO). |
NET_PACKET_EXTENSION_RSC_NAME NET_PACKET_EXTENSION_RSC_VERSION_1 | O nome e a versão da extensão de pacote RSC (coalescência do segmento de recebimento). |
Além disso, NetAdapterCx fornece métodos auxiliares que atuam como wrappers ao redor do método NetExtensionGetData . Cada um desses métodos retorna um ponteiro para o tipo apropriado de estrutura.
Método | Estrutura |
---|---|
NetExtensionGetPacketChecksum | NET_PACKET_CHECKSUM |
NetExtensionGetGso | NET_PACKET_GSO |
NetExtensionGetPacketRsc | NET_PACKET_RSC |
Usando extensões de fragmento
Importante
Atualmente, os drivers de cliente estão limitados a extensões de fragmento pré-existentes definidas pelo sistema operacional.
Registrando extensões de fragmento
O NetAdapterCx registra automaticamente a maioria das extensões de fragmento interpretando os recursos expressos de um driver. Por exemplo, se o driver expressar que dá suporte ao DMA, a estrutura adicionará automaticamente a extensão NET_FRAGMENT_LOGICAL_ADDRESS necessária para programação de DMA.
Consultando deslocamentos de extensão de fragmento para filas de datapath
Para acessar extensões de fragmento, você pode seguir o mesmo processo para acessar extensões de pacote descritas em Consultar deslocamentos de extensão de pacote para filas de datapath.
Constantes de extensão de fragmento predefinidas
NetAdapterCx fornece definições para constantes de extensão de fragmento conhecidas.
Constante | Definição |
---|---|
NET_FRAGMENT_EXTENSION_DATA_BUFFER_NAME NET_FRAGMENT_EXTENSION_DATA_BUFFER_VERSION_1 | O nome e a versão da extensão de fragmento do buffer de dados. |
NET_FRAGMENT_EXTENSION_LOGICAL_ADDRESS_NAME NET_FRAGMENT_EXTENSION_LOGICAL_ADDRESS_VERSION_1 | O nome e a versão da extensão de fragmento de endereço lógico. |
NET_FRAGMENT_EXTENSION_MDL_NAME NET_FRAGMENT_EXTENSION_MDL_VERSION_1 | O nome e a versão da extensão de fragmento MDL. |
NET_FRAGMENT_EXTENSION_RETURN_CONTEXT_NAME NET_FRAGMENT_EXTENSION_RETURN_CONTEXT_VERSION_1 | O nome e a versão da extensão de fragmento de contexto de retorno. |
NET_FRAGMENT_EXTENSION_VIRTUAL_ADDRESS_NAME NET_FRAGMENT_EXTENSION_VIRTUAL_ADDRESS_VERSION_1 | O nome e a versão da extensão de fragmento de endereço virtual. |