Compartilhar via


OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES

Aviso

Algumas informações neste tópico estão relacionadas ao produto pré-relacionado, que pode ser substancialmente modificado antes de ser lançado comercialmente. A Microsoft não oferece garantias, expressas ou implícitas, das informações aqui fornecidas.

O RSSv2 é visualizado apenas em Windows 10, versão 1809.

O OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES OID é enviado para drivers de miniporta compatíveis com RSSv2 para executar movimentações de entradas de tabela de indireção individuais. Esse OID é um OID síncrono, o que significa que não pode retornar NDIS_STATUS_PENDING. Ele é emitido apenas como uma solicitação de método, em IRQL == DISPATCH_LEVEL.

Essa chamada usa o ponto de entrada XxxSynchronousOidRequest , em que Xxx é Miniport ou Filter , dependendo do tipo de driver que recebe a solicitação. Esse ponto de entrada causará um bug do sistema marcar se ele vir um NDIS_STATUS_PENDING retornar status.

OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES usa a estrutura NDIS_RSS_SET_INDIRECTION_ENTRIES para instruir um adaptador de miniporto a executar de forma síncrona um conjunto de ações, em que cada ação move uma única entrada da tabela de indireção RSS de um VPort especificado para uma CPU especificada de destino.

Comentários

Esse OID deve ser executado e concluído no contexto do processador que o emitiu. Os drivers de miniporta devem executar totalmente esse OID ao retornar NDIS_STATUS_SUCCESS para a camada superior. Isso significa que o driver de miniporto deve estar preparado para receber solicitações de OID back-to-back para mover vários ITEs em um novo processador imediatamente após a conclusão do primeiro movimento com NDIS_STATUS_SUCCESS.

Dica

Executar totalmente esse OID significa que o driver de miniporto deve estar pronto para tentar outra ação com êxito para mover um ITE. Ele não prescreve onde o tráfego de recebimento em andamento é indicado logo após a movimentação da fila, que pode estar na CPU de origem ou na CPU de destino.

Os protocolos de camada superior emitem OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES para definir ITEs e/ou os parâmetros de processador primários e padrão para apontar para processadores diferentes.

Esse OID pode ser emitido para parâmetros de direção de tráfego ativos ou inativos . Para obter mais informações sobre parâmetros de direção, consulte Receive side scaling version 2 (RSSv2). Para parâmetros/ITEs no estado inativo , o driver de miniporte deve validar e armazenar em cache o processador de destino até a próxima alteração de estado RSS relevante (habilitação ou desabilitação). Nesse ponto, os números de processador armazenados em cache ficam ativos e são usados para direcionar o tráfego. Atualizações para parâmetros ativos (que também devem ser validados) devem ser imediatamente colocados em vigor para direcionar o tráfego.

OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES deve ser emitido para um adaptador de miniporta com o sinalizador NDIS_OID_REQUEST_FLAGS_VPORT_ID_VALID limpo. Isso ocorre devido à possibilidade de diferentes VPorts serem referenciados por elementos diferentes na matriz.

Esse OID é invocado apenas em IRQL == DISPATCH_LEVEL.

Os drivers de miniporta devem estar preparados para lidar com pelo menos quantas ações de movimentação de entrada de tabela de indireção forem anunciadas na estrutura NDIS_NIC_SWITCH_CAPABILITIES . Isso é definido no membro NumberOfIndirectionTableEntriesPerNonDefaultPFVPort ou NumberOfIndirectionTableEntriesForDefaultVPort dessa estrutura ou 128 no modo RSS nativo.

Os drivers de miniport devem tentar executar o máximo de entradas possível e atualizar o membro EntryStatus de cada NDIS_RSS_SET_INDIRECTION_ENTRY com o resultado da operação.

Manipulador de OID para OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES

