1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2020 Marvell International Ltd.
12 * @b EXPERIMENTAL: this API may change without prior notice
14 * Graph architecture abstracts the data processing functions as
15 * "node" and "link" them together to create a complex "graph" to enable
16 * reusable/modular data processing functions.
18 * This API enables graph framework operations such as create, lookup,
19 * dump and destroy on graph and node operations such as clone,
20 * edge update, and edge shrink, etc. The API also allows to create the stats
21 * cluster to monitor per graph and per node stats.
28 #include <rte_common.h>
29 #include <rte_compat.h>
35 #define RTE_GRAPH_NAMESIZE 64 /**< Max length of graph name. */
36 #define RTE_NODE_NAMESIZE 64 /**< Max length of node name. */
37 #define RTE_GRAPH_OFF_INVALID UINT32_MAX /**< Invalid graph offset. */
38 #define RTE_NODE_ID_INVALID UINT32_MAX /**< Invalid node id. */
39 #define RTE_EDGE_ID_INVALID UINT16_MAX /**< Invalid edge id. */
40 #define RTE_GRAPH_ID_INVALID UINT16_MAX /**< Invalid graph id. */
41 #define RTE_GRAPH_FENCE 0xdeadbeef12345678ULL /**< Graph fence data. */
43 typedef uint32_t rte_graph_off_t; /**< Graph offset type. */
44 typedef uint32_t rte_node_t; /**< Node id type. */
45 typedef uint16_t rte_edge_t; /**< Edge id type. */
46 typedef uint16_t rte_graph_t; /**< Graph id type. */
48 /** Burst size in terms of log2 */
49 #if RTE_GRAPH_BURST_SIZE == 1
50 #define RTE_GRAPH_BURST_SIZE_LOG2 0 /**< Object burst size of 1. */
51 #elif RTE_GRAPH_BURST_SIZE == 2
52 #define RTE_GRAPH_BURST_SIZE_LOG2 1 /**< Object burst size of 2. */
53 #elif RTE_GRAPH_BURST_SIZE == 4
54 #define RTE_GRAPH_BURST_SIZE_LOG2 2 /**< Object burst size of 4. */
55 #elif RTE_GRAPH_BURST_SIZE == 8
56 #define RTE_GRAPH_BURST_SIZE_LOG2 3 /**< Object burst size of 8. */
57 #elif RTE_GRAPH_BURST_SIZE == 16
58 #define RTE_GRAPH_BURST_SIZE_LOG2 4 /**< Object burst size of 16. */
59 #elif RTE_GRAPH_BURST_SIZE == 32
60 #define RTE_GRAPH_BURST_SIZE_LOG2 5 /**< Object burst size of 32. */
61 #elif RTE_GRAPH_BURST_SIZE == 64
62 #define RTE_GRAPH_BURST_SIZE_LOG2 6 /**< Object burst size of 64. */
63 #elif RTE_GRAPH_BURST_SIZE == 128
64 #define RTE_GRAPH_BURST_SIZE_LOG2 7 /**< Object burst size of 128. */
65 #elif RTE_GRAPH_BURST_SIZE == 256
66 #define RTE_GRAPH_BURST_SIZE_LOG2 8 /**< Object burst size of 256. */
68 #error "Unsupported burst size"
71 /* Forward declaration */
72 struct rte_node; /**< Node object */
73 struct rte_graph; /**< Graph object */
74 struct rte_graph_cluster_stats; /**< Stats for Cluster of graphs */
75 struct rte_graph_cluster_node_stats; /**< Node stats within cluster of graphs */
78 * Node process function.
80 * The function invoked when the worker thread walks on nodes using
84 * Pointer to the graph object.
86 * Pointer to the node object.
88 * Pointer to an array of objects to be processed.
90 * Number of objects in the array.
93 * Number of objects processed.
95 * @see rte_graph_walk()
98 typedef uint16_t (*rte_node_process_t)(struct rte_graph *graph,
99 struct rte_node *node, void **objs,
103 * Node initialization function.
105 * The function invoked when the user creates the graph using rte_graph_create()
108 * Pointer to the graph object.
110 * Pointer to the node object.
116 * @see rte_graph_create()
118 typedef int (*rte_node_init_t)(const struct rte_graph *graph,
119 struct rte_node *node);
122 * Node finalization function.
124 * The function invoked when the user destroys the graph using
125 * rte_graph_destroy().
128 * Pointer to the graph object.
130 * Pointer to the node object.
132 * @see rte_graph_destroy()
134 typedef void (*rte_node_fini_t)(const struct rte_graph *graph,
135 struct rte_node *node);
138 * Graph cluster stats callback.
141 * Flag to denote that stats are of the first node.
143 * Flag to denote that stats are of the last node.
145 * Cookie supplied during stats creation.
147 * Node cluster stats data.
153 typedef int (*rte_graph_cluster_stats_cb_t)(bool is_first, bool is_last,
154 void *cookie, const struct rte_graph_cluster_node_stats *stats);
157 * Structure to hold configuration parameters for creating the graph.
159 * @see rte_graph_create()
161 struct rte_graph_param {
162 int socket_id; /**< Socket id where memory is allocated. */
163 uint16_t nb_node_patterns; /**< Number of node patterns. */
164 const char **node_patterns;
165 /**< Array of node patterns based on shell pattern. */
169 * Structure to hold configuration parameters for graph cluster stats create.
171 * @see rte_graph_cluster_stats_create()
173 struct rte_graph_cluster_stats_param {
175 /**< Socket id where memory is allocated */
176 rte_graph_cluster_stats_cb_t fn;
177 /**< Stats print callback function. NULL value allowed, in that case,
178 * default print stat function used.
183 FILE *f; /**< File pointer to dump the stats when fn == NULL. */
185 uint16_t nb_graph_patterns; /**< Number of graph patterns. */
186 const char **graph_patterns;
187 /**< Array of graph patterns based on shell pattern. */
191 * Node cluster stats data structure.
193 * @see struct rte_graph_cluster_stats_param::fn
195 struct rte_graph_cluster_node_stats {
196 uint64_t ts; /**< Current timestamp. */
197 uint64_t calls; /**< Current number of calls made. */
198 uint64_t objs; /**< Current number of objs processed. */
199 uint64_t cycles; /**< Current number of cycles. */
201 uint64_t prev_ts; /**< Previous call timestamp. */
202 uint64_t prev_calls; /**< Previous number of calls. */
203 uint64_t prev_objs; /**< Previous number of processed objs. */
204 uint64_t prev_cycles; /**< Previous number of cycles. */
206 uint64_t realloc_count; /**< Realloc count. */
208 rte_node_t id; /**< Node identifier of stats. */
209 uint64_t hz; /**< Cycles per seconds. */
210 char name[RTE_NODE_NAMESIZE]; /**< Name of the node. */
211 } __rte_cache_aligned;
216 * Create memory reel, detect loops and find isolated nodes.
219 * Unique name for this graph.
221 * Graph parameter, includes node names and count to be included
225 * Unique graph id on success, RTE_GRAPH_ID_INVALID otherwise.
228 rte_graph_t rte_graph_create(const char *name, struct rte_graph_param *prm);
233 * Free Graph memory reel.
236 * id of the graph to destroy.
239 * 0 on success, error otherwise.
242 int rte_graph_destroy(rte_graph_t id);
245 * Get graph id from graph name.
248 * Name of the graph to get id.
251 * Graph id on success, RTE_GRAPH_ID_INVALID otherwise.
254 rte_graph_t rte_graph_from_name(const char *name);
257 * Get graph name from graph id.
260 * id of the graph to get name.
263 * Graph name on success, NULL otherwise.
266 char *rte_graph_id_to_name(rte_graph_t id);
269 * Export the graph as graph viz dot file
272 * Name of the graph to export.
274 * File pointer to export the graph.
277 * 0 on success, error otherwise.
280 int rte_graph_export(const char *name, FILE *f);
283 * Get graph object from its name.
285 * Typical usage of this API to get graph objects in the worker thread and
286 * followed calling rte_graph_walk() in a loop.
292 * Graph pointer on success, NULL otherwise.
294 * @see rte_graph_walk()
297 struct rte_graph *rte_graph_lookup(const char *name);
300 * Get maximum number of graph available.
303 * Maximum graph count.
306 rte_graph_t rte_graph_max_count(void);
309 * Dump the graph information to file.
312 * File pointer to dump graph info.
314 * Graph id to get graph info.
317 void rte_graph_dump(FILE *f, rte_graph_t id);
320 * Dump all graphs information to file
323 * File pointer to dump graph info.
326 void rte_graph_list_dump(FILE *f);
329 * Dump graph information along with node info to file
332 * File pointer to dump graph info.
334 * Graph pointer to get graph info.
336 * true to dump nodes in the graph.
339 void rte_graph_obj_dump(FILE *f, struct rte_graph *graph, bool all);
341 /** Macro to browse rte_node object after the graph creation */
342 #define rte_graph_foreach_node(count, off, graph, node) \
343 for (count = 0, off = graph->nodes_start, \
344 node = RTE_PTR_ADD(graph, off); \
345 count < graph->nb_nodes; \
346 off = node->next, node = RTE_PTR_ADD(graph, off), count++)
349 * Get node object with in graph from id.
352 * Graph id to get node pointer from.
354 * Node id to get node pointer.
357 * Node pointer on success, NULL otherwise.
360 struct rte_node *rte_graph_node_get(rte_graph_t graph_id, rte_node_t node_id);
363 * Get node pointer with in graph from name.
366 * Graph name to get node pointer from.
368 * Node name to get the node pointer.
371 * Node pointer on success, NULL otherwise.
374 struct rte_node *rte_graph_node_get_by_name(const char *graph,
378 * Create graph stats cluster to aggregate runtime node stats.
381 * Parameters including file pointer to dump stats,
382 * Graph pattern to create cluster and callback function.
385 * Valid pointer on success, NULL otherwise.
388 struct rte_graph_cluster_stats *rte_graph_cluster_stats_create(
389 const struct rte_graph_cluster_stats_param *prm);
392 * Destroy cluster stats.
395 * Valid cluster pointer to destroy.
398 void rte_graph_cluster_stats_destroy(struct rte_graph_cluster_stats *stat);
401 * Get stats to application.
406 * true to skip callback function invocation.
409 void rte_graph_cluster_stats_get(struct rte_graph_cluster_stats *stat,
413 * Reset cluster stats to zero.
416 * Valid cluster stats pointer.
419 void rte_graph_cluster_stats_reset(struct rte_graph_cluster_stats *stat);
422 * Structure defines the node registration parameters.
424 * @see __rte_node_register(), RTE_NODE_REGISTER()
426 struct rte_node_register {
427 char name[RTE_NODE_NAMESIZE]; /**< Name of the node. */
428 uint64_t flags; /**< Node configuration flag. */
429 #define RTE_NODE_SOURCE_F (1ULL << 0) /**< Node type is source. */
430 rte_node_process_t process; /**< Node process function. */
431 rte_node_init_t init; /**< Node init function. */
432 rte_node_fini_t fini; /**< Node fini function. */
433 rte_node_t id; /**< Node Identifier. */
434 rte_node_t parent_id; /**< Identifier of parent node. */
435 rte_edge_t nb_edges; /**< Number of edges from this node. */
436 const char *next_nodes[]; /**< Names of next nodes. */
440 * Register new packet processing node. Nodes can be registered
441 * dynamically via this call or statically via the RTE_NODE_REGISTER
445 * Valid node pointer with name, process function and next_nodes.
448 * Valid node id on success, RTE_NODE_ID_INVALID otherwise.
450 * @see RTE_NODE_REGISTER()
453 rte_node_t __rte_node_register(const struct rte_node_register *node);
456 * Register a static node.
458 * The static node is registered through the constructor scheme, thereby, it can
459 * be used in a multi-process scenario.
462 * Valid node pointer with name, process function, and next_nodes.
464 #define RTE_NODE_REGISTER(node) \
465 RTE_INIT(rte_node_register_##node) \
467 node.parent_id = RTE_NODE_ID_INVALID; \
468 node.id = __rte_node_register(&node); \
472 * Clone a node from static node(node created from RTE_NODE_REGISTER).
475 * Static node id to clone from.
477 * Name of the new node. The library prepends the parent node name to the
478 * user-specified name. The final node name will be,
479 * "parent node name" + "-" + name.
482 * Valid node id on success, RTE_NODE_ID_INVALID otherwise.
485 rte_node_t rte_node_clone(rte_node_t id, const char *name);
488 * Get node id from node name.
491 * Valid node name. In the case of the cloned node, the name will be
492 * "parent node name" + "-" + name.
495 * Valid node id on success, RTE_NODE_ID_INVALID otherwise.
498 rte_node_t rte_node_from_name(const char *name);
501 * Get node name from node id.
507 * Valid node name on success, NULL otherwise.
510 char *rte_node_id_to_name(rte_node_t id);
513 * Get the number of edges(next-nodes) for a node from node id.
519 * Valid edge count on success, RTE_EDGE_ID_INVALID otherwise.
522 rte_edge_t rte_node_edge_count(rte_node_t id);
525 * Update the edges for a node from node id.
530 * Index to update the edges from. RTE_EDGE_ID_INVALID is valid,
531 * in that case, it will be added to the end of the list.
533 * Name of the edges to update.
535 * Number of edges to update.
538 * Valid edge count on success, 0 otherwise.
541 rte_edge_t rte_node_edge_update(rte_node_t id, rte_edge_t from,
542 const char **next_nodes, uint16_t nb_edges);
545 * Shrink the edges to a given size.
550 * New size to shrink the edges.
553 * New size on success, RTE_EDGE_ID_INVALID otherwise.
556 rte_edge_t rte_node_edge_shrink(rte_node_t id, rte_edge_t size);
559 * Get the edge names from a given node.
563 * @param[out] next_nodes
564 * Buffer to copy the edge names. The NULL value is allowed in that case,
565 * the function returns the size of the array that needs to be allocated.
568 * When next_nodes == NULL, it returns the size of the array else
569 * number of item copied.
572 rte_node_t rte_node_edge_get(rte_node_t id, char *next_nodes[]);
575 * Get maximum nodes available.
578 * Maximum nodes count.
581 rte_node_t rte_node_max_count(void);
584 * Dump node info to file.
587 * File pointer to dump the node info.
589 * Node id to get the info.
592 void rte_node_dump(FILE *f, rte_node_t id);
595 * Dump all node info to file.
598 * File pointer to dump the node info.
601 void rte_node_list_dump(FILE *f);
604 * Test the validity of node id.
610 * 1 if valid id, 0 otherwise.
612 static __rte_always_inline int
613 rte_node_is_invalid(rte_node_t id)
615 return (id == RTE_NODE_ID_INVALID);
619 * Test the validity of edge id.
622 * Edge node id to check.
625 * 1 if valid id, 0 otherwise.
627 static __rte_always_inline int
628 rte_edge_is_invalid(rte_edge_t id)
630 return (id == RTE_EDGE_ID_INVALID);
634 * Test the validity of graph id.
640 * 1 if valid id, 0 otherwise.
642 static __rte_always_inline int
643 rte_graph_is_invalid(rte_graph_t id)
645 return (id == RTE_GRAPH_ID_INVALID);
649 * Test stats feature support.
652 * 1 if stats enabled, 0 otherwise.
654 static __rte_always_inline int
655 rte_graph_has_stats_feature(void)
657 #ifdef RTE_LIBRTE_GRAPH_STATS
658 return RTE_LIBRTE_GRAPH_STATS;
668 #endif /* _RTE_GRAPH_H_ */