graph: define API
[dpdk.git] / lib / librte_graph / rte_graph.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2020 Marvell International Ltd.
3  */
4
5 #ifndef _RTE_GRAPH_H_
6 #define _RTE_GRAPH_H_
7
8 /**
9  * @file rte_graph.h
10  *
11  * @warning
12  * @b EXPERIMENTAL: this API may change without prior notice
13  *
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.
17  *
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.
22  *
23  */
24
25 #include <stdbool.h>
26 #include <stdio.h>
27
28 #include <rte_common.h>
29 #include <rte_compat.h>
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
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. */
42
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. */
47
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. */
67 #else
68 #error "Unsupported burst size"
69 #endif
70
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 */
76
77 /**
78  * Node process function.
79  *
80  * The function invoked when the worker thread walks on nodes using
81  * rte_graph_walk().
82  *
83  * @param graph
84  *   Pointer to the graph object.
85  * @param node
86  *   Pointer to the node object.
87  * @param objs
88  *   Pointer to an array of objects to be processed.
89  * @param nb_objs
90  *   Number of objects in the array.
91  *
92  * @return
93  *   Number of objects processed.
94  *
95  * @see rte_graph_walk()
96  *
97  */
98 typedef uint16_t (*rte_node_process_t)(struct rte_graph *graph,
99                                        struct rte_node *node, void **objs,
100                                        uint16_t nb_objs);
101
102 /**
103  * Node initialization function.
104  *
105  * The function invoked when the user creates the graph using rte_graph_create()
106  *
107  * @param graph
108  *   Pointer to the graph object.
109  * @param node
110  *   Pointer to the node object.
111  *
112  * @return
113  *   - 0: Success.
114  *   -<0: Failure.
115  *
116  * @see rte_graph_create()
117  */
118 typedef int (*rte_node_init_t)(const struct rte_graph *graph,
119                                struct rte_node *node);
120
121 /**
122  * Node finalization function.
123  *
124  * The function invoked when the user destroys the graph using
125  * rte_graph_destroy().
126  *
127  * @param graph
128  *   Pointer to the graph object.
129  * @param node
130  *   Pointer to the node object.
131  *
132  * @see rte_graph_destroy()
133  */
134 typedef void (*rte_node_fini_t)(const struct rte_graph *graph,
135                                 struct rte_node *node);
136
137 /**
138  * Graph cluster stats callback.
139  *
140  * @param is_first
141  *   Flag to denote that stats are of the first node.
142  * @param is_last
143  *   Flag to denote that stats are of the last node.
144  * @param cookie
145  *   Cookie supplied during stats creation.
146  * @param stats
147  *   Node cluster stats data.
148  *
149  * @return
150  *   - 0: Success.
151  *   -<0: Failure.
152  */
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);
155
156 /**
157  * Structure to hold configuration parameters for creating the graph.
158  *
159  * @see rte_graph_create()
160  */
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. */
166 };
167
168 /**
169  * Structure to hold configuration parameters for graph cluster stats create.
170  *
171  * @see rte_graph_cluster_stats_create()
172  */
173 struct rte_graph_cluster_stats_param {
174         int socket_id;
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.
179          */
180         RTE_STD_C11
181         union {
182                 void *cookie;
183                 FILE *f; /**< File pointer to dump the stats when fn == NULL. */
184         };
185         uint16_t nb_graph_patterns;  /**< Number of graph patterns. */
186         const char **graph_patterns;
187         /**< Array of graph patterns based on shell pattern. */
188 };
189
190 /**
191  * Node cluster stats data structure.
192  *
193  * @see struct rte_graph_cluster_stats_param::fn
194  */
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. */
200
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. */
205
206         uint64_t realloc_count; /**< Realloc count. */
207
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;
212
213 /**
214  * Create Graph.
215  *
216  * Create memory reel, detect loops and find isolated nodes.
217  *
218  * @param name
219  *   Unique name for this graph.
220  * @param prm
221  *   Graph parameter, includes node names and count to be included
222  *   in this graph.
223  *
224  * @return
225  *   Unique graph id on success, RTE_GRAPH_ID_INVALID otherwise.
226  */
227 __rte_experimental
228 rte_graph_t rte_graph_create(const char *name, struct rte_graph_param *prm);
229
230 /**
231  * Destroy Graph.
232  *
233  * Free Graph memory reel.
234  *
235  * @param id
236  *   id of the graph to destroy.
237  *
238  * @return
239  *   0 on success, error otherwise.
240  */
241 __rte_experimental
242 int rte_graph_destroy(rte_graph_t id);
243
244 /**
245  * Get graph id from graph name.
246  *
247  * @param name
248  *   Name of the graph to get id.
249  *
250  * @return
251  *   Graph id on success, RTE_GRAPH_ID_INVALID otherwise.
252  */
253 __rte_experimental
254 rte_graph_t rte_graph_from_name(const char *name);
255
256 /**
257  * Get graph name from graph id.
258  *
259  * @param id
260  *   id of the graph to get name.
261  *
262  * @return
263  *   Graph name on success, NULL otherwise.
264  */
265 __rte_experimental
266 char *rte_graph_id_to_name(rte_graph_t id);
267
268 /**
269  * Export the graph as graph viz dot file
270  *
271  * @param name
272  *   Name of the graph to export.
273  * @param f
274  *   File pointer to export the graph.
275  *
276  * @return
277  *   0 on success, error otherwise.
278  */
279 __rte_experimental
280 int rte_graph_export(const char *name, FILE *f);
281
282 /**
283  * Get graph object from its name.
284  *
285  * Typical usage of this API to get graph objects in the worker thread and
286  * followed calling rte_graph_walk() in a loop.
287  *
288  * @param name
289  *   Name of the graph.
290  *
291  * @return
292  *   Graph pointer on success, NULL otherwise.
293  *
294  * @see rte_graph_walk()
295  */
296 __rte_experimental
297 struct rte_graph *rte_graph_lookup(const char *name);
298
299 /**
300  * Get maximum number of graph available.
301  *
302  * @return
303  *   Maximum graph count.
304  */
305 __rte_experimental
306 rte_graph_t rte_graph_max_count(void);
307
308 /**
309  * Dump the graph information to file.
310  *
311  * @param f
312  *   File pointer to dump graph info.
313  * @param id
314  *   Graph id to get graph info.
315  */
316 __rte_experimental
317 void rte_graph_dump(FILE *f, rte_graph_t id);
318
319 /**
320  * Dump all graphs information to file
321  *
322  * @param f
323  *   File pointer to dump graph info.
324  */
325 __rte_experimental
326 void rte_graph_list_dump(FILE *f);
327
328 /**
329  * Dump graph information along with node info to file
330  *
331  * @param f
332  *   File pointer to dump graph info.
333  * @param graph
334  *   Graph pointer to get graph info.
335  * @param all
336  *   true to dump nodes in the graph.
337  */
338 __rte_experimental
339 void rte_graph_obj_dump(FILE *f, struct rte_graph *graph, bool all);
340
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++)
347
348 /**
349  * Get node object with in graph from id.
350  *
351  * @param graph_id
352  *   Graph id to get node pointer from.
353  * @param node_id
354  *   Node id to get node pointer.
355  *
356  * @return
357  *   Node pointer on success, NULL otherwise.
358  */
359 __rte_experimental
360 struct rte_node *rte_graph_node_get(rte_graph_t graph_id, rte_node_t node_id);
361
362 /**
363  * Get node pointer with in graph from name.
364  *
365  * @param graph
366  *   Graph name to get node pointer from.
367  * @param name
368  *   Node name to get the node pointer.
369  *
370  * @return
371  *   Node pointer on success, NULL otherwise.
372  */
373 __rte_experimental
374 struct rte_node *rte_graph_node_get_by_name(const char *graph,
375                                             const char *name);
376
377 /**
378  * Create graph stats cluster to aggregate runtime node stats.
379  *
380  * @param prm
381  *   Parameters including file pointer to dump stats,
382  *   Graph pattern to create cluster and callback function.
383  *
384  * @return
385  *   Valid pointer on success, NULL otherwise.
386  */
387 __rte_experimental
388 struct rte_graph_cluster_stats *rte_graph_cluster_stats_create(
389                         const struct rte_graph_cluster_stats_param *prm);
390
391 /**
392  * Destroy cluster stats.
393  *
394  * @param stat
395  *    Valid cluster pointer to destroy.
396  */
397 __rte_experimental
398 void rte_graph_cluster_stats_destroy(struct rte_graph_cluster_stats *stat);
399
400 /**
401  * Get stats to application.
402  *
403  * @param[out] stat
404  *   Cluster status.
405  * @param skip_cb
406  *   true to skip callback function invocation.
407  */
408 __rte_experimental
409 void rte_graph_cluster_stats_get(struct rte_graph_cluster_stats *stat,
410                                  bool skip_cb);
411
412 /**
413  * Reset cluster stats to zero.
414  *
415  * @param stat
416  *   Valid cluster stats pointer.
417  */
418 __rte_experimental
419 void rte_graph_cluster_stats_reset(struct rte_graph_cluster_stats *stat);
420
421 /**
422  * Structure defines the node registration parameters.
423  *
424  * @see __rte_node_register(), RTE_NODE_REGISTER()
425  */
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. */
437 };
438
439 /**
440  * Register new packet processing node. Nodes can be registered
441  * dynamically via this call or statically via the RTE_NODE_REGISTER
442  * macro.
443  *
444  * @param node
445  *   Valid node pointer with name, process function and next_nodes.
446  *
447  * @return
448  *   Valid node id on success, RTE_NODE_ID_INVALID otherwise.
449  *
450  * @see RTE_NODE_REGISTER()
451  */
452 __rte_experimental
453 rte_node_t __rte_node_register(const struct rte_node_register *node);
454
455 /**
456  * Register a static node.
457  *
458  * The static node is registered through the constructor scheme, thereby, it can
459  * be used in a multi-process scenario.
460  *
461  * @param node
462  *   Valid node pointer with name, process function, and next_nodes.
463  */
464 #define RTE_NODE_REGISTER(node)                                                \
465         RTE_INIT(rte_node_register_##node)                                     \
466         {                                                                      \
467                 node.parent_id = RTE_NODE_ID_INVALID;                          \
468                 node.id = __rte_node_register(&node);                          \
469         }
470
471 /**
472  * Clone a node from static node(node created from RTE_NODE_REGISTER).
473  *
474  * @param id
475  *   Static node id to clone from.
476  * @param name
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.
480  *
481  * @return
482  *   Valid node id on success, RTE_NODE_ID_INVALID otherwise.
483  */
484 __rte_experimental
485 rte_node_t rte_node_clone(rte_node_t id, const char *name);
486
487 /**
488  * Get node id from node name.
489  *
490  * @param name
491  *   Valid node name. In the case of the cloned node, the name will be
492  * "parent node name" + "-" + name.
493  *
494  * @return
495  *   Valid node id on success, RTE_NODE_ID_INVALID otherwise.
496  */
497 __rte_experimental
498 rte_node_t rte_node_from_name(const char *name);
499
500 /**
501  * Get node name from node id.
502  *
503  * @param id
504  *   Valid node id.
505  *
506  * @return
507  *   Valid node name on success, NULL otherwise.
508  */
509 __rte_experimental
510 char *rte_node_id_to_name(rte_node_t id);
511
512 /**
513  * Get the number of edges(next-nodes) for a node from node id.
514  *
515  * @param id
516  *   Valid node id.
517  *
518  * @return
519  *   Valid edge count on success, RTE_EDGE_ID_INVALID otherwise.
520  */
521 __rte_experimental
522 rte_edge_t rte_node_edge_count(rte_node_t id);
523
524 /**
525  * Update the edges for a node from node id.
526  *
527  * @param id
528  *   Valid node id.
529  * @param from
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.
532  * @param next_nodes
533  *   Name of the edges to update.
534  * @param nb_edges
535  *   Number of edges to update.
536  *
537  * @return
538  *   Valid edge count on success, 0 otherwise.
539  */
540 __rte_experimental
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);
543
544 /**
545  * Shrink the edges to a given size.
546  *
547  * @param id
548  *   Valid node id.
549  * @param size
550  *   New size to shrink the edges.
551  *
552  * @return
553  *   New size on success, RTE_EDGE_ID_INVALID otherwise.
554  */
555 __rte_experimental
556 rte_edge_t rte_node_edge_shrink(rte_node_t id, rte_edge_t size);
557
558 /**
559  * Get the edge names from a given node.
560  *
561  * @param id
562  *   Valid node id.
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.
566  *
567  * @return
568  *   When next_nodes == NULL, it returns the size of the array else
569  *  number of item copied.
570  */
571 __rte_experimental
572 rte_node_t rte_node_edge_get(rte_node_t id, char *next_nodes[]);
573
574 /**
575  * Get maximum nodes available.
576  *
577  * @return
578  *   Maximum nodes count.
579  */
580 __rte_experimental
581 rte_node_t rte_node_max_count(void);
582
583 /**
584  * Dump node info to file.
585  *
586  * @param f
587  *   File pointer to dump the node info.
588  * @param id
589  *   Node id to get the info.
590  */
591 __rte_experimental
592 void rte_node_dump(FILE *f, rte_node_t id);
593
594 /**
595  * Dump all node info to file.
596  *
597  * @param f
598  *   File pointer to dump the node info.
599  */
600 __rte_experimental
601 void rte_node_list_dump(FILE *f);
602
603 /**
604  * Test the validity of node id.
605  *
606  * @param id
607  *   Node id to check.
608  *
609  * @return
610  *   1 if valid id, 0 otherwise.
611  */
612 static __rte_always_inline int
613 rte_node_is_invalid(rte_node_t id)
614 {
615         return (id == RTE_NODE_ID_INVALID);
616 }
617
618 /**
619  * Test the validity of edge id.
620  *
621  * @param id
622  *   Edge node id to check.
623  *
624  * @return
625  *   1 if valid id, 0 otherwise.
626  */
627 static __rte_always_inline int
628 rte_edge_is_invalid(rte_edge_t id)
629 {
630         return (id == RTE_EDGE_ID_INVALID);
631 }
632
633 /**
634  * Test the validity of graph id.
635  *
636  * @param id
637  *   Graph id to check.
638  *
639  * @return
640  *   1 if valid id, 0 otherwise.
641  */
642 static __rte_always_inline int
643 rte_graph_is_invalid(rte_graph_t id)
644 {
645         return (id == RTE_GRAPH_ID_INVALID);
646 }
647
648 /**
649  * Test stats feature support.
650  *
651  * @return
652  *   1 if stats enabled, 0 otherwise.
653  */
654 static __rte_always_inline int
655 rte_graph_has_stats_feature(void)
656 {
657 #ifdef RTE_LIBRTE_GRAPH_STATS
658         return RTE_LIBRTE_GRAPH_STATS;
659 #else
660         return 0;
661 #endif
662 }
663
664 #ifdef __cplusplus
665 }
666 #endif
667
668 #endif /* _RTE_GRAPH_H_ */