Data Accelerator Offload
Loading...
Searching...
No Matches
dao_workers.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: Marvell-MIT
2 * Copyright (c) 2023 Marvell.
3 */
4
5#ifndef _DAO_LIB_WORKERS_H_
6#define _DAO_LIB_WORKERS_H_
7
49#include <errno.h>
50#include <stdint.h>
51#include <stdlib.h>
52#include <string.h>
53#include <stdio.h>
54#include <stddef.h>
55#include <signal.h>
56#include <assert.h>
57
58#include <rte_common.h>
59#include <rte_compat.h>
60#include <rte_debug.h>
61#include <rte_lcore.h>
62#include <rte_bitops.h>
63#include <rte_atomic.h>
64#include <rte_pause.h>
65
66#include <dao_log.h>
67#include <dao_util.h>
68
69#ifdef __cplusplus
70extern "C" {
71#endif
72
74#define DAO_WORKER_INVALID_INDEX UINT32_C(~0)
75
76#define DAO_WORKERS_LOG dao_dbg
77
85typedef struct dao_worker {
87 unsigned int dpdk_lcore_id;
88
91
94
96 uint32_t worker_index;
97
99 uint32_t core_index;
100
101 int dpdk_numa_id;
102
103 /* is this worker dpdk_main_core where rte_eal_init*/
104 int is_main;
105
106 /* back pointer to dao_workers_main */
107 void *dao_workers;
108
109 /* Size of app_private[] on worker */
110 size_t app_private_size;
111
112 RTE_MARKER c1 __rte_cache_aligned;
113 uint8_t app_private[];
114} dao_worker_t __rte_cache_aligned;
115
116typedef struct dao_workers_main {
117 RTE_MARKER c0 __rte_cache_aligned;
118
120 uint16_t num_cores;
121
123 uint16_t num_workers;
124
126 uint64_t core_mask;
127
128 uint32_t control_core_index;
129
131 size_t per_worker_sz;
132
134 size_t workers_main_sz;
135
137 int barrier_recursion_level;
138
140 RTE_MARKER c1 __rte_cache_aligned;
141 uint64_t parked_at_barrier;
142
144 RTE_MARKER c2 __rte_cache_aligned;
145 uint64_t barrier_count;
146
147 RTE_MARKER c3 __rte_cache_aligned;
149 dao_worker_t workers[];
150} dao_workers_main_t;
151
153extern dao_workers_main_t *__dao_workers;
154
155/* Static inline functions */
156
165static inline dao_worker_t *
166dao_workers_worker_get(dao_workers_main_t *dwm, uint8_t worker_index)
167{
168 RTE_VERIFY(dwm);
169 RTE_VERIFY(worker_index <= dwm->num_workers);
170
171 return ((dao_worker_t *)((uint8_t *)dwm->workers + (worker_index * dwm->per_worker_sz)));
172}
173
185static inline int
186dao_workers_app_data_get(dao_worker_t *wrkr, void **app_data, size_t *size)
187{
188 if (likely(wrkr)) {
189 if (app_data)
190 *app_data = wrkr->app_private;
191
192 if (size)
193 *size = wrkr->app_private_size;
194
195 return 0;
196 }
197 return -1;
198}
199
210static inline int
211dao_workers_core_index_get(dao_worker_t *wrkr)
212{
213 return wrkr->core_index;
214}
215
226static inline int
228{
229 return wrkr->worker_index;
230}
231
238static inline int
239dao_workers_numa_get(dao_worker_t *wrkr)
240{
241 return wrkr->dpdk_numa_id;
242}
243
251static inline int dao_workers_is_control_worker(dao_worker_t *worker)
252{
253 return worker->is_main;
254}
255
265static inline dao_worker_t *
266dao_workers_control_worker_get(dao_workers_main_t *dwm)
267{
268 if (likely(dwm && (dwm->control_core_index != DAO_WORKER_INVALID_INDEX)))
269 return (dwm->workers + dwm->control_core_index);
270 return NULL;
271}
272
280static inline dao_workers_main_t *dao_workers_get(void)
281{
282 return __dao_workers;
283}
284
285static inline int
286__dao_workers_num_workers_get(dao_workers_main_t *dwm)
287{
288 return dwm->num_workers;
289}
290
297static inline int dao_workers_num_workers_get(void)
298{
299 return __dao_workers_num_workers_get(dao_workers_get());
300}
301
308static inline int dao_workers_num_cores_get(void)
309{
310 dao_workers_main_t *dwm = dao_workers_get();
311
312 return dwm->num_cores;
313}
314
323static inline dao_worker_t *
325{
326 dao_workers_main_t *wm = dao_workers_get();
327 dao_worker_t *wrkr = NULL;
328 unsigned int lcore_id;
329 uint16_t i;
330
331 lcore_id = rte_lcore_id();
332
333 for (i = 0; i < wm->num_cores; i++) {
334 wrkr = dao_workers_worker_get(wm, i);
335
336 /* wrkr is sane */
337 assert(wrkr->core_index == i);
338 assert(wm == wrkr->dao_workers);
339
340 if (wrkr->dpdk_lcore_id != lcore_id)
341 continue;
342
343 if (LCORE_ID_ANY == lcore_id)
344 continue;
345
346 break;
347 }
348 if (i < wm->num_cores)
349 return (dao_workers_worker_get(wm, i));
350
351 /* We should not reach here */
352 return NULL;
353}
354
355/* Function declaration */
356
378int dao_workers_init(uint64_t core_mask, uint32_t control_core_index, size_t per_core_app_data_sz);
379
400int dao_workers_barrier_sync(dao_worker_t *worker);
401
414int dao_workers_barrier_release(dao_worker_t *worker);
415
426static inline void
427dao_workers_barrier_check(dao_worker_t *worker)
428{
429 dao_workers_main_t *dwm = (dao_workers_main_t *)worker->dao_workers;
430
431 if (unlikely(__atomic_load_n(&dwm->parked_at_barrier, __ATOMIC_ACQUIRE))) {
432 DAO_WORKERS_LOG("Worker%d: going to barrier 0x%lx ",
434 __atomic_load_n(&dwm->barrier_count, __ATOMIC_RELAXED));
435
436 __atomic_add_fetch(&dwm->barrier_count, 1, __ATOMIC_RELEASE);
437
438 /* Busy wait worker core until control-core releases barrier */
439 while (__atomic_load_n(&dwm->parked_at_barrier, __ATOMIC_RELAXED))
440 rte_pause();
441
442 DAO_WORKERS_LOG("Worker: %d released from barrier",
444 }
445}
446
447#ifdef __cplusplus
448}
449#endif
450#endif
static int dao_workers_core_index_get(dao_worker_t *wrkr)
static int dao_workers_numa_get(dao_worker_t *wrkr)
dao_workers_main_t * __dao_workers
static dao_workers_main_t * dao_workers_get(void)
static void dao_workers_barrier_check(dao_worker_t *worker)
static dao_worker_t * dao_workers_control_worker_get(dao_workers_main_t *dwm)
static int dao_workers_is_control_worker(dao_worker_t *worker)
static int dao_workers_app_data_get(dao_worker_t *wrkr, void **app_data, size_t *size)
static dao_worker_t * dao_workers_worker_get(dao_workers_main_t *dwm, uint8_t worker_index)
int dao_workers_init(uint64_t core_mask, uint32_t control_core_index, size_t per_core_app_data_sz)
static int dao_workers_num_cores_get(void)
int dao_workers_barrier_release(dao_worker_t *worker)
int dao_workers_fini(void)
#define DAO_WORKER_INVALID_INDEX
Definition dao_workers.h:74
struct dao_worker __rte_cache_aligned
static int dao_workers_num_workers_get(void)
static dao_worker_t * dao_workers_self_worker_get(void)
int dao_workers_barrier_sync(dao_worker_t *worker)
static int dao_workers_worker_index_get(dao_worker_t *wrkr)
uint32_t core_index
Definition dao_workers.h:99
int dpdk_cpu_id
Definition dao_workers.h:90
uint32_t worker_index
Definition dao_workers.h:96
unsigned int dpdk_lcore_id
Definition dao_workers.h:87
int dpdk_core_index
Definition dao_workers.h:93