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