Função KeQueryNodeActiveAffinity2 (wdm.h)

Essa rotina retorna a afinidade atual do processador de vários grupos do nó NUMA especificado.

Sintaxe

NTSTATUS KeQueryNodeActiveAffinity2(
  [in]  USHORT          NodeNumber,
  [out] PGROUP_AFFINITY GroupAffinities,
  [in]  USHORT          GroupAffinitiesCount,
  [out] PUSHORT         GroupAffinitiesRequired
);

Parâmetros

[in] NodeNumber

Fornece o número do nó do nó a ser consultado.

[out] GroupAffinities

Fornece um ponteiro para uma matriz de estruturas de GROUP_AFFINITY que, após o sucesso, recebem um número de grupo e a máscara de afinidade do grupo identificado.

[in] GroupAffinitiesCount

Um valor do tipo USHORT que especifica o número de elementos na matriz de afinidades de grupo. Se a matriz for muito pequena para manter a afinidade do nó , STATUS_BUFFER_TOO_SMALL será retornado e o número de elementos necessários será retornado em GroupAffinitiesRequired.

[out] GroupAffinitiesRequired

Um ponteiro para um valor do tipo USHORT que recebe o número de afinidades de grupo necessárias para representar a afinidade do nó. No caso de um nó NUMA somente de memória, zero é retornado.

Retornar valor

STATUS_SUCCESS se a afinidade do nó foi consultada com êxito.

STATUS_INVALID_PARAMETER se um número de nó inválido tiver sido especificado.

STATUS_BUFFER_TOO_SMALL se a matriz fornecida for muito pequena.

Comentários

A partir do Windows Server 2022, o sistema operacional não divide mais nós NUMA grandes; Em vez disso, o Windows relata a verdadeira topologia NUMA do sistema. Quando um nó contém mais de 64 processadores, um nó NUMA abrange mais de um único grupo. Nesse caso, o sistema atribui um grupo primário para cada nó NUMA. O grupo primário é sempre aquele que contém mais processadores. Para determinar o número de processadores ativos em um determinado nó NUMA (em todos os grupos), chame KeQueryNodeActiveProcessorCount. Para obter mais informações sobre essa alteração no comportamento, consulte Suporte a NUMA.

Para reabilitar o comportamento de divisão de nó herdado, faça a seguinte alteração no registro e reinicie o sistema:

reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\NUMA" /v SplitLargeNodes /t REG_DWORD /d 1

Se o driver mapear processadores para nós NUMA chamando KeQueryNodeActiveAffinity e seu código for executado em sistemas com mais de 64 processadores por nó NUMA, use uma das seguintes soluções alternativas:

  1. Migre para as APIs de afinidade de nó de vários grupos (modo de usuário e modo kernel), como KeQueryNodeActiveAffinity2.

  2. Chame KeQueryLogicalProcessorRelationship com RelationNumaNode para consultar diretamente o nó NUMA associado a um determinado número de processador.

O exemplo a seguir mostra o código que seria problemático no Windows Server 2022 e posterior e, em seguida, mostra as duas soluções alternativas.

//
// Problematic implementation using KeQueryNodeActiveAffinity.
//

    USHORT CurrentNode;
    USHORT HighestNodeNumber;
    GROUP_AFFINITY NodeAffinity;
    ULONG ProcessorIndex;
    PROCESSOR_NUMBER ProcessorNumber;

    HighestNodeNumber = KeQueryHighestNodeNumber();
    for (CurrentNode = 0; CurrentNode <= HighestNodeNumber; CurrentNode += 1) {

        KeQueryNodeActiveAffinity(CurrentNode, &NodeAffinity, NULL);
        while (NodeAffinity.Mask != 0) {

            ProcessorNumber.Group = NodeAffinity.Group;
            BitScanForward(&ProcessorNumber.Number, NodeAffinity.Mask);

            ProcessorIndex = KeGetProcessorIndexFromNumber(&ProcessorNumber);

            ProcessorNodeContexts[ProcessorIndex] = NodeContexts[CurrentNode;]

            NodeAffinity.Mask &= ~((KAFFINITY)1 << ProcessorNumber.Number);
        }
    }

//
// Resolution using KeQueryNodeActiveAffinity2.
//

    USHORT CurrentIndex;
    USHORT CurrentNode;
    USHORT CurrentNodeAffinityCount;
    USHORT HighestNodeNumber;
    ULONG MaximumGroupCount;
    PGROUP_AFFINITY NodeAffinityMasks;
    ULONG ProcessorIndex;
    PROCESSOR_NUMBER ProcessorNumber;
    NTSTATUS Status;

    MaximumGroupCount = KeQueryMaximumGroupCount();
    NodeAffinityMasks = ExAllocatePool2(POOL_FLAG_PAGED,
                                        sizeof(GROUP_AFFINITY) * MaximumGroupCount,
                                        'tseT');

    if (NodeAffinityMasks == NULL) {
        return STATUS_NO_MEMORY;
    }

    HighestNodeNumber = KeQueryHighestNodeNumber();
    for (CurrentNode = 0; CurrentNode <= HighestNodeNumber; CurrentNode += 1) {

        Status = KeQueryNodeActiveAffinity2(CurrentNode,
                                            NodeAffinityMasks,
                                            MaximumGroupCount,
                                            &CurrentNodeAffinityCount);
        NT_ASSERT(NT_SUCCESS(Status));

        for (CurrentIndex = 0; CurrentIndex < CurrentNodeAffinityCount; CurrentIndex += 1) {

            CurrentAffinity = &NodeAffinityMasks[CurrentIndex];

            while (CurrentAffinity->Mask != 0) {

                ProcessorNumber.Group = CurrentAffinity.Group;
                BitScanForward(&ProcessorNumber.Number, CurrentAffinity->Mask);

                ProcessorIndex = KeGetProcessorIndexFromNumber(&ProcessorNumber);

                ProcessorNodeContexts[ProcessorIndex] = NodeContexts[CurrentNode];

                CurrentAffinity->Mask &= ~((KAFFINITY)1 << ProcessorNumber.Number);
            }
        }
    }

//
// Resolution using KeQueryLogicalProcessorRelationship.
//

    ULONG ProcessorCount;
    ULONG ProcessorIndex;
    SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX ProcessorInformation;
    ULONG ProcessorInformationSize;
    PROCESSOR_NUMBER ProcessorNumber;
    NTSTATUS Status;

    ProcessorCount = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS);

    for (ProcessorIndex = 0; ProcessorIndex < ProcessorCount; ProcessorIndex += 1) {

        Status = KeGetProcessorNumberFromIndex(ProcessorIndex, &ProcessorNumber);
        NT_ASSERT(NT_SUCCESS(Status));

        ProcessorInformationSize = sizeof(ProcessorInformation);
        Status = KeQueryLogicalProcessorRelationship(&ProcessorNumber,
                                                     RelationNumaNode,
                                                     &ProcessorInformation,
                                                     &ProcessorInformationSize);
        NT_ASSERT(NT_SUCCESS(Status));

        NodeNumber = ProcessorInformation.NumaNode.NodeNumber;

        ProcessorNodeContexts[ProcessorIndex] = NodeContexts[NodeNumber];
    }

Requisitos

Requisito Valor
Servidor mínimo com suporte Windows Server 2022
Cabeçalho wdm.h
IRQL Qualquer nível

Confira também

KeQueryNodeActiveAffinity

KeQueryNodeActiveProcessorCount

Suporte ao NUMA