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