Espera-se que o manipulador de OID para OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES se comporte da seguinte maneira:

  • Um retorno de NDIS_STATUS_PENDING não é permitido devido ao tipo de chamada síncrona do OID.
  • Finalize todas as movimentações de ITE de entrada destinadas à CPU atual (iniciada anteriormente em processadores remotos).
  • É altamente recomendável que os drivers de miniporto executem uma aprovação de validação de parâmetro completa. Se não for possível, execute a validação um por um e a execução de entradas de matriz. Os drivers de miniport devem marcar especificamente se todos os objetos referenciados forem válidos:
    • Não é permitido retornar NDIS_STATUS_PENDING no campo EntryStatus para um ITE.
    • O adaptador de miniporta existe e está em um bom estado. Caso contrário, defina o campo EntryStatus da entrada como NDIS_STATUS_ADAPTER_NOT_FOUND, NDIS_STATUS_ADAPTER_NOT_READY etc.
    • Cada VPort existe e está em um bom estado. Caso contrário, defina o campo EntryStatus da entrada como NDIS_STATUS_INVALID_PORT, NDIS_STATUS_INVALID_PORT_STATE etc.
    • Cada índice de entrada da tabela de indireção está dentro do intervalo configurado. Esse intervalo é 0xFFFF ou está no intervalo [0...NumberOfIndirectionTableEntries - 1] definido pelo OID_GEN_RECEIVE_SCALE_PARAMETERS_V2 OID. Os índices de entrada 0xFFFF e 0xFFFE têm significados especiais: 0xFFFF define o processador padrão, enquanto 0xFFFE define o processador primário. Em caso de erro, o manipulador define o campo EntryStatus da entrada como NDIS_STATUS_INVALID_PARAMETER.
    • A camada superior e o driver de miniporto esperam que o ITE aponte para o processador atual (CPU do ator) antes da movimentação. Em outras palavras, o ITE não pode ser redirecionado remotamente. Se isso não for verdadeiro, defina o campo EntryStatus da entrada como NDIS_STATUS_NOT_ACCEPTED.
    • Todos os processadores de destino são válidos e fazem parte do conjunto RSS do adaptador de miniport. Caso contrário, defina o campo EntryStatus da entrada como NDIS_STATUS_INVALID_DATA.
  • Posteriormente ou como parte da aprovação de validação de parâmetro, valide a situação do recurso. Valide se o número de filas a serem usadas após uma movimentação em lote completa (evacuação) não excede o conjunto NumberOfQueues na estrutura NDIS_RECEIVE_SCALE_PARAMETERS_V2 durante uma solicitação de OID_GEN_RECEIVE_SCALE_PARAMETERS_V2 . Caso contrário, NDIS_STATUS_NO_QUEUES será retornado. NDIS_STATUS_NO_QUEUES deve ser usado para todas as condições que representam uma violação do número configurado de filas. NDIS_STATUS_RESOURCES só deve ser usado para designar condições transitórias de memória insuficiente.
  • Como parte das verificações de recursos, para cada entidade de dimensionamento (por exemplo, VPort), o driver de miniporto deve lidar com uma condição quando todos os ITEs que apontam para a CPU currrent são movidos para longe dela.

Se todas as verificações acima forem aprovadas, o driver de miniporto deverá ser capaz de aplicar incondicionalmente a nova configuração e deve definir o campo EntryStatus de cada entrada como NDIS_STATUS_SUCCESS.

Em geral, o manipulador para esse OID deve ser muito leve. Ele não deve chamar serviços de sistema operacional ou NDIS além de possíveis operações de sincronização, como spinlocks e NdisMConfigMSIXTableEntry.

O driver de miniporta não deve chamar NDIS para indicar eventos status ou PnP.

O driver de miniporto também não deve usar indicações completas de recebimento/transmissão no contexto desse manipulador de OID, pois isso leva à recursão. A camada superior pode invocar esse OID do contexto de indicações de recebimento ou transmissão.

Movendo todas as entradas da tabela de indireção

