KeQueryNodeActiveAffinity2-Funktion (wdm.h)
Diese Routine gibt die aktuelle Prozessoraffinität mit mehreren Gruppen des angegebenen NUMA-Knotens zurück.
Syntax
NTSTATUS KeQueryNodeActiveAffinity2(
[in] USHORT NodeNumber,
[out] PGROUP_AFFINITY GroupAffinities,
[in] USHORT GroupAffinitiesCount,
[out] PUSHORT GroupAffinitiesRequired
);
Parameter
[in] NodeNumber
Gibt die Knotennummer des abzufragenden Knotens an.
[out] GroupAffinities
Stellt einen Zeiger auf ein Array von GROUP_AFFINITY Strukturen bereit, die bei Erfolg eine Gruppennummer und die Affinitätsmaske der identifizierten Gruppe erhalten.
[in] GroupAffinitiesCount
Ein Wert vom Typ USHORT, der die Anzahl der Elemente im Gruppenaffinitätsarray angibt. Wenn das Array zu klein ist, um die Knotenaffinität zu halten, wird STATUS_BUFFER_TOO_SMALL zurückgegeben, und die anzahl der erforderlichen Elemente wird in GroupAffinitiesRequired zurückgegeben.
[out] GroupAffinitiesRequired
Ein Zeiger auf einen Wert vom Typ USHORT, der die Anzahl der Gruppenaffinitäten empfängt, die zur Darstellung der Knotenaffinität erforderlich sind. Bei einem NUMA-Knoten, der nur arbeitsspeicheret, wird 0 zurückgegeben.
Rückgabewert
STATUS_SUCCESS , wenn die Knotenaffinität erfolgreich abgefragt wurde.
STATUS_INVALID_PARAMETER , wenn eine ungültige Knotennummer angegeben wurde.
STATUS_BUFFER_TOO_SMALL , wenn das angegebene Array zu klein ist.
Hinweise
Ab Windows Server 2022 teilt das Betriebssystem keine großen NUMA-Knoten mehr auf. Stattdessen meldet Windows die echte NUMA-Topologie des Systems. Wenn ein Knoten mehr als 64 Prozessoren enthält, erstreckt sich ein NUMA-Knoten über mehr als eine einzelne Gruppe. In diesem Fall weist das System jedem NUMA-Knoten eine primäre Gruppe zu. Die primäre Gruppe ist immer die Gruppe, die die meisten Prozessoren enthält. Um die Anzahl der aktiven Prozessoren in einem bestimmten NUMA-Knoten (über alle Gruppen hinweg) zu bestimmen, rufen Sie KeQueryNodeActiveProcessorCount auf. Weitere Informationen zu dieser Verhaltensänderung finden Sie unter NUMA-Unterstützung.
Um das Legacy-Knotenteilungsverhalten erneut zu aktivieren, nehmen Sie die folgende Änderung an der Registrierung vor, und starten Sie das System neu:
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\NUMA" /v SplitLargeNodes /t REG_DWORD /d 1
Wenn Ihr Treiber Prozessoren NUMA-Knoten durch Aufrufen von KeQueryNodeActiveAffinity zuordnet und Ihr Code auf Systemen mit mehr als 64 Prozessoren pro NUMA-Knoten ausgeführt wird, verwenden Sie eine der folgenden Problemumgehungen:
Migrieren Sie zu den Affinitäts-APIs für knotenübergreifende Gruppen (Benutzermodus und Kernelmodus), z. B. KeQueryNodeActiveAffinity2.
Rufen Sie KeQueryLogicalProcessorRelationship mit RelationNumaNode auf, um den NUMA-Knoten, der einer bestimmten Prozessornummer zugeordnet ist, direkt abzufragen.
Das folgende Beispiel zeigt Code, der unter Windows Server 2022 und höher problematisch wäre, und zeigt dann beide Problemumgehungen an.
//
// 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];
}
Anforderungen
Anforderung | Wert |
---|---|
Unterstützte Mindestversion (Server) | Windows Server 2022 |
Kopfzeile | wdm.h |
IRQL | Beliebige Ebene |