Función KeQueryNodeActiveAffinity2 (wdm.h)
Esta rutina devuelve la afinidad actual del procesador multigrupo del nodo NUMA especificado.
Sintaxis
NTSTATUS KeQueryNodeActiveAffinity2(
[in] USHORT NodeNumber,
[out] PGROUP_AFFINITY GroupAffinities,
[in] USHORT GroupAffinitiesCount,
[out] PUSHORT GroupAffinitiesRequired
);
Parámetros
[in] NodeNumber
Proporciona el número de nodo del nodo que se va a consultar.
[out] GroupAffinities
Proporciona un puntero a una matriz de estructuras de GROUP_AFFINITY que, tras el éxito, reciben un número de grupo y la máscara de afinidad del grupo identificado.
[in] GroupAffinitiesCount
Valor de tipo USHORT que especifica el número de elementos de la matriz de afinidades de grupo. Si la matriz es demasiado pequeña para contener la afinidad de nodo, se devuelve STATUS_BUFFER_TOO_SMALL y se devuelve el número de elementos necesarios en GroupAffinitiesRequired.
[out] GroupAffinitiesRequired
Puntero a un valor de tipo USHORT que recibe el número de afinidades de grupo necesarias para representar la afinidad de nodo. En el caso de un nodo NUMA de solo memoria, se devuelve cero.
Valor devuelto
STATUS_SUCCESS si la afinidad de nodo se ha consultado correctamente.
STATUS_INVALID_PARAMETER si se especificó un número de nodo no válido.
STATUS_BUFFER_TOO_SMALL si la matriz proporcionada es demasiado pequeña.
Comentarios
A partir de Windows Server 2022, el sistema operativo ya no divide nodos NUMA grandes; en su lugar, Windows notifica la topología NUMA verdadera del sistema. Cuando un nodo contiene más de 64 procesadores, un nodo NUMA abarca más de un único grupo. En este caso, el sistema asigna un grupo principal para cada nodo NUMA. El grupo principal es siempre el que contiene la mayoría de los procesadores. Para determinar el número de procesadores activos en un nodo NUMA determinado (en todos los grupos), llame a KeQueryNodeActiveProcessorCount. Para obtener más información sobre este cambio en el comportamiento, consulte Compatibilidad con NUMA.
Para volver a habilitar el comportamiento de división de nodos heredados, realice el siguiente cambio en el registro y reinicie el sistema:
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\NUMA" /v SplitLargeNodes /t REG_DWORD /d 1
Si el controlador asigna procesadores a nodos NUMA mediante una llamada a KeQueryNodeActiveAffinity y el código se ejecuta en sistemas con más de 64 procesadores por nodo NUMA, use una de las siguientes soluciones alternativas:
Migre a las API de afinidad de nodo de varios grupos (modo de usuario y modo kernel), como KeQueryNodeActiveAffinity2.
Llame a KeQueryLogicalProcessorRelationship con RelationNumaNode para consultar directamente el nodo NUMA asociado a un número de procesador determinado.
En el ejemplo siguiente se muestra el código que sería problemático en Windows Server 2022 y versiones posteriores y, a continuación, se muestran ambas soluciones 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 | Value |
---|---|
Servidor mínimo compatible | Windows Server 2022 |
Encabezado | wdm.h |
IRQL | Cualquier nivel |