KeQueryNodeActiveAffinity2, fonction (wdm.h)
Cette routine retourne l’affinité actuelle du processeur multi-groupe du nœud NUMA donné.
Syntaxe
NTSTATUS KeQueryNodeActiveAffinity2(
[in] USHORT NodeNumber,
[out] PGROUP_AFFINITY GroupAffinities,
[in] USHORT GroupAffinitiesCount,
[out] PUSHORT GroupAffinitiesRequired
);
Paramètres
[in] NodeNumber
Fournit le numéro de nœud du nœud à interroger.
[out] GroupAffinities
Fournit un pointeur vers un tableau de structures GROUP_AFFINITY qui, en cas de réussite, reçoivent un numéro de groupe et le masque d’affinité du groupe identifié.
[in] GroupAffinitiesCount
Valeur de type USHORT qui spécifie le nombre d’éléments dans le tableau d’affinités de groupe. Si le tableau est trop petit pour contenir l’affinité de nœud, STATUS_BUFFER_TOO_SMALL est retourné et le nombre d’éléments requis est retourné dans GroupAffinitiesRequired.
[out] GroupAffinitiesRequired
Pointeur vers une valeur de type USHORT qui reçoit le nombre d’affinités de groupe requises pour représenter l’affinité de nœud. Dans le cas d’un nœud NUMA en mémoire seule, zéro est retourné.
Valeur de retour
STATUS_SUCCESS si l’affinité de nœud a été interrogée avec succès.
STATUS_INVALID_PARAMETER si un numéro de nœud non valide a été spécifié.
STATUS_BUFFER_TOO_SMALL si le tableau fourni est trop petit.
Remarques
À compter de Windows Server 2022, le système d’exploitation ne fractionne plus les nœuds NUMA volumineux ; Au lieu de cela, Windows signale la topologie NUMA vraie du système. Lorsqu’un nœud contient plus de 64 processeurs, un nœud NUMA s’étend sur plusieurs groupes. Dans ce cas, le système affecte un groupe principal pour chaque nœud NUMA. Le groupe principal est toujours celui qui contient le plus de processeurs. Pour déterminer le nombre de processeurs actifs dans un nœud NUMA donné (entre tous les groupes), appelez KeQueryNodeActiveProcessorCount. Pour plus d’informations sur ce changement de comportement, consultez prise en charge de NUMA.
Pour réactiver le comportement de fractionnement de nœud hérité, apportez la modification suivante au Registre et redémarrez le système :
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\NUMA" /v SplitLargeNodes /t REG_DWORD /d 1
Si votre pilote mappe des processeurs aux nœuds NUMA en appelant KeQueryNodeActiveAffinity, et que votre code s’exécute sur des systèmes avec plus de 64 processeurs par nœud NUMA, utilisez l’une des solutions de contournement suivantes :
Migrez vers les API d’affinité de nœud à plusieurs groupes (mode utilisateur et mode noyau), telles que KeQueryNodeActiveAffinity2.
Appelez KeQueryLogicalProcessorRelationship avec RelationNumaNode pour interroger directement le nœud NUMA associé à un numéro de processeur donné.
L’exemple suivant montre le code qui serait problématique sur Windows Server 2022 et versions ultérieures, puis présente les deux solutions de contournement.
//
// 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];
}
Exigences
Exigence | Valeur |
---|---|
serveur minimum pris en charge | Windows Server 2022 |
d’en-tête | wdm.h |
IRQL | N’importe quel niveau |