OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES

Aviso

Algumas informações contidas neste tópico estão relacionadas ao produto em pré-lançamento, o qual poderá ser modificado substancialmente antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.

O RSSv2 é uma versão prévia somente no Windows 10, versão 1809.

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

Essa chamada usa o ponto de entrada XxxSynchronousOidRequest, onde Xxx é Miniport ou Filter, dependendo do tipo de driver que recebe a solicitação. Esse ponto de entrada causa uma verificação de bug do sistema se vir um status de retorno NDIS_STATUS_PENDING.

OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES usa a estrutura NDIS_RSS_SET_INDIRECTION_ENTRIES para instruir um adaptador de miniporta 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 uma VPort especificada para uma CPU de destino especificada.

Comentários

Esse OID deve ser executado e concluído no contexto de processador que o emitiu. Os drivers de miniporta devem executar esse OID integralmente ao retornar NDIS_STATUS_SUCCESS para a camada superior. Isso significa que o driver de miniporta deve estar preparado para receber solicitações OID sucessivamente para mover vários ITEs em um novo processador tão logo o primeiro movimento terminar com NDIS_STATUS_SUCCESS.

Dica

Executar esse OID integralmente significa que o driver de miniporta deve estar pronto para tentar outra ação para mover um ITE. Ele não prescreve onde o tráfego de recebimento em curso é indicado logo após a movimentação da fila, o 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 principal e padrão para apontar para diferentes processadores.

Esse OID pode ser emitido para parâmetros de direcionamento de tráfego ativos ou inativos. Para obter mais informações sobre parâmetros de direcionamento, consulte RSS versão 2 (RSSv2). Para parâmetros/ITEs no estado inativo, o driver de miniporta deve validar e armazenar o processador de destino em cache até a próxima alteração relevante no estado do RSS (habilitação ou desabilitação). Nesse ponto, os números do processador armazenado em cache tornam-se ativos e são usados para direcionar o tráfego. As atualizações nos parâmetros ativos (que também devem ser validadas) devem entrar em vigor imediatamente 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 desmarcado. Isso ocorre devido à possibilidade de diferentes VPorts serem referenciadas por diferentes elementos da matriz.

Esse OID é invocado somente em IRQL == DISPATCH_LEVEL.

Os drivers de miniporta devem estar preparados para processar pelo menos tantas ações de movimentação de entrada na tabela de indireção quantas 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 miniporta devem tentar executar o máximo de entradas possíveis e atualizar o membro EntryStatus de cada NDIS_RSS_SET_INDIRECTION_ENTRY com o resultado da operação.

Manipulador OID para OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES

O manipulador OID para OID_GEN_RSS_SET_INDIRECTION_TABLE_ENTRIES deve se comportar da seguinte maneira:

  • Não é permitido um retorno de NDIS_STATUS_PENDING devido ao tipo de chamada síncrona do OID.
  • Finalize as movimentações de ITE de entrada destinadas à CPU atual (iniciadas anteriormente em processadores remotos).
  • É altamente recomendável que os drivers de miniporta façam uma aprovação de validação completa dos parâmetros. Se isso não for possível, faça a validação e a execução das entradas da matriz individualmente. Os drivers de miniporta devem verificar especificamente se todos os objetos referenciados são válidos:
    • Não é permitido retornar NDIS_STATUS_PENDING no campo EntryStatus de um ITE.
    • O adaptador de miniporta existe e está em um bom estado. Do 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. Do 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 OID_GEN_RECEIVE_SCALE_PARAMETERS_V2. Os índices de entrada 0xFFFF e 0xFFFE têm significados especiais: 0xFFFF define o processador padrão, enquanto 0xFFFE define o processador principal. Em caso de erro, o manipulador define o campo EntryStatus da entrada como NDIS_STATUS_INVALID_PARAMETER.
    • A camada superior e o driver de miniporta esperam que o ITE aponte para o processador atual (CPU de ator) antes da movimentação. Em outras palavras, o ITE não pode ser redirecionado remotamente. Se isso não for verdade, 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 miniporta. Do contrário, defina o campo EntryStatus da entrada como NDIS_STATUS_INVALID_DATA.
  • Posteriormente ou como parte da aprovação na validação de parâmetros, 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 NumberOfQueues definido na estrutura NDIS_RECEIVE_SCALE_PARAMETERS_V2 durante uma solicitação de OID_GEN_RECEIVE_SCALE_PARAMETERS_V2. Caso contrário, será retornado NDIS_STATUS_NO_QUEUES. NDIS_STATUS_NO_QUEUES deve ser usado para todas as condições que representam uma violação do número de filas configurado. NDIS_STATUS_RESOURCES só deve ser usado para designar condições temporárias de falta de memória.
  • Como parte das verificações de recursos, para cada entidade de dimensionamento (por exemplo, VPort), o driver de miniporta deve processar uma condição quando todos os ITEs que apontam para a CPU atual são removidos.

