1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019 Intel Corporation
3 * Copyright (C) 2022 Microsoft Corporation
9 #include <rte_common.h>
10 #include <rte_debug.h>
11 #include <rte_lcore.h>
13 #include "eal_private.h"
14 #include "eal_thread.h"
15 #include "eal_windows.h"
17 /** Number of logical processors (cores) in a processor group (32 or 64). */
18 #define EAL_PROCESSOR_GROUP_SIZE (sizeof(KAFFINITY) * CHAR_BIT)
30 unsigned int lcore_count;
31 unsigned int socket_count;
32 unsigned int cpu_count;
33 struct lcore_map lcores[RTE_MAX_LCORE];
34 struct socket_map sockets[RTE_MAX_NUMA_NODES];
35 GROUP_AFFINITY cpus[CPU_SETSIZE];
38 static struct cpu_map cpu_map;
40 /* eal_create_cpu_map() is called before logging is initialized */
42 __rte_format_printf(1, 2)
43 log_early(const char *format, ...)
48 vfprintf(stderr, format, va);
53 eal_query_group_affinity(void)
55 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *infos = NULL;
56 unsigned int *cpu_count = &cpu_map.cpu_count;
64 if (!GetLogicalProcessorInformationEx(RelationGroup, NULL,
66 DWORD error = GetLastError();
67 if (error != ERROR_INSUFFICIENT_BUFFER) {
68 RTE_LOG(ERR, EAL, "Cannot get group information size, error %lu\n", error);
75 infos = malloc(infos_size);
77 RTE_LOG(ERR, EAL, "Cannot allocate memory for NUMA node information\n");
83 if (!GetLogicalProcessorInformationEx(RelationGroup, infos,
85 RTE_LOG(ERR, EAL, "Cannot get group information, error %lu\n",
93 group_count = infos->Group.ActiveGroupCount;
94 for (group_no = 0; group_no < group_count; group_no++) {
95 affinity = infos->Group.GroupInfo[group_no].ActiveProcessorMask;
96 for (i = 0; i < EAL_PROCESSOR_GROUP_SIZE; i++) {
97 if ((affinity & ((KAFFINITY)1 << i)) == 0)
99 cpu_map.cpus[*cpu_count].Group = group_no;
100 cpu_map.cpus[*cpu_count].Mask = (KAFFINITY)1 << i;
111 eal_create_lcore_map(const SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *info)
113 const unsigned int node_id = info->NumaNode.NodeNumber;
114 const GROUP_AFFINITY *cores = &info->NumaNode.GroupMask;
115 struct lcore_map *lcore;
116 unsigned int socket_id;
120 * NUMA node may be reported multiple times if it includes
121 * cores from different processor groups, e. g. 80 cores
122 * of a physical processor comprise one NUMA node, but two
123 * processor groups, because group size is limited by 32/64.
125 for (socket_id = 0; socket_id < cpu_map.socket_count; socket_id++)
126 if (cpu_map.sockets[socket_id].node_id == node_id)
129 if (socket_id == cpu_map.socket_count) {
130 if (socket_id == RTE_DIM(cpu_map.sockets))
133 cpu_map.sockets[socket_id].node_id = node_id;
134 cpu_map.socket_count++;
137 for (i = 0; i < EAL_PROCESSOR_GROUP_SIZE; i++) {
138 if ((cores->Mask & ((KAFFINITY)1 << i)) == 0)
141 if (cpu_map.lcore_count == RTE_DIM(cpu_map.lcores))
144 lcore = &cpu_map.lcores[cpu_map.lcore_count];
145 lcore->socket_id = socket_id;
146 lcore->core_id = cores->Group * EAL_PROCESSOR_GROUP_SIZE + i;
147 cpu_map.lcore_count++;
153 eal_create_cpu_map(void)
155 SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *infos, *info;
162 if (!GetLogicalProcessorInformationEx(
163 RelationNumaNode, NULL, &infos_size)) {
164 DWORD error = GetLastError();
165 if (error != ERROR_INSUFFICIENT_BUFFER) {
166 log_early("Cannot get NUMA node info size, error %lu\n",
174 infos = malloc(infos_size);
176 log_early("Cannot allocate memory for NUMA node information\n");
182 if (!GetLogicalProcessorInformationEx(
183 RelationNumaNode, infos, &infos_size)) {
184 log_early("Cannot get NUMA node information, error %lu\n",
192 while ((uint8_t *)info - (uint8_t *)infos < infos_size) {
193 if (eal_create_lcore_map(info)) {
198 info = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(
199 (uint8_t *)info + info->Size);
202 if (eal_query_group_affinity()) {
204 * No need to set rte_errno here.
205 * It is set by eal_query_group_affinity().
213 /* Not a fatal error, but important for troubleshooting. */
214 log_early("Enumerated maximum of %u NUMA nodes and %u cores\n",
215 cpu_map.socket_count, cpu_map.lcore_count);
224 eal_cpu_detected(unsigned int lcore_id)
226 return lcore_id < cpu_map.lcore_count;
230 eal_cpu_socket_id(unsigned int lcore_id)
232 return cpu_map.lcores[lcore_id].socket_id;
236 eal_cpu_core_id(unsigned int lcore_id)
238 return cpu_map.lcores[lcore_id].core_id;
242 eal_socket_numa_node(unsigned int socket_id)
244 return cpu_map.sockets[socket_id].node_id;
248 eal_get_cpu_affinity(size_t cpu_index)
250 RTE_VERIFY(cpu_index < CPU_SETSIZE);
252 return &cpu_map.cpus[cpu_index];