xref: /dpdk/lib/eal/include/rte_lcore.h (revision 9625d8dbd9248490026088a7f861c3fc03e4b139)
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 rte_lcore_id(void)
79 {
80 	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  * Register a callback from an application to be called in rte_lcore_dump() and
363  * the /eal/lcore/info telemetry endpoint handler. Applications are expected to
364  * report lcore usage statistics via this callback.
365  *
366  * If a callback was already registered, it can be replaced with another callback
367  * or unregistered with NULL. The previously registered callback may remain in
368  * use for an undetermined period of time.
369  *
370  * @param cb
371  *   The callback function.
372  */
373 void rte_lcore_register_usage_cb(rte_lcore_usage_cb cb);
374 
375 /**
376  * List all lcores.
377  *
378  * @param f
379  *   The output stream where the dump should be sent.
380  */
381 void
382 rte_lcore_dump(FILE *f);
383 
384 /**
385  * Register current non-EAL thread as a lcore.
386  *
387  * @note This API is not compatible with the multi-process feature:
388  * - if a primary process registers a non-EAL thread, then no secondary process
389  *   will initialise.
390  * - if a secondary process initialises successfully, trying to register a
391  *   non-EAL thread from either primary or secondary processes will always end
392  *   up with the thread getting LCORE_ID_ANY as lcore.
393  *
394  * @return
395  *   On success, return 0; otherwise return -1 with rte_errno set.
396  */
397 int
398 rte_thread_register(void);
399 
400 /**
401  * Unregister current thread and release lcore if one was associated.
402  */
403 void
404 rte_thread_unregister(void);
405 
406 #ifdef __cplusplus
407 }
408 #endif
409 
410 
411 #endif /* _RTE_LCORE_H_ */
412