lib: remove librte_ prefix from directory names
[dpdk.git] / lib / eal / windows / eal_lcore.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019 Intel Corporation
3  */
4
5 #include <pthread.h>
6 #include <stdbool.h>
7 #include <stdint.h>
8
9 #include <rte_common.h>
10 #include <rte_debug.h>
11 #include <rte_lcore.h>
12
13 #include "eal_private.h"
14 #include "eal_thread.h"
15 #include "eal_windows.h"
16
17 /** Number of logical processors (cores) in a processor group (32 or 64). */
18 #define EAL_PROCESSOR_GROUP_SIZE (sizeof(KAFFINITY) * CHAR_BIT)
19
20 struct lcore_map {
21         uint8_t socket_id;
22         uint8_t core_id;
23 };
24
25 struct socket_map {
26         uint16_t node_id;
27 };
28
29 struct cpu_map {
30         unsigned int socket_count;
31         unsigned int lcore_count;
32         struct lcore_map lcores[RTE_MAX_LCORE];
33         struct socket_map sockets[RTE_MAX_NUMA_NODES];
34 };
35
36 static struct cpu_map cpu_map = { 0 };
37
38 /* eal_create_cpu_map() is called before logging is initialized */
39 static void
40 __rte_format_printf(1, 2)
41 log_early(const char *format, ...)
42 {
43         va_list va;
44
45         va_start(va, format);
46         vfprintf(stderr, format, va);
47         va_end(va);
48 }
49
50 int
51 eal_create_cpu_map(void)
52 {
53         SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *infos, *info;
54         DWORD infos_size;
55         bool full = false;
56
57         infos_size = 0;
58         if (!GetLogicalProcessorInformationEx(
59                         RelationNumaNode, NULL, &infos_size)) {
60                 DWORD error = GetLastError();
61                 if (error != ERROR_INSUFFICIENT_BUFFER) {
62                         log_early("Cannot get NUMA node info size, error %lu\n",
63                                 GetLastError());
64                         rte_errno = ENOMEM;
65                         return -1;
66                 }
67         }
68
69         infos = malloc(infos_size);
70         if (infos == NULL) {
71                 log_early("Cannot allocate memory for NUMA node information\n");
72                 rte_errno = ENOMEM;
73                 return -1;
74         }
75
76         if (!GetLogicalProcessorInformationEx(
77                         RelationNumaNode, infos, &infos_size)) {
78                 log_early("Cannot get NUMA node information, error %lu\n",
79                         GetLastError());
80                 rte_errno = EINVAL;
81                 return -1;
82         }
83
84         info = infos;
85         while ((uint8_t *)info - (uint8_t *)infos < infos_size) {
86                 unsigned int node_id = info->NumaNode.NodeNumber;
87                 GROUP_AFFINITY *cores = &info->NumaNode.GroupMask;
88                 struct lcore_map *lcore;
89                 unsigned int i, socket_id;
90
91                 /* NUMA node may be reported multiple times if it includes
92                  * cores from different processor groups, e. g. 80 cores
93                  * of a physical processor comprise one NUMA node, but two
94                  * processor groups, because group size is limited by 32/64.
95                  */
96                 for (socket_id = 0; socket_id < cpu_map.socket_count;
97                     socket_id++) {
98                         if (cpu_map.sockets[socket_id].node_id == node_id)
99                                 break;
100                 }
101
102                 if (socket_id == cpu_map.socket_count) {
103                         if (socket_id == RTE_DIM(cpu_map.sockets)) {
104                                 full = true;
105                                 goto exit;
106                         }
107
108                         cpu_map.sockets[socket_id].node_id = node_id;
109                         cpu_map.socket_count++;
110                 }
111
112                 for (i = 0; i < EAL_PROCESSOR_GROUP_SIZE; i++) {
113                         if ((cores->Mask & ((KAFFINITY)1 << i)) == 0)
114                                 continue;
115
116                         if (cpu_map.lcore_count == RTE_DIM(cpu_map.lcores)) {
117                                 full = true;
118                                 goto exit;
119                         }
120
121                         lcore = &cpu_map.lcores[cpu_map.lcore_count];
122                         lcore->socket_id = socket_id;
123                         lcore->core_id =
124                                 cores->Group * EAL_PROCESSOR_GROUP_SIZE + i;
125                         cpu_map.lcore_count++;
126                 }
127
128                 info = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(
129                         (uint8_t *)info + info->Size);
130         }
131
132 exit:
133         if (full) {
134                 /* Not a fatal error, but important for troubleshooting. */
135                 log_early("Enumerated maximum of %u NUMA nodes and %u cores\n",
136                         cpu_map.socket_count, cpu_map.lcore_count);
137         }
138
139         free(infos);
140
141         return 0;
142 }
143
144 int
145 eal_cpu_detected(unsigned int lcore_id)
146 {
147         return lcore_id < cpu_map.lcore_count;
148 }
149
150 unsigned
151 eal_cpu_socket_id(unsigned int lcore_id)
152 {
153         return cpu_map.lcores[lcore_id].socket_id;
154 }
155
156 unsigned
157 eal_cpu_core_id(unsigned int lcore_id)
158 {
159         return cpu_map.lcores[lcore_id].core_id;
160 }
161
162 unsigned int
163 eal_socket_numa_node(unsigned int socket_id)
164 {
165         return cpu_map.sockets[socket_id].node_id;
166 }