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