Os drivers de miniporto devem reconhecer e lidar com uma solicitação especial que afasta todas as entradas da tabela de indireção da CPU atual. Como o RSSv2 opera com movimentações individuais de ITE, os drivers de miniporto devem garantir a atomicidade da operação geral. Se encontrar um erro no meio de um lote durante o processamento da matriz correspondente de comandos de movimentação, o driver de miniporte deverá reverter todos os comandos que já foram executados e marcar todos os comandos como "com falha" no campo EntryStatus por comando. O protocolo de camada superior sempre espera que o lote "mover todos os ITEs" contenha todos os comandos marcados como "bem-sucedidos" ou todos os comandos marcados como "com falha", e ele assumirá que o tráfego obedece ao estado resultante (antes ou depois da movimentação). Se a camada superior vir apenas algumas entradas marcadas como "com falha", ela causará bugs marcar sistema e apontará para o driver de miniporta como a causa.

Para auxiliar na manipulação do driver de miniporto do comando "mover todos os ITEs" e evitar deadlocks, os protocolos de camada superior agrupam comandos de movimentação no lote em pares de campos SwitchId + VPortId , de modo que:

  • Os comandos que a camada superior deseja executar juntos, como parte do comando "mover tudo", para o mesmo VPort são colocados consecutivamente no lote geral.
  • O driver de miniporta não deve tentar executar o lote de comando geral, que pode ter como destino VPorts diferentes, de forma "mover tudo". Somente o grupo de comandos direcionados ao mesmo VPort (marcado com o mesmo par SwitchId + VPortId ) precisa ser executado em conformidade com a semântica "mover tudo".
  • Quando a camada superior não se importa com a semântica "mover tudo", ela pode intercalar comandos para o mesmo VPort com comandos para VPort(s) diferentes. Nesse caso, se o segundo grupo de comandos para o mesmo VPort não puder ser executado devido a uma violação de "número de filas", o driver de miniporto marcará esse grupo com o código de status correspondente (NDIS_STATUS_NO_QUEUES) e a camada superior assumirá a responsabilidade pela recuperação.

Por exemplo, se o protocolo de camada superior intercalar uma série de comandos como este:

  • VPort=1 ITE[0,1]
  • VPort=2 ITE[0]
  • VPort=1 ITE[2]

O driver de miniporto não precisa tentar executar atomicamente todos os quatro comandos de movimentação ou todos os três comandos de movimentação para VPort=1 (ITE[0,1,2]). Ele só precisa executar o VPort=1 ITE[0,1] grupo de forma "mover tudo", depois o VPort=2 ITE[0] grupo e , em seguida VPort=1 ITE[2], . Todos os três grupos de comandos podem ter um resultado diferente. Por exemplo, os grupos para VPort=1 ITE[0,1] e VPort=2 ITE[0] podem ter êxito e o VPort=1 ITE[2] grupo pode falhar. O resultado deve ser refletido no membro EntryStatus correspondente de cada estrutura de comando. Dessa forma, o driver de miniporto não precisa tomar precauções para a execução segura do lote geral (por exemplo, bloquear todo o adaptador). Somente os comandos direcionados a um VPort específico precisam ser serializados, o bloqueio por VPort mais refinado pode ser usado e determinados deadlocks são evitados.

Observação

Todo o grupo de entradas de comando deve ser marcado com a mesma entrada status.

Condições de erro e códigos de status

Esse OID retorna os seguintes códigos de status quando ocorre um erro:

Código de status Condição de erro
NDIS_STATUS_INVALID_LENGTH O OID estava malformado.
NDIS_STATUS_INVALID_PARAMETER Outros campos, no cabeçalho ou no próprio OID (mas não em entradas de comando individuais) contêm valores inválidos.

Requisitos

Versão: Windows 10, versão 1709 Cabeçalho: Ntddndis.h (include Ndis.h)

Confira também