UDP recebem descarga coalescente de segmento (URO)
A partir do Windows 11, versão 24H2, o UDP receive segment coalescing offload (URO) permite que placas de interface de rede (NICs) coalescam segmentos de recebimento UDP. As NICs podem combinar datagramas UDP do mesmo fluxo que correspondem a um conjunto de regras em um buffer logicamente contíguo. Esses datagramas combinados são então indicados para a pilha de rede do Windows como um único pacote grande.
A coalescência de datagramas UDP reduz o custo da CPU para processar pacotes em fluxos de alta largura de banda, resultando em maior taxa de transferência e menos ciclos por byte.
As seções a seguir descrevem as regras para aglutinar pacotes UDP e como escrever um driver de miniporta URO.
- Regras para aglutinação de pacotes UDP
- Escreva um driver de miniporta URO
- Considerações de Programação para Drivers URO
Regras para aglutinar pacotes UDP
A coalescência URO só pode ser tentada em pacotes que atendam a todos os seguintes critérios:
-
IpHeader.Version
é idêntico para todos os pacotes. -
IpHeader.SourceAddress
eIpHeader.DestinationAddress
são idênticos para todos os pacotes. -
UdpHeader.SourcePort
eUdpHeader.DestinationPort
são idênticos para todos os pacotes. -
UdpHeader.Length
é idêntico para todos os pacotes, exceto o último pacote, que pode ser menor. -
UdpHeader.Length
deve ser diferente de zero. -
UdpHeader.Checksum
, se for diferente de zero, deve estar correto em todos os pacotes. Isso significa que o descarregamento da soma de verificação de recebimento deve validar o pacote. -
Layer 2 headers
deve ser idêntico para todos os pacotes.
Se os pacotes forem IPv4, eles também devem atender aos seguintes critérios:
-
IPv4Header.Protocol
== 17 (UDP) para todos os pacotes. -
EthernetHeader.EtherType
== 0x0800 para todos os pacotes. - O
IPv4Header.HeaderChecksum
no pacote recebido deve estar correto. Isso significa que receber o descarregamento da soma de verificação deve validar o cabeçalho. -
IPv4Header.HeaderLength
== 5 (sem cabeçalhos de opção IPv4) para todos os pacotes. -
IPv4Header.ToS
é idêntico para todos os pacotes. -
IPv4Header.ECN
é idêntico para todos os pacotes. -
IPv4Header.DontFragment
é idêntico para todos os pacotes. -
IPv4Header.TTL
é idêntico para todos os pacotes. -
IPv4Header.TotalLength
==UdpHeader.Length
* + comprimento(IPv4Header
) para todos os pacotes.
Se os pacotes forem IPv6, eles também devem atender aos seguintes critérios:
-
IPv6Header.NextHeader
== 17 (UDP) para todos os pacotes (sem cabeçalhos de extensão). -
EthernetHeader.EtherType
== 0x86dd (IPv6) para todos os pacotes. -
IPv6Header.TrafficClass
eIPv6Header.ECN
são idênticos para todos os pacotes. -
IPv6Header.FlowLabel
é idêntico para todos os pacotes. -
IPv6Header.HopLimit
é idêntico para todos os pacotes. -
IPv6Header.PayloadLength
==UdpHeader.Length
para todos os pacotes.
Estrutura de pacotes URO
A unidade única coalescida (SCU) resultante deve ter um único cabeçalho IP e um cabeçalho UDP, seguidos pela carga útil UDP para todos os datagramas coalescentes concatenados.
As indicações URO devem definir o campo IPv4Header.TotalLength
para o comprimento total da SCU, o campo IPv6Header.PayloadLength
para o comprimento da carga útil UDP e o campo UdpHeader.Length
para o comprimento das cargas úteis coalescidas.
Se os cabeçalhos de Camada 2 (L2) estiverem presentes em datagramas coalescidos, a SCU deverá conter um cabeçalho L2 válido. O cabeçalho L2 na SCU deve ser semelhante ao cabeçalho L2 dos datagramas coalescidos.
Validação e indicação do checksum
As indicações URO devem definir os campos IPv4Header.HeaderChecksum
e UdpHeader.Checksum
como zero e preencher as informações de descarregamento fora de banda da soma de verificação na SCU indicando o sucesso da soma de verificação IPv4 e UDP.
Um pacote que corresponda a todas as condições para ser coalescido, mas que não seja validado pela soma de verificação, deve ser indicado separadamente. Os pacotes recebidos após não devem ser agrupados com os pacotes recebidos antes.
Por exemplo, suponha que os pacotes 1, 2, 3, 4 e 5 sejam recebidos do mesmo fluxo, mas o pacote 3 falhe na validação da soma de verificação. Os pacotes 1 e 2 podem ser aglutinados, e os pacotes 4 e 5 podem ser aglutinados, mas o pacote 3 não deve ser aglutinado com nenhum dos SCU. Os pacotes 1 e 2 não devem ser aglutinados com os pacotes 4 e 5. O pacote 2 é o último pacote em uma SCU e o pacote 4 inicia uma nova SCU. Além disso, o SCU que contém os pacotes 1 e 2 deve ser indicado antes da indicação do pacote 3 e o pacote 3 deve ser indicado antes do SCU que contém os pacotes 4 e 5.
Coalescência de pacotes e separação de fluxo
Os pacotes de vários fluxos podem ser aglutinados em paralelo, conforme o hardware e a memória permitirem. Os pacotes provenientes de fluxos diferentes não devem ser aglutinados.
Os pacotes de múltiplos recebíveis intercalados podem ser separados e aglutinados com seus respetivos fluxos. Por exemplo, dados os fluxos A, B e C, se os pacotes chegassem na ordem A, A, B, C, B, A, os pacotes do fluxo A podem ser aglutinados em AAA, e os pacotes do fluxo B aglutinados em BB, enquanto o pacote do fluxo C pode ser indicado normalmente ou aglutinado com uma SCU pendente do fluxo C.
Os pacotes dentro de um determinado fluxo não devem ser reordenados uns em relação aos outros. Por exemplo, os pacotes do fluxo A devem ser aglutinados na ordem recebida, independentemente dos pacotes dos fluxos B e C recebidos entre eles.
Palavra-chave INF para controlar URO
A seguinte palavra-chave pode ser usada para ativar/desativar o URO com uma configuração de chave do Registro:
*UdpRsc
As palavras-chave INF padronizadas pela enumeração têm os seguintes atributos:
SubkeyName: O nome da palavra-chave que você deve especificar no arquivo INF e que aparece no registro.
ParamDesc: O texto de exibição associado a SubkeyName.
Valor: O valor inteiro de enumeração associado a cada opção na lista. Esse valor é armazenado em NDI\params\SubkeyName\Value.
EnumDesc: O texto de exibição associado a cada valor que aparece no menu.
Default: O valor padrão para o menu.
Nome da subchave | ParamDesc | Valor | EnumDesc |
---|---|---|---|
*UdpRsc |
URO | 0 | Desabilitado |
1 (Padrão) | Ativado |
Para obter mais informações sobre como usar palavras-chave de enumeração, consulte Palavras-chave de enumeração.
Escrever um controlador de miniporta URO
A partir do NDIS 6.89, a interface NDIS para URO facilita a comunicação entre o TCP/IP e o driver de miniporta NDIS.
Capacidade de relatório URO
Um driver de miniporta anuncia suporte para URO no membro
Capacidade de consulta URO
Para verificar se um driver de miniporta suporta URO, os drivers NDIS e outras aplicações podem consultar os OIDs OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES OID, que retornam a estrutura NDIS_OFFLOAD
.
Consultar estado URO
Para determinar o estado atual do URO, os controladores NDIS e outras aplicações podem consultar a solicitação OID OID_TCP_OFFLOAD_CURRENT_CONFIG. O NDIS lida com esse OID e não o transmite para a miniporta.
Alterar o estado do URO
O URO pode ser ativado ou desativado emitindo a solicitação OID_TCP_OFFLOAD_PARAMETERS OID. Este OID usa uma estrutura NDIS_OFFLOAD_PARAMETERS. Nesta estrutura, o membro UdpRsc.Enabled
pode ter os seguintes valores:
Valor | Significado |
---|---|
NDIS_OFFLOAD_PARAMETERS_UDP_RSC_NO_CHANGE 0 |
O driver da miniporta não deve alterar a configuração atual. |
NDIS_OFFLOAD_PARAMETERS_UDP_RSC_DISABLED 1 |
O URO está desativado. |
NDIS_OFFLOAD_PARAMETERS_UDP_RSC_ENABLED 2 |
O URO está ativado. |
Quando um driver processa uma solicitação OID OID_TCP_OFFLOAD_PARAMETERS com o sinalizador NDIS_OFFLOAD_PARAMETERS_UDP_RSC_DISABLED
definido, a NIC deve esperar para concluir a solicitação até que todos os segmentos coalescidos existentes e as indicações URO pendentes sejam sinalizadas. Isso garante a sincronização de eventos de habilitação/desativação do URO entre os componentes NDIS.
Depois que o driver de miniporta processar a solicitação de OID de OID_TCP_OFFLOAD_PARAMETERS, o driver de miniporta deve emitir uma indicação de status de NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG com o estado de descarregamento atualizado.
O sinalizador NDIS_OFFLOAD_PARAMETERS_SKIP_REGISTRY_UPDATE
em NDIS_OFFLOAD_PARAMETERS permite a desativação do URO somente em tempo de execução. As alterações feitas com esse sinalizador não são salvas no registro.
Desativação do URO no NDIS 6.89 e posterior
Os drivers que visam o NDIS 6.89 e posterior devem entender os pacotes URO e manipulá-los de forma eficiente. Para optar por não participar da URO:
- Os drivers de filtro leve (LWF) definem o sinalizador de
NDIS_FILTER_DRIVER_UDP_RSC_NOT_SUPPORTED
na estrutura NDIS_FILTER_DRIVER_CHARACTERISTICS. - Os drivers de protocolo configuram o indicador
NDIS_PROTOCOL_DRIVER_UDP_RSC_NOT_SUPPORTED
na estrutura NDIS_PROTOCOL_DRIVER_CHARACTERISTICS.
Essa abordagem garante que os componentes que não estejam familiarizados com o URO não recebam NBLs de URO. O NDIS desativa o URO na miniporta durante a vinculação se um driver de protocolo ou LWF que não suporta URO estiver presente.
Considerações de programação para drivers URO
Considere os seguintes problemas ao implementar um driver de miniporta compatível com URO.
Winsock URO API
Para obter informações sobre a API Winsock URO, consulte IPPROTO_UDP opções de soquete. Consulte as informações sobre UDP_RECV_MAX_COALESCED_SIZE
e UDP_COALESCED_INFO
.
Atualizações de pilha de TCP/IP do Windows
O transporte TCP/IP da Microsoft habilita o URO no momento da ligação com NDIS, a menos que a configuração impeça isso.
Os textos explicativos do PMA podem usar FWP_CALLOUT_FLAG_ALLOW_URO
em FWPS_CALLOUT2 para anunciar o seu apoio à URO. Se um módulo WFP incompatível for registado numa camada sensível ao URO, o sistema operativo desativará o URO enquanto o módulo estiver registado.
Se um soquete optar por URO com um tamanho máximo coalesced maior ou igual ao tamanho de descarregamento de hardware, a pilha entregará os NBLs do hardware não modificado para o soquete. Se um socket optar por um tamanho máximo agregado menor, a pilha divide o recebimento combinado no tamanho menor para o socket.
Se um soquete não optar por URO, a pilha resegmenta os recebimentos para esse soquete. Na ausência de hardware URO, o recurso de software URO existente continua disponível.