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