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