eal: deinline lcore APIs
[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                 lcore_id = (int)rte_lcore_id();
36
37         return lcore_config[lcore_id].core_index;
38 }
39
40 int rte_lcore_to_cpu_id(int lcore_id)
41 {
42         if (unlikely(lcore_id >= RTE_MAX_LCORE))
43                 return -1;
44
45         if (lcore_id < 0)
46                 lcore_id = (int)rte_lcore_id();
47
48         return lcore_config[lcore_id].core_id;
49 }
50
51 rte_cpuset_t rte_lcore_cpuset(unsigned int lcore_id)
52 {
53         return lcore_config[lcore_id].cpuset;
54 }
55
56 int rte_lcore_is_enabled(unsigned int lcore_id)
57 {
58         struct rte_config *cfg = rte_eal_get_configuration();
59
60         if (lcore_id >= RTE_MAX_LCORE)
61                 return 0;
62         return cfg->lcore_role[lcore_id] == ROLE_RTE;
63 }
64
65 unsigned int rte_get_next_lcore(unsigned int i, int skip_master, int wrap)
66 {
67         i++;
68         if (wrap)
69                 i %= RTE_MAX_LCORE;
70
71         while (i < RTE_MAX_LCORE) {
72                 if (!rte_lcore_is_enabled(i) ||
73                     (skip_master && (i == rte_get_master_lcore()))) {
74                         i++;
75                         if (wrap)
76                                 i %= RTE_MAX_LCORE;
77                         continue;
78                 }
79                 break;
80         }
81         return i;
82 }
83
84 unsigned int
85 rte_lcore_to_socket_id(unsigned int lcore_id)
86 {
87         return lcore_config[lcore_id].socket_id;
88 }
89
90 static int
91 socket_id_cmp(const void *a, const void *b)
92 {
93         const int *lcore_id_a = a;
94         const int *lcore_id_b = b;
95
96         if (*lcore_id_a < *lcore_id_b)
97                 return -1;
98         if (*lcore_id_a > *lcore_id_b)
99                 return 1;
100         return 0;
101 }
102
103 /*
104  * Parse /sys/devices/system/cpu to get the number of physical and logical
105  * processors on the machine. The function will fill the cpu_info
106  * structure.
107  */
108 int
109 rte_eal_cpu_init(void)
110 {
111         /* pointer to global configuration */
112         struct rte_config *config = rte_eal_get_configuration();
113         unsigned lcore_id;
114         unsigned count = 0;
115         unsigned int socket_id, prev_socket_id;
116         int lcore_to_socket_id[RTE_MAX_LCORE];
117
118         /*
119          * Parse the maximum set of logical cores, detect the subset of running
120          * ones and enable them by default.
121          */
122         for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
123                 lcore_config[lcore_id].core_index = count;
124
125                 /* init cpuset for per lcore config */
126                 CPU_ZERO(&lcore_config[lcore_id].cpuset);
127
128                 /* find socket first */
129                 socket_id = eal_cpu_socket_id(lcore_id);
130                 lcore_to_socket_id[lcore_id] = socket_id;
131
132                 /* in 1:1 mapping, record related cpu detected state */
133                 lcore_config[lcore_id].detected = eal_cpu_detected(lcore_id);
134                 if (lcore_config[lcore_id].detected == 0) {
135                         config->lcore_role[lcore_id] = ROLE_OFF;
136                         lcore_config[lcore_id].core_index = -1;
137                         continue;
138                 }
139
140                 /* By default, lcore 1:1 map to cpu id */
141                 CPU_SET(lcore_id, &lcore_config[lcore_id].cpuset);
142
143                 /* By default, each detected core is enabled */
144                 config->lcore_role[lcore_id] = ROLE_RTE;
145                 lcore_config[lcore_id].core_role = ROLE_RTE;
146                 lcore_config[lcore_id].core_id = eal_cpu_core_id(lcore_id);
147                 lcore_config[lcore_id].socket_id = socket_id;
148                 RTE_LOG(DEBUG, EAL, "Detected lcore %u as "
149                                 "core %u on socket %u\n",
150                                 lcore_id, lcore_config[lcore_id].core_id,
151                                 lcore_config[lcore_id].socket_id);
152                 count++;
153         }
154         /* Set the count of enabled logical cores of the EAL configuration */
155         config->lcore_count = count;
156         RTE_LOG(DEBUG, EAL,
157                 "Support maximum %u logical core(s) by configuration.\n",
158                 RTE_MAX_LCORE);
159         RTE_LOG(INFO, EAL, "Detected %u lcore(s)\n", config->lcore_count);
160
161         /* sort all socket id's in ascending order */
162         qsort(lcore_to_socket_id, RTE_DIM(lcore_to_socket_id),
163                         sizeof(lcore_to_socket_id[0]), socket_id_cmp);
164
165         prev_socket_id = -1;
166         config->numa_node_count = 0;
167         for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
168                 socket_id = lcore_to_socket_id[lcore_id];
169                 if (socket_id != prev_socket_id)
170                         config->numa_nodes[config->numa_node_count++] =
171                                         socket_id;
172                 prev_socket_id = socket_id;
173         }
174         RTE_LOG(INFO, EAL, "Detected %u NUMA nodes\n", config->numa_node_count);
175
176         return 0;
177 }
178
179 unsigned int
180 rte_socket_count(void)
181 {
182         const struct rte_config *config = rte_eal_get_configuration();
183         return config->numa_node_count;
184 }
185
186 int
187 rte_socket_id_by_idx(unsigned int idx)
188 {
189         const struct rte_config *config = rte_eal_get_configuration();
190         if (idx >= config->numa_node_count) {
191                 rte_errno = EINVAL;
192                 return -1;
193         }
194         return config->numa_nodes[idx];
195 }