From: Andre Muezerie <andremue@linux.microsoft.com>
To: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
Cc: dev@dpdk.org, Gena Tertychnyi <genter@microsoft.com>,
Andre Muezerie <andremue@linux.microsoft.com>
Subject: [PATCH] Windows: fix core count on NUMA with more than 64 cores per node
Date: Wed, 13 May 2026 16:55:18 -0700 [thread overview]
Message-ID: <20260513235518.408895-1-andremue@linux.microsoft.com> (raw)
From: Gena Tertychnyi <genter@microsoft.com>
Fix specific to Windows NUMA machines with more than 64 cores per node
(e.g. 2 NUMAs with 128 cores each):
- NumaNode.GroupMasks[] array is used instead of NumaNode.GroupMask.
- RelationAll is used instead of RelationNumaNode when calling
GetLogicalProcessorInformationEx because RelationAll returns the full
multi-group NUMA affinity as RelationNumaNode returns only the NUMA
node's primary group.
Signed-off-by: Gena Tertychnyi <genter@microsoft.com>
Signed-off-by: Andre Muezerie <andremue@linux.microsoft.com>
---
lib/eal/windows/eal_lcore.c | 68 +++++++++++++++++++++++++++----------
1 file changed, 51 insertions(+), 17 deletions(-)
diff --git a/lib/eal/windows/eal_lcore.c b/lib/eal/windows/eal_lcore.c
index a498044620..d2a2c2d091 100644
--- a/lib/eal/windows/eal_lcore.c
+++ b/lib/eal/windows/eal_lcore.c
@@ -17,13 +17,27 @@
/** Number of logical processors (cores) in a processor group (32 or 64). */
#define EAL_PROCESSOR_GROUP_SIZE (sizeof(KAFFINITY) * CHAR_BIT)
+/*
+ * NUMA_NODE_RELATIONSHIP layout differs:
+ * - MSVC + modern SDK: GroupCount + GroupMasks[]
+ * - MinGW-w64: only GroupMask (MinGW headers lag behind Windows SDK ABI changes)
+ */
+#ifdef RTE_TOOLCHAIN_GCC
+#define EAL_NUMA_GROUP_COUNT(numa) (RTE_SET_USED(numa), 1)
+#define EAL_NUMA_GROUP_MASKS(numa) (&((numa).GroupMask))
+#else
+#define EAL_NUMA_GROUP_COUNT(numa) ((numa).GroupCount)
+#define EAL_NUMA_GROUP_MASKS(numa) ((numa).GroupMasks)
+#endif
+
struct lcore_map {
- uint8_t socket_id;
- uint8_t core_id;
+ unsigned int socket_id;
+ unsigned int core_id;
};
struct socket_map {
uint16_t node_id;
+ unsigned int lcore_count;
};
struct cpu_map {
@@ -112,11 +126,15 @@ static bool
eal_create_lcore_map(const SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *info)
{
const unsigned int node_id = info->NumaNode.NodeNumber;
- const GROUP_AFFINITY *cores = &info->NumaNode.GroupMask;
+ const GROUP_AFFINITY *group_masks = EAL_NUMA_GROUP_MASKS(info->NumaNode);
struct lcore_map *lcore;
unsigned int socket_id;
+ unsigned int group_count;
+ unsigned int group_no;
unsigned int i;
+ group_count = EAL_NUMA_GROUP_COUNT(info->NumaNode);
+
/*
* NUMA node may be reported multiple times if it includes
* cores from different processor groups, e. g. 80 cores
@@ -132,20 +150,33 @@ eal_create_lcore_map(const SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *info)
return true;
cpu_map.sockets[socket_id].node_id = node_id;
+ cpu_map.sockets[socket_id].lcore_count = 0;
cpu_map.socket_count++;
}
- for (i = 0; i < EAL_PROCESSOR_GROUP_SIZE; i++) {
- if ((cores->Mask & ((KAFFINITY)1 << i)) == 0)
- continue;
+ /* Old Windows versions report NUMA nodes with GroupCount == 0 */
+ if (group_count == 0) {
+ group_count = 1;
+ group_masks = &info->NumaNode.GroupMask;
+ }
- if (cpu_map.lcore_count == RTE_DIM(cpu_map.lcores))
- return true;
+ for (group_no = 0; group_no < group_count; group_no++) {
+ const GROUP_AFFINITY *cores = &group_masks[group_no];
+ for (i = 0; i < EAL_PROCESSOR_GROUP_SIZE; i++) {
+ if ((cores->Mask & ((KAFFINITY)1 << i)) == 0)
+ continue;
+
+ if (cpu_map.lcore_count == RTE_DIM(cpu_map.lcores))
+ return true;
- lcore = &cpu_map.lcores[cpu_map.lcore_count];
- lcore->socket_id = socket_id;
- lcore->core_id = cores->Group * EAL_PROCESSOR_GROUP_SIZE + i;
- cpu_map.lcore_count++;
+ lcore = &cpu_map.lcores[cpu_map.lcore_count];
+ lcore->socket_id = socket_id;
+
+ /* core_id within the socket */
+ lcore->core_id = cpu_map.sockets[socket_id].lcore_count;
+ cpu_map.sockets[socket_id].lcore_count++;
+ cpu_map.lcore_count++;
+ }
}
return false;
}
@@ -160,8 +191,9 @@ eal_create_cpu_map(void)
infos = NULL;
infos_size = 0;
+ /* RelationAll is needed to get full multi-group NUMA affinity */
if (!GetLogicalProcessorInformationEx(
- RelationNumaNode, NULL, &infos_size)) {
+ RelationAll, NULL, &infos_size)) {
DWORD error = GetLastError();
if (error != ERROR_INSUFFICIENT_BUFFER) {
log_early("Cannot get NUMA node info size, error %lu\n",
@@ -181,7 +213,7 @@ eal_create_cpu_map(void)
}
if (!GetLogicalProcessorInformationEx(
- RelationNumaNode, infos, &infos_size)) {
+ RelationAll, infos, &infos_size)) {
log_early("Cannot get NUMA node information, error %lu\n",
GetLastError());
rte_errno = EINVAL;
@@ -191,9 +223,11 @@ eal_create_cpu_map(void)
info = infos;
while ((uint8_t *)info - (uint8_t *)infos < infos_size) {
- if (eal_create_lcore_map(info)) {
- full = true;
- break;
+ if (info->Relationship == RelationNumaNode) {
+ if (eal_create_lcore_map(info)) {
+ full = true;
+ break;
+ }
}
info = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(
--
2.53.0.vfs.0.7
reply other threads:[~2026-05-13 23:55 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260513235518.408895-1-andremue@linux.microsoft.com \
--to=andremue@linux.microsoft.com \
--cc=dev@dpdk.org \
--cc=dmitry.kozliuk@gmail.com \
--cc=genter@microsoft.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox