Condividi tramite


Funzione KeQueryNodeActiveAffinity2 (wdm.h)

Questa routine restituisce l'affinità corrente del processore multi-gruppo del nodo NUMA specificato.

Sintassi

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

Parametri

[in] NodeNumber

Specifica il numero di nodo del nodo da eseguire per la query.

[out] GroupAffinities

Fornisce un puntatore a una matrice di strutture GROUP_AFFINITY che in caso di esito positivo ricevono un numero di gruppo e la maschera di affinità del gruppo identificato.

[in] GroupAffinitiesCount

Valore di tipo USHORT che specifica il numero di elementi nella matrice di affinità di gruppo. Se la matrice è troppo piccola per contenere l'affinità del nodo, STATUS_BUFFER_TOO_SMALL viene restituita e il numero di elementi necessari viene restituito in GroupAffinitiesRequired.

[out] GroupAffinitiesRequired

Puntatore a un valore di tipo USHORT che riceve il numero di affinità di gruppo necessarie per rappresentare l'affinità del nodo. Nel caso di un nodo NUMA di sola memoria, viene restituito zero.

Valore restituito

STATUS_SUCCESS se l'affinità del nodo è stata eseguita correttamente.

STATUS_INVALID_PARAMETER se è stato specificato un numero di nodo non valido.

STATUS_BUFFER_TOO_SMALL se la matrice fornita è troppo piccola.

Commenti

A partire da Windows Server 2022, il sistema operativo non divide più nodi NUMA di grandi dimensioni; Windows segnala invece la vera topologia NUMA del sistema. Quando un nodo contiene più di 64 processori, un nodo NUMA si estende su più di un singolo gruppo. In questo caso, il sistema assegna un gruppo primario per ogni nodo NUMA. Il gruppo primario è sempre quello che contiene la maggior parte dei processori. Per determinare il numero di processori attivi in un determinato nodo NUMA (in tutti i gruppi), chiamare KeQueryNodeActiveProcessorCount. Per altre informazioni su questa modifica nel comportamento, vedere Supporto NUMA.

Per riabilitare il comportamento di divisione del nodo legacy, apportare le modifiche seguenti al Registro di sistema e riavviare il sistema:

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

Se il driver esegue il mapping dei processori ai nodi NUMA chiamando KeQueryNodeActiveAffinity e il codice viene eseguito nei sistemi con più di 64 processori per nodo NUMA, usare una delle soluzioni alternative seguenti:

  1. Eseguire la migrazione alle API di affinità del nodo multi-gruppo (modalità utente e modalità kernel), ad esempio KeQueryNodeActiveAffinity2.

  2. Chiamare KeQueryLogicalProcessorRelationship con RelationNumaNode per eseguire direttamente una query sul nodo NUMA associato a un determinato numero di processore.

L'esempio seguente mostra il codice che sarebbe problematico in Windows Server 2022 e versioni successive e quindi mostra entrambe le soluzioni alternative.

//
// 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];
    }

Requisiti

Requisito Valore
Server minimo supportato Windows Server 2022
Intestazione wdm.h
IRQL Qualsiasi livello

Vedi anche

KeQueryNodeActiveAffinity

KeQueryNodeActiveProcessorCount

Supporto NUMA