5#ifndef _RTE_GRAPH_WORKER_COMMON_H_
6#define _RTE_GRAPH_WORKER_COMMON_H_
33#define RTE_GRAPH_MODEL_RTC 0
34#define RTE_GRAPH_MODEL_MCORE_DISPATCH 1
36#define RTE_GRAPH_MODEL_DEFAULT RTE_GRAPH_MODEL_RTC
43SLIST_HEAD(rte_graph_rq_head, rte_graph);
56 uint64_t *src_pending;
57 uint16_t nb_sched_words;
63 alignas(RTE_CACHE_LINE_SIZE)
struct rte_graph_rq_head *rq;
65 struct rte_graph_rq_head rq_head;
67 unsigned int lcore_id;
74 SLIST_ENTRY(rte_graph) next;
81 uint64_t nb_pkt_captured;
83 uint64_t nb_pkt_to_capture;
101 uint32_t realloc_count;
112 unsigned int lcore_id;
113 uint64_t total_sched_objs;
114 uint64_t total_sched_fail;
115 struct rte_graph *graph;
124#ifdef RTE_GRAPH_PROFILE
146#define RTE_NODE_CTX_SZ 16
148 uint8_t ctx[RTE_NODE_CTX_SZ];
149 __extension__
struct {
166 uint64_t process_u64;
172#ifndef RTE_GRAPH_PROFILE
173static_assert(
offsetof(
struct rte_node, nodes) -
offsetof(
struct rte_node, ctx)
189void __rte_node_stream_alloc(
struct rte_graph *graph,
struct rte_node *node);
205void __rte_node_stream_alloc_size(
struct rte_graph *graph,
206 struct rte_node *node, uint16_t req_size);
221__rte_node_process(
struct rte_graph *graph,
struct rte_node *node)
232 cycles = rte_rdtsc();
233 rc = node->process(graph, node, objs, node->idx);
234 cycles = rte_rdtsc() - cycles;
235 node->total_cycles += cycles;
237 node->total_objs += rc;
238#ifdef RTE_GRAPH_PROFILE
239 static_assert(RTE_GRAPH_PROFILE_BURST_SMALL >= 2,
240 "BURST_SMALL must be >= 2");
241 static_assert(RTE_GRAPH_PROFILE_BURST_SMALL < RTE_GRAPH_PROFILE_BURST_MEDIUM,
242 "BURST_SMALL must be < BURST_MEDIUM");
243 static_assert(RTE_GRAPH_PROFILE_BURST_MEDIUM < RTE_GRAPH_PROFILE_BURST_LARGE,
244 "BURST_MEDIUM must be < BURST_LARGE");
246 node->usage_stats_01[rc].calls++;
247 node->usage_stats_01[rc].cycles += cycles;
251 if (rc >= RTE_GRAPH_PROFILE_BURST_LARGE)
253 else if (rc >= RTE_GRAPH_PROFILE_BURST_MEDIUM)
255 else if (rc >= RTE_GRAPH_PROFILE_BURST_SMALL)
260 node->usage_stats[index].calls++;
261 node->usage_stats[index].cycles += cycles;
262 node->usage_stats[index].objs += rc;
266 node->process(graph, node, objs, node->idx);
286static inline struct rte_node *
287__rte_graph_pending_node(
struct rte_graph *graph, uint16_t word, uint16_t bit)
289 const uint16_t index = (word *
sizeof(*graph->pending) * CHAR_BIT) + bit;
291 return (
struct rte_node *)
RTE_PTR_ADD(graph, node_offset);
305__rte_node_pending_set(uint64_t *bitmap,
struct rte_node *node)
307 const uint16_t word = node->sched_idx / (
sizeof(*bitmap) * CHAR_BIT);
308 const uint16_t bit = node->sched_idx % (
sizeof(*bitmap) * CHAR_BIT);
309 bitmap[word] |= 1ULL << bit;
330__rte_node_enqueue_prologue(
struct rte_graph *graph,
struct rte_node *node,
331 const uint16_t idx,
const uint16_t space)
335 __rte_node_pending_set(graph->pending, node);
337 if (
unlikely(node->size < (idx + space)))
338 __rte_node_stream_alloc_size(graph, node, node->size + space);
355__rte_node_next_node_get(
struct rte_node *node,
rte_edge_t next)
357 RTE_ASSERT(next < node->nb_edges);
359 node = node->nodes[next];
382 rte_edge_t next,
void **objs, uint16_t nb_objs)
384 node = __rte_node_next_node_get(node, next);
385 const uint16_t idx = node->idx;
387 __rte_node_enqueue_prologue(graph, node, idx, nb_objs);
389 rte_memcpy(&node->objs[idx], objs, nb_objs *
sizeof(
void *));
390 node->idx = idx + nb_objs;
410 node = __rte_node_next_node_get(node, next);
411 uint16_t idx = node->idx;
413 __rte_node_enqueue_prologue(graph, node, idx, 1);
415 node->objs[idx++] = obj;
439 node = __rte_node_next_node_get(node, next);
440 uint16_t idx = node->idx;
442 __rte_node_enqueue_prologue(graph, node, idx, 2);
444 node->objs[idx++] = obj0;
445 node->objs[idx++] = obj1;
471 rte_edge_t next,
void *obj0,
void *obj1,
void *obj2,
474 node = __rte_node_next_node_get(node, next);
475 uint16_t idx = node->idx;
477 __rte_node_enqueue_prologue(graph, node, idx, 4);
479 node->objs[idx++] = obj0;
480 node->objs[idx++] = obj1;
481 node->objs[idx++] = obj2;
482 node->objs[idx++] = obj3;
504 rte_edge_t *nexts,
void **objs, uint16_t nb_objs)
508 for (i = 0; i < nb_objs; i++)
535 node = __rte_node_next_node_get(node, next);
536 const uint16_t idx = node->idx;
537 uint16_t free_space = node->size - idx;
540 __rte_node_stream_alloc_size(graph, node, node->size + nb_objs);
542 return &node->objs[idx];
568 node = __rte_node_next_node_get(node, next);
570 __rte_node_pending_set(graph->pending, node);
593 struct rte_node *dst = __rte_node_next_node_get(src, next);
596 if (
likely(dst->idx == 0)) {
597 void **dobjs = dst->objs;
598 uint16_t dsz = dst->size;
599 dst->objs = src->objs;
600 dst->size = src->size;
604 __rte_node_pending_set(graph->pending, dst);
683 uint64_t *xstat = (uint64_t *)
RTE_PTR_ADD(node, node->xstat_off);
684 xstat[xstat_id] += value;
#define RTE_CACHE_LINE_MIN_SIZE
#define offsetof(TYPE, MEMBER)
#define RTE_PTR_ADD(ptr, x)
#define __rte_cache_aligned
#define __rte_always_inline
uint16_t(* rte_node_process_t)(struct rte_graph *graph, struct rte_node *node, void **objs, uint16_t nb_objs)
void(* packets_enqueued_cb)(struct rte_graph *graph, uint64_t cb_priv)
#define RTE_NODE_NAMESIZE
#define RTE_GRAPH_PCAP_FILE_SZ
#define RTE_GRAPH_NAMESIZE
static __rte_always_inline int rte_graph_has_stats_feature(void)
static __rte_always_inline uint8_t rte_graph_worker_model_no_check_get(struct rte_graph *graph)
static void rte_node_enqueue_x4(struct rte_graph *graph, struct rte_node *node, rte_edge_t next, void *obj0, void *obj1, void *obj2, void *obj3)
bool rte_graph_model_is_valid(uint8_t model)
static void rte_node_next_stream_put(struct rte_graph *graph, struct rte_node *node, rte_edge_t next, uint16_t idx)
static void rte_node_enqueue(struct rte_graph *graph, struct rte_node *node, rte_edge_t next, void **objs, uint16_t nb_objs)
static void rte_node_next_stream_move(struct rte_graph *graph, struct rte_node *src, rte_edge_t next)
int rte_graph_worker_model_set(uint8_t model)
static void rte_node_enqueue_next(struct rte_graph *graph, struct rte_node *node, rte_edge_t *nexts, void **objs, uint16_t nb_objs)
static void rte_node_enqueue_x1(struct rte_graph *graph, struct rte_node *node, rte_edge_t next, void *obj)
static __rte_experimental void rte_node_xstat_increment(struct rte_node *node, uint16_t xstat_id, uint64_t value)
static void ** rte_node_next_stream_get(struct rte_graph *graph, struct rte_node *node, rte_edge_t next, uint16_t nb_objs)
static void rte_node_enqueue_x2(struct rte_graph *graph, struct rte_node *node, rte_edge_t next, void *obj0, void *obj1)
uint8_t rte_graph_worker_model_get(struct rte_graph *graph)
static void * rte_memcpy(void *dst, const void *src, size_t n)
static void rte_prefetch0(const volatile void *p)
char name[RTE_MEMPOOL_NAMESIZE]
rte_node_process_t process