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 #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_PCAP_FILE_SZ 64 /**< Max length of pcap file 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 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 bool pcap_enable; /**< Pcap enable. */ 168 uint64_t num_pkt_to_capture; /**< Number of packets to capture. */ 169 char *pcap_filename; /**< Filename in which packets to be captured.*/ 170 171 RTE_STD_C11 172 union { 173 struct { 174 uint64_t rsvd; /**< Reserved for rtc model. */ 175 } rtc; 176 struct { 177 uint32_t wq_size_max; /**< Maximum size of workqueue for dispatch model. */ 178 uint32_t mp_capacity; /**< Capacity of memory pool for dispatch model. */ 179 } dispatch; 180 }; 181 }; 182 183 /** 184 * Structure to hold configuration parameters for graph cluster stats create. 185 * 186 * @see rte_graph_cluster_stats_create() 187 */ 188 struct rte_graph_cluster_stats_param { 189 int socket_id; 190 /**< Socket id where memory is allocated */ 191 rte_graph_cluster_stats_cb_t fn; 192 /**< Stats print callback function. NULL value allowed, in that case, 193 * default print stat function used. 194 */ 195 RTE_STD_C11 196 union { 197 void *cookie; 198 FILE *f; /**< File pointer to dump the stats when fn == NULL. */ 199 }; 200 uint16_t nb_graph_patterns; /**< Number of graph patterns. */ 201 const char **graph_patterns; 202 /**< Array of graph patterns based on shell pattern. */ 203 }; 204 205 /** 206 * Node cluster stats data structure. 207 * 208 * @see struct rte_graph_cluster_stats_param::fn 209 */ 210 struct rte_graph_cluster_node_stats { 211 uint64_t ts; /**< Current timestamp. */ 212 uint64_t calls; /**< Current number of calls made. */ 213 uint64_t objs; /**< Current number of objs processed. */ 214 uint64_t cycles; /**< Current number of cycles. */ 215 216 uint64_t prev_ts; /**< Previous call timestamp. */ 217 uint64_t prev_calls; /**< Previous number of calls. */ 218 uint64_t prev_objs; /**< Previous number of processed objs. */ 219 uint64_t prev_cycles; /**< Previous number of cycles. */ 220 221 RTE_STD_C11 222 union { 223 struct { 224 uint64_t sched_objs; 225 /**< Previous number of scheduled objs for dispatch model. */ 226 uint64_t sched_fail; 227 /**< Previous number of failed schedule objs for dispatch model. */ 228 } dispatch; 229 }; 230 231 uint64_t realloc_count; /**< Realloc count. */ 232 233 rte_node_t id; /**< Node identifier of stats. */ 234 uint64_t hz; /**< Cycles per seconds. */ 235 char name[RTE_NODE_NAMESIZE]; /**< Name of the node. */ 236 } __rte_cache_aligned; 237 238 /** 239 * Create Graph. 240 * 241 * Create memory reel, detect loops and find isolated nodes. 242 * 243 * @param name 244 * Unique name for this graph. 245 * @param prm 246 * Graph parameter, includes node names and count to be included 247 * in this graph. 248 * 249 * @return 250 * Unique graph id on success, RTE_GRAPH_ID_INVALID otherwise. 251 */ 252 __rte_experimental 253 rte_graph_t rte_graph_create(const char *name, struct rte_graph_param *prm); 254 255 /** 256 * Destroy Graph. 257 * 258 * Free Graph memory reel. 259 * 260 * @param id 261 * id of the graph to destroy. 262 * 263 * @return 264 * 0 on success, error otherwise. 265 */ 266 __rte_experimental 267 int rte_graph_destroy(rte_graph_t id); 268 269 /** 270 * Clone Graph. 271 * 272 * Clone a graph from static graph (graph created from rte_graph_create()). And 273 * all cloned graphs attached to the parent graph MUST be destroyed together 274 * for fast schedule design limitation (stop ALL graph walk firstly). 275 * 276 * @param id 277 * Static graph id to clone from. 278 * @param name 279 * Name of the new graph. The library prepends the parent graph name to the 280 * user-specified name. The final graph name will be, 281 * "parent graph name" + "-" + name. 282 * @param prm 283 * Graph parameter, includes model-specific parameters in this graph. 284 * 285 * @return 286 * Valid graph id on success, RTE_GRAPH_ID_INVALID otherwise. 287 */ 288 __rte_experimental 289 rte_graph_t rte_graph_clone(rte_graph_t id, const char *name, struct rte_graph_param *prm); 290 291 /** 292 * Get graph id from graph name. 293 * 294 * @param name 295 * Name of the graph to get id. 296 * 297 * @return 298 * Graph id on success, RTE_GRAPH_ID_INVALID otherwise. 299 */ 300 __rte_experimental 301 rte_graph_t rte_graph_from_name(const char *name); 302 303 /** 304 * Get graph name from graph id. 305 * 306 * @param id 307 * id of the graph to get name. 308 * 309 * @return 310 * Graph name on success, NULL otherwise. 311 */ 312 __rte_experimental 313 char *rte_graph_id_to_name(rte_graph_t id); 314 315 /** 316 * Export the graph as graph viz dot file 317 * 318 * @param name 319 * Name of the graph to export. 320 * @param f 321 * File pointer to export the graph. 322 * 323 * @return 324 * 0 on success, error otherwise. 325 */ 326 __rte_experimental 327 int rte_graph_export(const char *name, FILE *f); 328 329 /** 330 * Bind graph with specific lcore for mcore dispatch model. 331 * 332 * @param id 333 * Graph id to get the pointer of graph object 334 * @param lcore 335 * The lcore where the graph will run on 336 * @return 337 * 0 on success, error otherwise. 338 */ 339 __rte_experimental 340 int rte_graph_model_mcore_dispatch_core_bind(rte_graph_t id, int lcore); 341 342 /** 343 * Unbind graph with lcore for mcore dispatch model 344 * 345 * @param id 346 * Graph id to get the pointer of graph object 347 */ 348 __rte_experimental 349 void rte_graph_model_mcore_dispatch_core_unbind(rte_graph_t id); 350 351 /** 352 * Get graph object from its name. 353 * 354 * Typical usage of this API to get graph objects in the worker thread and 355 * followed calling rte_graph_walk() in a loop. 356 * 357 * @param name 358 * Name of the graph. 359 * 360 * @return 361 * Graph pointer on success, NULL otherwise. 362 * 363 * @see rte_graph_walk() 364 */ 365 __rte_experimental 366 struct rte_graph *rte_graph_lookup(const char *name); 367 368 /** 369 * Get maximum number of graph available. 370 * 371 * @return 372 * Maximum graph count. 373 */ 374 __rte_experimental 375 rte_graph_t rte_graph_max_count(void); 376 377 /** 378 * Dump the graph information to file. 379 * 380 * @param f 381 * File pointer to dump graph info. 382 * @param id 383 * Graph id to get graph info. 384 */ 385 __rte_experimental 386 void rte_graph_dump(FILE *f, rte_graph_t id); 387 388 /** 389 * Dump all graphs information to file 390 * 391 * @param f 392 * File pointer to dump graph info. 393 */ 394 __rte_experimental 395 void rte_graph_list_dump(FILE *f); 396 397 /** 398 * Dump graph information along with node info to file 399 * 400 * @param f 401 * File pointer to dump graph info. 402 * @param graph 403 * Graph pointer to get graph info. 404 * @param all 405 * true to dump nodes in the graph. 406 */ 407 __rte_experimental 408 void rte_graph_obj_dump(FILE *f, struct rte_graph *graph, bool all); 409 410 /** Macro to browse rte_node object after the graph creation */ 411 #define rte_graph_foreach_node(count, off, graph, node) \ 412 for (count = 0, off = graph->nodes_start, \ 413 node = RTE_PTR_ADD(graph, off); \ 414 count < graph->nb_nodes; \ 415 off = node->next, node = RTE_PTR_ADD(graph, off), count++) 416 417 /** 418 * Get node object with in graph from id. 419 * 420 * @param graph_id 421 * Graph id to get node pointer from. 422 * @param node_id 423 * Node id to get node pointer. 424 * 425 * @return 426 * Node pointer on success, NULL otherwise. 427 */ 428 __rte_experimental 429 struct rte_node *rte_graph_node_get(rte_graph_t graph_id, rte_node_t node_id); 430 431 /** 432 * Get node pointer with in graph from name. 433 * 434 * @param graph 435 * Graph name to get node pointer from. 436 * @param name 437 * Node name to get the node pointer. 438 * 439 * @return 440 * Node pointer on success, NULL otherwise. 441 */ 442 __rte_experimental 443 struct rte_node *rte_graph_node_get_by_name(const char *graph, 444 const char *name); 445 446 /** 447 * Create graph stats cluster to aggregate runtime node stats. 448 * 449 * @param prm 450 * Parameters including file pointer to dump stats, 451 * Graph pattern to create cluster and callback function. 452 * 453 * @return 454 * Valid pointer on success, NULL otherwise. 455 */ 456 __rte_experimental 457 struct rte_graph_cluster_stats *rte_graph_cluster_stats_create( 458 const struct rte_graph_cluster_stats_param *prm); 459 460 /** 461 * Destroy cluster stats. 462 * 463 * @param stat 464 * Valid cluster pointer to destroy. 465 */ 466 __rte_experimental 467 void rte_graph_cluster_stats_destroy(struct rte_graph_cluster_stats *stat); 468 469 /** 470 * Get stats to application. 471 * 472 * @param[out] stat 473 * Cluster status. 474 * @param skip_cb 475 * true to skip callback function invocation. 476 */ 477 __rte_experimental 478 void rte_graph_cluster_stats_get(struct rte_graph_cluster_stats *stat, 479 bool skip_cb); 480 481 /** 482 * Reset cluster stats to zero. 483 * 484 * @param stat 485 * Valid cluster stats pointer. 486 */ 487 __rte_experimental 488 void rte_graph_cluster_stats_reset(struct rte_graph_cluster_stats *stat); 489 490 /** 491 * Structure defines the node registration parameters. 492 * 493 * @see __rte_node_register(), RTE_NODE_REGISTER() 494 */ 495 struct rte_node_register { 496 char name[RTE_NODE_NAMESIZE]; /**< Name of the node. */ 497 uint64_t flags; /**< Node configuration flag. */ 498 #define RTE_NODE_SOURCE_F (1ULL << 0) /**< Node type is source. */ 499 rte_node_process_t process; /**< Node process function. */ 500 rte_node_init_t init; /**< Node init function. */ 501 rte_node_fini_t fini; /**< Node fini function. */ 502 rte_node_t id; /**< Node Identifier. */ 503 rte_node_t parent_id; /**< Identifier of parent node. */ 504 rte_edge_t nb_edges; /**< Number of edges from this node. */ 505 const char *next_nodes[]; /**< Names of next nodes. */ 506 }; 507 508 /** 509 * Register new packet processing node. Nodes can be registered 510 * dynamically via this call or statically via the RTE_NODE_REGISTER 511 * macro. 512 * 513 * @param node 514 * Valid node pointer with name, process function and next_nodes. 515 * 516 * @return 517 * Valid node id on success, RTE_NODE_ID_INVALID otherwise. 518 * 519 * @see RTE_NODE_REGISTER() 520 */ 521 __rte_experimental 522 rte_node_t __rte_node_register(const struct rte_node_register *node); 523 524 /** 525 * Register a static node. 526 * 527 * The static node is registered through the constructor scheme, thereby, it can 528 * be used in a multi-process scenario. 529 * 530 * @param node 531 * Valid node pointer with name, process function, and next_nodes. 532 */ 533 #define RTE_NODE_REGISTER(node) \ 534 RTE_INIT(rte_node_register_##node) \ 535 { \ 536 node.parent_id = RTE_NODE_ID_INVALID; \ 537 node.id = __rte_node_register(&node); \ 538 } 539 540 /** 541 * Clone a node from static node(node created from RTE_NODE_REGISTER). 542 * 543 * @param id 544 * Static node id to clone from. 545 * @param name 546 * Name of the new node. The library prepends the parent node name to the 547 * user-specified name. The final node name will be, 548 * "parent node name" + "-" + name. 549 * 550 * @return 551 * Valid node id on success, RTE_NODE_ID_INVALID otherwise. 552 */ 553 __rte_experimental 554 rte_node_t rte_node_clone(rte_node_t id, const char *name); 555 556 /** 557 * Get node id from node name. 558 * 559 * @param name 560 * Valid node name. In the case of the cloned node, the name will be 561 * "parent node name" + "-" + name. 562 * 563 * @return 564 * Valid node id on success, RTE_NODE_ID_INVALID otherwise. 565 */ 566 __rte_experimental 567 rte_node_t rte_node_from_name(const char *name); 568 569 /** 570 * Get node name from node id. 571 * 572 * @param id 573 * Valid node id. 574 * 575 * @return 576 * Valid node name on success, NULL otherwise. 577 */ 578 __rte_experimental 579 char *rte_node_id_to_name(rte_node_t id); 580 581 /** 582 * Get the number of edges(next-nodes) for a node from node id. 583 * 584 * @param id 585 * Valid node id. 586 * 587 * @return 588 * Valid edge count on success, RTE_EDGE_ID_INVALID otherwise. 589 */ 590 __rte_experimental 591 rte_edge_t rte_node_edge_count(rte_node_t id); 592 593 /** 594 * Update the edges for a node from node id. 595 * 596 * @param id 597 * Valid node id. 598 * @param from 599 * Index to update the edges from. RTE_EDGE_ID_INVALID is valid, 600 * in that case, it will be added to the end of the list. 601 * @param next_nodes 602 * Name of the edges to update. 603 * @param nb_edges 604 * Number of edges to update. 605 * 606 * @return 607 * Valid edge count on success, 0 otherwise. 608 */ 609 __rte_experimental 610 rte_edge_t rte_node_edge_update(rte_node_t id, rte_edge_t from, 611 const char **next_nodes, uint16_t nb_edges); 612 613 /** 614 * Shrink the edges to a given size. 615 * 616 * @param id 617 * Valid node id. 618 * @param size 619 * New size to shrink the edges. 620 * 621 * @return 622 * New size on success, RTE_EDGE_ID_INVALID otherwise. 623 */ 624 __rte_experimental 625 rte_edge_t rte_node_edge_shrink(rte_node_t id, rte_edge_t size); 626 627 /** 628 * Get the edge names from a given node. 629 * 630 * @param id 631 * Valid node id. 632 * @param[out] next_nodes 633 * Buffer to copy the edge names. The NULL value is allowed in that case, 634 * the function returns the size of the array that needs to be allocated. 635 * 636 * @return 637 * When next_nodes == NULL, it returns the size of the array else 638 * number of item copied. 639 */ 640 __rte_experimental 641 rte_node_t rte_node_edge_get(rte_node_t id, char *next_nodes[]); 642 643 /** 644 * Get maximum nodes available. 645 * 646 * @return 647 * Maximum nodes count. 648 */ 649 __rte_experimental 650 rte_node_t rte_node_max_count(void); 651 652 /** 653 * Dump node info to file. 654 * 655 * @param f 656 * File pointer to dump the node info. 657 * @param id 658 * Node id to get the info. 659 */ 660 __rte_experimental 661 void rte_node_dump(FILE *f, rte_node_t id); 662 663 /** 664 * Dump all node info to file. 665 * 666 * @param f 667 * File pointer to dump the node info. 668 */ 669 __rte_experimental 670 void rte_node_list_dump(FILE *f); 671 672 /** 673 * Test the validity of node id. 674 * 675 * @param id 676 * Node id to check. 677 * 678 * @return 679 * 1 if valid id, 0 otherwise. 680 */ 681 static __rte_always_inline int 682 rte_node_is_invalid(rte_node_t id) 683 { 684 return (id == RTE_NODE_ID_INVALID); 685 } 686 687 /** 688 * Test the validity of edge id. 689 * 690 * @param id 691 * Edge node id to check. 692 * 693 * @return 694 * 1 if valid id, 0 otherwise. 695 */ 696 static __rte_always_inline int 697 rte_edge_is_invalid(rte_edge_t id) 698 { 699 return (id == RTE_EDGE_ID_INVALID); 700 } 701 702 /** 703 * Test the validity of graph id. 704 * 705 * @param id 706 * Graph id to check. 707 * 708 * @return 709 * 1 if valid id, 0 otherwise. 710 */ 711 static __rte_always_inline int 712 rte_graph_is_invalid(rte_graph_t id) 713 { 714 return (id == RTE_GRAPH_ID_INVALID); 715 } 716 717 /** 718 * Test stats feature support. 719 * 720 * @return 721 * 1 if stats enabled, 0 otherwise. 722 */ 723 static __rte_always_inline int 724 rte_graph_has_stats_feature(void) 725 { 726 #ifdef RTE_LIBRTE_GRAPH_STATS 727 return RTE_LIBRTE_GRAPH_STATS; 728 #else 729 return 0; 730 #endif 731 } 732 733 #ifdef __cplusplus 734 } 735 #endif 736 737 #endif /* _RTE_GRAPH_H_ */ 738