Skip to content

Commit

Permalink
windows: support multiple processor Groups per NUMA
Browse files Browse the repository at this point in the history
The previous Windows API could not describe NUMA nodes with PUs
from more than a single Processor Group (64 PUs max).

Starting with Windows 10 build 20348 and Windows 11, the NUMA affinity
can be described in more than one group affinity structure.

Refs #465

Signed-off-by: Brice Goglin <Brice.Goglin@inria.fr>
  • Loading branch information
bgoglin committed Nov 13, 2021
1 parent db730cf commit 0185d00
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 10 deletions.
2 changes: 2 additions & 0 deletions NEWS
Expand Up @@ -20,6 +20,8 @@ bug fixes (and other actions) for each version of hwloc since version
Version 2.7.0
-------------
* Backends
+ Add support for NUMA nodes spanning multiple processor groups
on recent Windows versions (NUMA nodes with more than 64 PUs).
+ Expose "Cluster" group objects on Linux kernel 5.16+ for CPUs
that share some internal cache or bus. This can be equivalent
to the L2 Cache level on some platforms (e.g. x86) or a specific
Expand Down
32 changes: 22 additions & 10 deletions hwloc/topology-windows.c
Expand Up @@ -103,13 +103,17 @@ typedef struct HWLOC_PROCESSOR_RELATIONSHIP {
GROUP_AFFINITY GroupMask[ANYSIZE_ARRAY];
} HWLOC_PROCESSOR_RELATIONSHIP;

#ifndef HAVE_NUMA_NODE_RELATIONSHIP
typedef struct _NUMA_NODE_RELATIONSHIP {
/* always use our own structure because the GroupCount and GroupMasks fields didn't exist in some Win10 */
typedef struct HWLOC_NUMA_NODE_RELATIONSHIP {
DWORD NodeNumber;
BYTE Reserved[20];
GROUP_AFFINITY GroupMask;
} NUMA_NODE_RELATIONSHIP, *PNUMA_NODE_RELATIONSHIP;
#endif
BYTE Reserved[18];
WORD GroupCount;
_ANONYMOUS_UNION
union {
GROUP_AFFINITY GroupMask;
GROUP_AFFINITY GroupMasks[ANYSIZE_ARRAY];
} DUMMYUNIONNAME;
} HWLOC_NUMA_NODE_RELATIONSHIP;

#ifndef HAVE_CACHE_RELATIONSHIP
typedef struct _CACHE_RELATIONSHIP {
Expand Down Expand Up @@ -141,14 +145,14 @@ typedef struct _GROUP_RELATIONSHIP {
} GROUP_RELATIONSHIP, *PGROUP_RELATIONSHIP;
#endif

/* always use our own structure because we need our own HWLOC_PROCESSOR_RELATIONSHIP */
/* always use our own structure because we need our own HWLOC_PROCESSOR_RELATIONSHIP and HWLOC_NUMA_NODE_RELATIONSHIP */
typedef struct HWLOC_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX {
LOGICAL_PROCESSOR_RELATIONSHIP Relationship;
DWORD Size;
_ANONYMOUS_UNION
union {
HWLOC_PROCESSOR_RELATIONSHIP Processor;
NUMA_NODE_RELATIONSHIP NumaNode;
HWLOC_NUMA_NODE_RELATIONSHIP NumaNode;
CACHE_RELATIONSHIP Cache;
GROUP_RELATIONSHIP Group;
/* Odd: no member to tell the cpu mask of the package... */
Expand Down Expand Up @@ -1208,8 +1212,16 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
switch (procInfo->Relationship) {
case RelationNumaNode:
type = HWLOC_OBJ_NUMANODE;
num = 1;
GroupMask = &procInfo->NumaNode.GroupMask;
/* Starting with Windows 10 Build 20348 and Windows 11, the GroupCount field is valid and >=1
* and we may read GroupMasks[]. Older releases have GroupCount==0 and we must read GroupMask.
*/
if (procInfo->NumaNode.GroupCount) {
num = procInfo->NumaNode.GroupCount;
GroupMask = procInfo->NumaNode.GroupMasks;
} else {
num = 1;
GroupMask = &procInfo->NumaNode.GroupMask;
}
id = procInfo->NumaNode.NodeNumber;
gotnuma++;
if (id > max_numanode_index)
Expand Down

0 comments on commit 0185d00

Please sign in to comment.