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