Se for aprovado em todas as verificações acima, o driver de miniporta deverá ser capaz de aplicar a nova configuração incondicionalmente e deverá definir o campo EntryStatus de cada entrada como NDIS_STATUS_SUCCESS.

Em geral, o manipulador desse OID deve ser muito leve. Ele não deve chamar o NDIS nem serviços do sistema operacional, a não ser no caso de operações de sincronização possíveis, como spinlocks e NdisMConfigMSIXTableEntry.

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

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

Movendo todas as entradas da tabela de indireção

Os drivers de miniporta devem reconhecer e processar uma solicitação especial que remove todas as entradas da tabela de indireção da CPU atual. Como o RSSv2 opera com movimentações de ITE individuais, os drivers de miniporta devem garantir a atomicidade da operação geral. Se encontrar um erro no meio de um lote durante o processamento da matriz de comandos de movimentação correspondente, o driver de miniporta deverá reverter todos os comandos que já foram executados e marcar todos os comandos como "falha" no campo EntryStatus de cada um deles. O protocolo de camada superior sempre espera que o lote "mover todos os ITEs" contenha todos os comandos marcados como "êxito" ou todos os comandos marcados como "falha" e presumirá que o tráfego obedece ao estado resultante (antes ou depois da movimentação). Se a camada superior vir apenas algumas entradas marcadas como "falha", ela fará uma verificação de bugs no sistema e indicará o driver de miniporta como sendo a causa.

Para ajudar o driver de miniporta a processar o comando "mover todos os ITEs" e evitar deadlocks, os protocolos da camada superior agrupam os comandos de movimentação do lote em pares de campos SwitchId + VPortId, de modo que:

  • Os comandos que a camada superior deseja que sejam executados juntos, como parte do comando "mover tudo", para a mesma VPort são colocados consecutivamente no lote geral.
  • O driver de miniporta não deve tentar executar o lote geral de comandos, que pode ter como alvo diferentes VPorts, movendo todos os comandos. Somente o grupo de comandos que visam a mesma VPort (marcada com o mesmo par SwitchId + VPortId ) precisa ser executado de acordo com a semântica "mover tudo".
  • Quando a camada superior não se preocupa com a semântica "mover tudo", ela pode intercalar comandos para a mesma VPort com comandos para VPorts diferentes. Nesse caso, se o segundo grupo de comandos para a mesma VPort não puder ser executado devido a uma violação de "número de filas", o driver de miniporta 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 da camada superior intercalar uma série de comandos desta maneira:

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

O driver de miniporta 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 grupo VPort=1 ITE[0,1] movendo tudo, depois o grupo VPort=2 ITE[0] e, em seguida, VPort=1 ITE[2]. Todos os três grupos de comandos podem ter um resultado diferente. Por exemplo, os grupos de VPort=1 ITE[0,1] e VPort=2 ITE[0] podem ter êxito, e o grupo de VPort=1 ITE[2] pode falhar. O resultado deve se refletir no membro EntryStatus correspondente de cada estrutura de comando. Dessa forma, o driver de miniporta não precisa tomar precauções para a execução segura do lote geral (por exemplo, bloquear o adaptador inteiro). Somente os comandos que visam a uma VPort específica precisam ser serializados, o bloqueio por VPort mais refinado pode ser usado e certos deadlocks são evitados.

Observação

Todo o grupo das entradas de comando deve ser marcado com o mesmo status de entrada.

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, seja no cabeçalho ou no próprio OID (mas não em entradas de comandos individuais), contêm valores inválidos.

Requisitos

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

Confira também