eal: fix lcore accessors for non-EAL threads
[dpdk.git] / lib / librte_eal / common / eal_common_lcore.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4
5 #include <unistd.h>
6 #include <limits.h>
7 #include <string.h>
8
9 #include <rte_errno.h>
10 #include <rte_log.h>
11 #include <rte_eal.h>
12 #include <rte_lcore.h>
13 #include <rte_common.h>
14 #include <rte_debug.h>
15
16 #include "eal_private.h"
17 #include "eal_thread.h"
18
19 unsigned int rte_get_master_lcore(void)
20 {
21         return rte_eal_get_configuration()->master_lcore;
22 }
23
24 unsigned int rte_lcore_count(void)
25 {
26         return rte_eal_get_configuration()->lcore_count;
27 }
28
29 int rte_lcore_index(int lcore_id)
30 {
31         if (unlikely(lcore_id >= RTE_MAX_LCORE))
32                 return -1;
33
34         if (lcore_id < 0) {
35                 if (rte_lcore_id() == LCORE_ID_ANY)
36                         return -1;
37
38                 lcore_id = (int)rte_lcore_id();
39         }
40
41         return lcore_config[lcore_id].core_index;
42 }
43
44 int rte_lcore_to_cpu_id(int lcore_id)
45 {
46         if (unlikely(lcore_id >= RTE_MAX_LCORE))
47                 return -1;
48
49         if (lcore_id < 0) {
50                 if (rte_lcore_id() == LCORE_ID_ANY)
51                         return -1;
52
53                 lcore_id = (int)rte_lcore_id();
54         }
55
56         return lcore_config[lcore_id].core_id;
57 }
58
59 rte_cpuset_t rte_lcore_cpuset(unsigned int lcore_id)
60 {
61         return lcore_config[lcore_id].cpuset;
62 }
63
64 enum rte_lcore_role_t
65 rte_eal_lcore_role(unsigned int lcore_id)
66 {
67         struct rte_config *cfg = rte_eal_get_configuration();
68
69         if (lcore_id >= RTE_MAX_LCORE)
70                 return ROLE_OFF;
71         return cfg->lcore_role[lcore_id];
72 }
73
74 int rte_lcore_is_enabled(unsigned int lcore_id)
75 {
76         struct rte_config *cfg = rte_eal_get_configuration();
77
78         if (lcore_id >= RTE_MAX_LCORE)
79                 return 0;
80         return cfg->lcore_role[lcore_id] == ROLE_RTE;
81 }
82
83 unsigned int rte_get_next_lcore(unsigned int i, int skip_master, int wrap)
84 {
85         i++;
86         if (wrap)
87                 i %= RTE_MAX_LCORE;
88
89         while (i < RTE_MAX_LCORE) {
90                 if (!rte_lcore_is_enabled(i) ||
91                     (skip_master && (i == rte_get_master_lcore()))) {
92                         i++;
93                         if (wrap)
94                                 i %= RTE_MAX_LCORE;
95                         continue;
96                 }
97                 break;
98         }
99         return i;
100 }
101
102 unsigned int
103 rte_lcore_to_socket_id(unsigned int lcore_id)
104 {
105         return lcore_config[lcore_id].socket_id;
106 }
107
108 static int
109 socket_id_cmp(const void *a, const void *b)
110 {
111         const int *lcore_id_a = a;
112         const int *lcore_id_b = b;
113
114         if (*lcore_id_a < *lcore_id_b)
115                 return -1;
116         if (*lcore_id_a > *lcore_id_b)
117                 return 1;
118         return 0;
119 }
120
121 /*
122  * Parse /sys/devices/system/cpu to get the number of physical and logical
123  * processors on the machine. The function will fill the cpu_info
124  * structure.
125  */
126 int
127 rte_eal_cpu_init(void)
128 {
129         /* pointer to global configuration */
130         struct rte_config *config = rte_eal_get_configuration();
131         unsigned lcore_id;
132         unsigned count = 0;
133         unsigned int socket_id, prev_socket_id;
134         int lcore_to_socket_id[RTE_MAX_LCORE];
135
136         /*
137          * Parse the maximum set of logical cores, detect the subset of running
138          * ones and enable them by default.
139          */
140         for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
141                 lcore_config[lcore_id].core_index = count;
142
143                 /* init cpuset for per lcore config */
144                 CPU_ZERO(&lcore_config[lcore_id].cpuset);
145
146                 /* find socket first */
147                 socket_id = eal_cpu_socket_id(lcore_id);
148                 lcore_to_socket_id[lcore_id] = socket_id;
149
150                 if (eal_cpu_detected(lcore_id) == 0) {
151                         config->lcore_role[lcore_id] = ROLE_OFF;
152                         lcore_config[lcore_id].core_index = -1;
153                         continue;
154                 }
155
156                 /* By default, lcore 1:1 map to cpu id */
157                 CPU_SET(lcore_id, &lcore_config[lcore_id].cpuset);
158
159                 /* By default, each detected core is enabled */
160                 config->lcore_role[lcore_id] = ROLE_RTE;
161                 lcore_config[lcore_id].core_role = ROLE_RTE;
162                 lcore_config[lcore_id].core_id = eal_cpu_core_id(lcore_id);
163                 lcore_config[lcore_id].socket_id = socket_id;
164                 RTE_LOG(DEBUG, EAL, "Detected lcore %u as "
165                                 "core %u on socket %u\n",
166                                 lcore_id, lcore_config[lcore_id].core_id,
167                                 lcore_config[lcore_id].socket_id);
168                 count++;
169         }
170         for (; lcore_id < CPU_SETSIZE; lcore_id++) {
171                 if (eal_cpu_detected(lcore_id) == 0)
172                         continue;
173                 RTE_LOG(DEBUG, EAL, "Skipped lcore %u as core %u on socket %u\n",
174                         lcore_id, eal_cpu_core_id(lcore_id),
175                         eal_cpu_socket_id(lcore_id));
176         }
177
178         /* Set the count of enabled logical cores of the EAL configuration */
179         config->lcore_count = count;
180         RTE_LOG(DEBUG, EAL,
181                 "Support maximum %u logical core(s) by configuration.\n",
182                 RTE_MAX_LCORE);
183         RTE_LOG(INFO, EAL, "Detected %u lcore(s)\n", config->lcore_count);
184
185         /* sort all socket id's in ascending order */
186         qsort(lcore_to_socket_id, RTE_DIM(lcore_to_socket_id),
187                         sizeof(lcore_to_socket_id[0]), socket_id_cmp);
188
189         prev_socket_id = -1;
190         config->numa_node_count = 0;
191         for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
192                 socket_id = lcore_to_socket_id[lcore_id];
193                 if (socket_id != prev_socket_id)
194                         config->numa_nodes[config->numa_node_count++] =
195                                         socket_id;
196                 prev_socket_id = socket_id;
197         }
198         RTE_LOG(INFO, EAL, "Detected %u NUMA nodes\n", config->numa_node_count);
199
200         return 0;
201 }
202
203 unsigned int
204 rte_socket_count(void)
205 {
206         const struct rte_config *config = rte_eal_get_configuration();
207         return config->numa_node_count;
208 }
209
210 int
211 rte_socket_id_by_idx(unsigned int idx)
212 {
213         const struct rte_config *config = rte_eal_get_configuration();
214         if (idx >= config->numa_node_count) {
215                 rte_errno = EINVAL;
216                 return -1;
217         }
218         return config->numa_nodes[idx];
219 }