Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2010-2014 Intel Corporation
3 : : */
4 : :
5 : : #ifndef _RTE_LCORE_H_
6 : : #define _RTE_LCORE_H_
7 : :
8 : : /**
9 : : * @file
10 : : *
11 : : * API for lcore and socket manipulation
12 : : */
13 : : #include <stdio.h>
14 : :
15 : : #include <rte_compat.h>
16 : : #include <rte_config.h>
17 : : #include <rte_per_lcore.h>
18 : : #include <rte_eal.h>
19 : : #include <rte_launch.h>
20 : : #include <rte_thread.h>
21 : :
22 : : #ifdef __cplusplus
23 : : extern "C" {
24 : : #endif
25 : :
26 : : #define LCORE_ID_ANY UINT32_MAX /**< Any lcore. */
27 : :
28 : : RTE_DECLARE_PER_LCORE(unsigned, _lcore_id); /**< Per thread "lcore id". */
29 : :
30 : : /**
31 : : * The lcore role (used in RTE or not).
32 : : */
33 : : enum rte_lcore_role_t {
34 : : ROLE_RTE,
35 : : ROLE_OFF,
36 : : ROLE_SERVICE,
37 : : ROLE_NON_EAL,
38 : : };
39 : :
40 : : /**
41 : : * Get a lcore's role.
42 : : *
43 : : * @param lcore_id
44 : : * The identifier of the lcore, which MUST be between 0 and RTE_MAX_LCORE-1.
45 : : * @return
46 : : * The role of the lcore.
47 : : */
48 : : enum rte_lcore_role_t rte_eal_lcore_role(unsigned int lcore_id);
49 : :
50 : : /**
51 : : * Test if the core supplied has a specific role
52 : : *
53 : : * @param lcore_id
54 : : * The identifier of the lcore, which MUST be between 0 and
55 : : * RTE_MAX_LCORE-1.
56 : : * @param role
57 : : * The role to be checked against.
58 : : * @return
59 : : * Boolean value: positive if test is true; otherwise returns 0.
60 : : */
61 : : int
62 : : rte_lcore_has_role(unsigned int lcore_id, enum rte_lcore_role_t role);
63 : :
64 : : /**
65 : : * Return the Application thread ID of the execution unit.
66 : : *
67 : : * Note: in most cases the lcore id returned here will also correspond
68 : : * to the processor id of the CPU on which the thread is pinned, this
69 : : * will not be the case if the user has explicitly changed the thread to
70 : : * core affinities using --lcores EAL argument e.g. --lcores '(0-3)@10'
71 : : * to run threads with lcore IDs 0, 1, 2 and 3 on physical core 10..
72 : : *
73 : : * @return
74 : : * Logical core ID (in EAL thread or registered non-EAL thread) or
75 : : * LCORE_ID_ANY (in unregistered non-EAL thread)
76 : : */
77 : : static inline unsigned
78 : 0 : rte_lcore_id(void)
79 : : {
80 [ + + + + : 373203343 : return RTE_PER_LCORE(_lcore_id);
+ + + + +
+ - + + +
- - - - -
- - - + -
+ - - - -
- - - + -
+ - - - -
- + - + -
- - # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
81 : : }
82 : :
83 : : /**
84 : : * Get the id of the main lcore
85 : : *
86 : : * @return
87 : : * the id of the main lcore
88 : : */
89 : : unsigned int rte_get_main_lcore(void);
90 : :
91 : : /**
92 : : * Return the number of execution units (lcores) on the system.
93 : : *
94 : : * @return
95 : : * the number of execution units (lcores) on the system.
96 : : */
97 : : unsigned int rte_lcore_count(void);
98 : :
99 : : /**
100 : : * Return the index of the lcore starting from zero.
101 : : *
102 : : * When option -c or -l is given, the index corresponds
103 : : * to the order in the list.
104 : : * For example:
105 : : * -c 0x30, lcore 4 has index 0, and 5 has index 1.
106 : : * -l 22,18 lcore 22 has index 0, and 18 has index 1.
107 : : *
108 : : * @param lcore_id
109 : : * The targeted lcore, or -1 for the current one.
110 : : * @return
111 : : * The relative index, or -1 if not enabled.
112 : : */
113 : : int rte_lcore_index(int lcore_id);
114 : :
115 : : /**
116 : : * Return the ID of the physical socket of the logical core we are
117 : : * running on.
118 : : * @return
119 : : * the ID of current lcoreid's physical socket
120 : : */
121 : : unsigned int rte_socket_id(void);
122 : :
123 : : /**
124 : : * Return number of physical sockets detected on the system.
125 : : *
126 : : * Note that number of nodes may not be correspondent to their physical id's:
127 : : * for example, a system may report two socket id's, but the actual socket id's
128 : : * may be 0 and 8.
129 : : *
130 : : * @return
131 : : * the number of physical sockets as recognized by EAL
132 : : */
133 : : unsigned int
134 : : rte_socket_count(void);
135 : :
136 : : /**
137 : : * Return socket id with a particular index.
138 : : *
139 : : * This will return socket id at a particular position in list of all detected
140 : : * physical socket id's. For example, on a machine with sockets [0, 8], passing
141 : : * 1 as a parameter will return 8.
142 : : *
143 : : * @param idx
144 : : * index of physical socket id to return
145 : : *
146 : : * @return
147 : : * - physical socket id as recognized by EAL
148 : : * - -1 on error, with errno set to EINVAL
149 : : */
150 : : int
151 : : rte_socket_id_by_idx(unsigned int idx);
152 : :
153 : : /**
154 : : * Get the ID of the physical socket of the specified lcore
155 : : *
156 : : * @param lcore_id
157 : : * the targeted lcore, which MUST be between 0 and RTE_MAX_LCORE-1.
158 : : * @return
159 : : * the ID of lcoreid's physical socket
160 : : */
161 : : unsigned int
162 : : rte_lcore_to_socket_id(unsigned int lcore_id);
163 : :
164 : : /**
165 : : * Return the id of the lcore on a socket starting from zero.
166 : : *
167 : : * @param lcore_id
168 : : * The targeted lcore, or -1 for the current one.
169 : : * @return
170 : : * The relative index, or -1 if not enabled.
171 : : */
172 : : int rte_lcore_to_cpu_id(int lcore_id);
173 : :
174 : : #ifdef RTE_HAS_CPUSET
175 : :
176 : : /**
177 : : * Return the cpuset for a given lcore.
178 : : *
179 : : * @param lcore_id
180 : : * the targeted lcore, which MUST be between 0 and RTE_MAX_LCORE-1.
181 : : * @return
182 : : * The cpuset of that lcore
183 : : */
184 : : rte_cpuset_t rte_lcore_cpuset(unsigned int lcore_id);
185 : :
186 : : #endif /* RTE_HAS_CPUSET */
187 : :
188 : : /**
189 : : * Test if an lcore is enabled.
190 : : *
191 : : * @param lcore_id
192 : : * The identifier of the lcore, which MUST be between 0 and
193 : : * RTE_MAX_LCORE-1.
194 : : * @return
195 : : * True if the given lcore is enabled; false otherwise.
196 : : */
197 : : int rte_lcore_is_enabled(unsigned int lcore_id);
198 : :
199 : : /**
200 : : * Get the next enabled lcore ID.
201 : : *
202 : : * @param i
203 : : * The current lcore (reference).
204 : : * @param skip_main
205 : : * If true, do not return the ID of the main lcore.
206 : : * @param wrap
207 : : * If true, go back to 0 when RTE_MAX_LCORE is reached; otherwise,
208 : : * return RTE_MAX_LCORE.
209 : : * @return
210 : : * The next lcore_id or RTE_MAX_LCORE if not found.
211 : : */
212 : : unsigned int rte_get_next_lcore(unsigned int i, int skip_main, int wrap);
213 : :
214 : : /**
215 : : * Macro to browse all running lcores.
216 : : */
217 : : #define RTE_LCORE_FOREACH(i) \
218 : : for (i = rte_get_next_lcore(-1, 0, 0); \
219 : : i < RTE_MAX_LCORE; \
220 : : i = rte_get_next_lcore(i, 0, 0))
221 : :
222 : : /**
223 : : * Macro to browse all running lcores except the main lcore.
224 : : */
225 : : #define RTE_LCORE_FOREACH_WORKER(i) \
226 : : for (i = rte_get_next_lcore(-1, 1, 0); \
227 : : i < RTE_MAX_LCORE; \
228 : : i = rte_get_next_lcore(i, 1, 0))
229 : :
230 : : /**
231 : : * Callback prototype for initializing lcores.
232 : : *
233 : : * @param lcore_id
234 : : * The lcore to consider.
235 : : * @param arg
236 : : * An opaque pointer passed at callback registration.
237 : : * @return
238 : : * - -1 when refusing this operation,
239 : : * - 0 otherwise.
240 : : */
241 : : typedef int (*rte_lcore_init_cb)(unsigned int lcore_id, void *arg);
242 : :
243 : : /**
244 : : * Callback prototype for uninitializing lcores.
245 : : *
246 : : * @param lcore_id
247 : : * The lcore to consider.
248 : : * @param arg
249 : : * An opaque pointer passed at callback registration.
250 : : */
251 : : typedef void (*rte_lcore_uninit_cb)(unsigned int lcore_id, void *arg);
252 : :
253 : : /**
254 : : * Register callbacks invoked when initializing and uninitializing a lcore.
255 : : *
256 : : * This function calls the init callback with all initialized lcores.
257 : : * Any error reported by the init callback triggers a rollback calling the
258 : : * uninit callback for each lcore.
259 : : * If this step succeeds, the callbacks are put in the lcore callbacks list
260 : : * that will get called for each lcore allocation/release.
261 : : *
262 : : * Note: callbacks execution is serialised under a write lock protecting the
263 : : * lcores and callbacks list.
264 : : *
265 : : * @param name
266 : : * A name serving as a small description for this callback.
267 : : * @param init
268 : : * The callback invoked when a lcore_id is initialized.
269 : : * init can be NULL.
270 : : * @param uninit
271 : : * The callback invoked when a lcore_id is uninitialized.
272 : : * uninit can be NULL.
273 : : * @param arg
274 : : * An optional argument that gets passed to the callback when it gets
275 : : * invoked.
276 : : * @return
277 : : * On success, returns an opaque pointer for the registered object.
278 : : * On failure (either memory allocation issue in the function itself or an
279 : : * error is returned by the init callback itself), returns NULL.
280 : : */
281 : : void *
282 : : rte_lcore_callback_register(const char *name, rte_lcore_init_cb init,
283 : : rte_lcore_uninit_cb uninit, void *arg);
284 : :
285 : : /**
286 : : * Unregister callbacks previously registered with rte_lcore_callback_register.
287 : : *
288 : : * This function calls the uninit callback with all initialized lcores.
289 : : * The callbacks are then removed from the lcore callbacks list.
290 : : *
291 : : * @param handle
292 : : * The handle pointer returned by a former successful call to
293 : : * rte_lcore_callback_register.
294 : : */
295 : : void
296 : : rte_lcore_callback_unregister(void *handle);
297 : :
298 : : /**
299 : : * Callback prototype for iterating over lcores.
300 : : *
301 : : * @param lcore_id
302 : : * The lcore to consider.
303 : : * @param arg
304 : : * An opaque pointer coming from the caller.
305 : : * @return
306 : : * - 0 lets the iteration continue.
307 : : * - !0 makes the iteration stop.
308 : : */
309 : : typedef int (*rte_lcore_iterate_cb)(unsigned int lcore_id, void *arg);
310 : :
311 : : /**
312 : : * Iterate on all active lcores (ROLE_RTE, ROLE_SERVICE and ROLE_NON_EAL).
313 : : * No modification on the lcore states is allowed in the callback.
314 : : *
315 : : * Note: as opposed to init/uninit callbacks, iteration callbacks can be
316 : : * invoked in parallel as they are run under a read lock protecting the lcores
317 : : * and callbacks list.
318 : : *
319 : : * @param cb
320 : : * The callback that gets passed each lcore.
321 : : * @param arg
322 : : * An opaque pointer passed to cb.
323 : : * @return
324 : : * Same return code as the callback last invocation (see rte_lcore_iterate_cb
325 : : * description).
326 : : */
327 : : int
328 : : rte_lcore_iterate(rte_lcore_iterate_cb cb, void *arg);
329 : :
330 : : /**
331 : : * lcore usage statistics.
332 : : */
333 : : struct rte_lcore_usage {
334 : : /**
335 : : * The total amount of time that the application has been running on
336 : : * this lcore, in TSC cycles.
337 : : */
338 : : uint64_t total_cycles;
339 : : /**
340 : : * The amount of time the application was busy, handling some
341 : : * workload on this lcore, in TSC cycles.
342 : : */
343 : : uint64_t busy_cycles;
344 : : };
345 : :
346 : : /**
347 : : * Callback to allow applications to report lcore usage.
348 : : *
349 : : * @param [in] lcore_id
350 : : * The lcore to consider.
351 : : * @param [out] usage
352 : : * Counters representing this lcore usage. This can never be NULL.
353 : : * @return
354 : : * - 0 if fields in usage were updated successfully. The fields that the
355 : : * application does not support must not be modified.
356 : : * - a negative value if the information is not available or if any error
357 : : * occurred.
358 : : */
359 : : typedef int (*rte_lcore_usage_cb)(unsigned int lcore_id, struct rte_lcore_usage *usage);
360 : :
361 : : /**
362 : : * @warning
363 : : * @b EXPERIMENTAL: this API may change without prior notice.
364 : : *
365 : : * Register a callback from an application to be called in rte_lcore_dump() and
366 : : * the /eal/lcore/info telemetry endpoint handler. Applications are expected to
367 : : * report lcore usage statistics via this callback.
368 : : *
369 : : * If a callback was already registered, it can be replaced with another callback
370 : : * or unregistered with NULL. The previously registered callback may remain in
371 : : * use for an undetermined period of time.
372 : : *
373 : : * @param cb
374 : : * The callback function.
375 : : */
376 : : __rte_experimental
377 : : void rte_lcore_register_usage_cb(rte_lcore_usage_cb cb);
378 : :
379 : : /**
380 : : * List all lcores.
381 : : *
382 : : * @param f
383 : : * The output stream where the dump should be sent.
384 : : */
385 : : void
386 : : rte_lcore_dump(FILE *f);
387 : :
388 : : /**
389 : : * Register current non-EAL thread as a lcore.
390 : : *
391 : : * @note This API is not compatible with the multi-process feature:
392 : : * - if a primary process registers a non-EAL thread, then no secondary process
393 : : * will initialise.
394 : : * - if a secondary process initialises successfully, trying to register a
395 : : * non-EAL thread from either primary or secondary processes will always end
396 : : * up with the thread getting LCORE_ID_ANY as lcore.
397 : : *
398 : : * @return
399 : : * On success, return 0; otherwise return -1 with rte_errno set.
400 : : */
401 : : int
402 : : rte_thread_register(void);
403 : :
404 : : /**
405 : : * Unregister current thread and release lcore if one was associated.
406 : : */
407 : : void
408 : : rte_thread_unregister(void);
409 : :
410 : : #ifdef __cplusplus
411 : : }
412 : : #endif
413 : :
414 : :
415 : : #endif /* _RTE_LCORE_H_ */
|