1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2020 Marvell International Ltd. 3 */ 4 5 #ifndef _RTE_GRAPH_PRIVATE_H_ 6 #define _RTE_GRAPH_PRIVATE_H_ 7 8 #include <inttypes.h> 9 #include <sys/queue.h> 10 11 #include <rte_common.h> 12 #include <rte_eal.h> 13 #include <rte_spinlock.h> 14 #include <rte_errno.h> 15 #include <rte_string_fns.h> 16 17 #include "rte_graph.h" 18 #include "rte_graph_worker.h" 19 20 extern int rte_graph_logtype; 21 #define RTE_LOGTYPE_GRAPH rte_graph_logtype 22 23 #define GRAPH_LOG(level, ...) \ 24 RTE_LOG_LINE_PREFIX(level, GRAPH, \ 25 "%s():%u ", __func__ RTE_LOG_COMMA __LINE__, __VA_ARGS__) 26 27 #define graph_err(...) GRAPH_LOG(ERR, __VA_ARGS__) 28 #define graph_warn(...) GRAPH_LOG(WARNING, __VA_ARGS__) 29 #define graph_info(...) GRAPH_LOG(INFO, __VA_ARGS__) 30 #define graph_dbg(...) GRAPH_LOG(DEBUG, __VA_ARGS__) 31 32 #define ID_CHECK(id, id_max) \ 33 do { \ 34 if ((id) >= (id_max)) { \ 35 rte_errno = EINVAL; \ 36 goto fail; \ 37 } \ 38 } while (0) 39 40 #define SET_ERR_JMP(err, where, fmt, ...) \ 41 do { \ 42 graph_err(fmt, ##__VA_ARGS__); \ 43 rte_errno = err; \ 44 goto where; \ 45 } while (0) 46 47 /** 48 * @internal 49 * 50 * Structure that holds node internal data. 51 */ 52 struct node { 53 STAILQ_ENTRY(node) next; /**< Next node in the list. */ 54 char name[RTE_NODE_NAMESIZE]; /**< Name of the node. */ 55 uint64_t flags; /**< Node configuration flag. */ 56 unsigned int lcore_id; 57 /**< Node runs on the Lcore ID used for mcore dispatch model. */ 58 rte_node_process_t process; /**< Node process function. */ 59 rte_node_init_t init; /**< Node init function. */ 60 rte_node_fini_t fini; /**< Node fini function. */ 61 rte_node_t id; /**< Allocated identifier for the node. */ 62 rte_node_t parent_id; /**< Parent node identifier. */ 63 rte_edge_t nb_edges; /**< Number of edges from this node. */ 64 struct rte_node_xstats *xstats; /**< Node specific xstats. */ 65 char next_nodes[][RTE_NODE_NAMESIZE]; /**< Names of next nodes. */ 66 }; 67 68 /** 69 * @internal 70 * 71 * Structure that holds the graph scheduling workqueue node stream. 72 * Used for mcore dispatch model. 73 */ 74 struct __rte_cache_aligned graph_mcore_dispatch_wq_node { 75 rte_graph_off_t node_off; 76 uint16_t nb_objs; 77 void *objs[RTE_GRAPH_BURST_SIZE]; 78 }; 79 80 /** 81 * @internal 82 * 83 * Structure that holds the graph node data. 84 */ 85 struct graph_node { 86 STAILQ_ENTRY(graph_node) next; /**< Next graph node in the list. */ 87 struct node *node; /**< Pointer to internal node. */ 88 bool visited; /**< Flag used in BFS to mark node visited. */ 89 struct graph_node *adjacency_list[]; /**< Adjacency list of the node. */ 90 }; 91 92 /** 93 * @internal 94 * 95 * Structure that holds graph internal data. 96 */ 97 struct graph { 98 STAILQ_ENTRY(graph) next; 99 /**< List of graphs. */ 100 char name[RTE_GRAPH_NAMESIZE]; 101 /**< Name of the graph. */ 102 const struct rte_memzone *mz; 103 /**< Memzone to store graph data. */ 104 rte_graph_off_t nodes_start; 105 /**< Node memory start offset in graph reel. */ 106 rte_graph_off_t xstats_start; 107 /**< Node xstats memory start offset in graph reel. */ 108 rte_node_t src_node_count; 109 /**< Number of source nodes in a graph. */ 110 struct rte_graph *graph; 111 /**< Pointer to graph data. */ 112 rte_node_t node_count; 113 /**< Total number of nodes. */ 114 uint32_t cir_start; 115 /**< Circular buffer start offset in graph reel. */ 116 uint32_t cir_mask; 117 /**< Circular buffer mask for wrap around. */ 118 rte_graph_t id; 119 /**< Graph identifier. */ 120 rte_graph_t parent_id; 121 /**< Parent graph identifier. */ 122 unsigned int lcore_id; 123 /**< Lcore identifier where the graph prefer to run on. Used for mcore dispatch model. */ 124 size_t mem_sz; 125 /**< Memory size of the graph. */ 126 int socket; 127 /**< Socket identifier where memory is allocated. */ 128 uint64_t num_pkt_to_capture; 129 /**< Number of packets to be captured per core. */ 130 char pcap_filename[RTE_GRAPH_PCAP_FILE_SZ]; 131 /**< pcap file name/path. */ 132 STAILQ_HEAD(gnode_list, graph_node) node_list; 133 /**< Nodes in a graph. */ 134 }; 135 136 /* Node and graph common functions */ 137 /** 138 * @internal 139 * 140 * Naming a cloned graph or node by appending a string to base name. 141 * 142 * @param new_name 143 * Pointer to the name of the cloned object. 144 * @param base_name 145 * Pointer to the name of original object. 146 * @param append_str 147 * Pointer to the appended string. 148 * 149 * @return 150 * 0 on success, negative errno value otherwise. 151 */ 152 static inline int clone_name(char *new_name, char *base_name, const char *append_str) 153 { 154 ssize_t sz, rc; 155 156 #define SZ RTE_MIN(RTE_NODE_NAMESIZE, RTE_GRAPH_NAMESIZE) 157 rc = rte_strscpy(new_name, base_name, SZ); 158 if (rc < 0) 159 goto fail; 160 sz = rc; 161 rc = rte_strscpy(new_name + sz, "-", RTE_MAX((int16_t)(SZ - sz), 0)); 162 if (rc < 0) 163 goto fail; 164 sz += rc; 165 sz = rte_strscpy(new_name + sz, append_str, RTE_MAX((int16_t)(SZ - sz), 0)); 166 if (sz < 0) 167 goto fail; 168 169 return 0; 170 fail: 171 rte_errno = E2BIG; 172 return -rte_errno; 173 } 174 175 /* Node functions */ 176 STAILQ_HEAD(node_head, node); 177 178 /** 179 * @internal 180 * 181 * Get the head of the node list. 182 * 183 * @return 184 * Pointer to the node head. 185 */ 186 struct node_head *node_list_head_get(void); 187 188 /** 189 * @internal 190 * 191 * Get node pointer from node name. 192 * 193 * @param name 194 * Pointer to character string containing the node name. 195 * 196 * @return 197 * Pointer to the node. 198 */ 199 struct node *node_from_name(const char *name); 200 201 /* Graph list functions */ 202 STAILQ_HEAD(graph_head, graph); 203 204 /** 205 * @internal 206 * 207 * Get the head of the graph list. 208 * 209 * @return 210 * Pointer to the graph head. 211 */ 212 struct graph_head *graph_list_head_get(void); 213 214 rte_spinlock_t * 215 graph_spinlock_get(void); 216 217 /* Lock functions */ 218 /** 219 * @internal 220 * 221 * Take a lock on the graph internal spin lock. 222 */ 223 void graph_spinlock_lock(void) 224 __rte_exclusive_lock_function(graph_spinlock_get()); 225 226 /** 227 * @internal 228 * 229 * Release a lock on the graph internal spin lock. 230 */ 231 void graph_spinlock_unlock(void) 232 __rte_unlock_function(graph_spinlock_get()); 233 234 /* Graph operations */ 235 /** 236 * @internal 237 * 238 * Run a BFS(Breadth First Search) on the graph marking all 239 * the graph nodes as visited. 240 * 241 * @param graph 242 * Pointer to the internal graph object. 243 * @param start 244 * Pointer to the starting graph node. 245 * 246 * @return 247 * - 0: Success. 248 * - -ENOMEM: Not enough memory for BFS. 249 */ 250 int graph_bfs(struct graph *graph, struct graph_node *start); 251 252 /** 253 * @internal 254 * 255 * Check if there is an isolated node in the given graph. 256 * 257 * @param graph 258 * Pointer to the internal graph object. 259 * 260 * @return 261 * - 0: No isolated node found. 262 * - 1: Isolated node found. 263 */ 264 int graph_has_isolated_node(struct graph *graph); 265 266 /** 267 * @internal 268 * 269 * Check whether a node in the graph has next_node to a source node. 270 * 271 * @param graph 272 * Pointer to the internal graph object. 273 * 274 * @return 275 * - 0: Node has an edge to source node. 276 * - 1: Node doesn't have an edge to source node. 277 */ 278 int graph_node_has_edge_to_src_node(struct graph *graph); 279 280 /** 281 * @internal 282 * 283 * Checks whether node in the graph has a edge to itself i.e. forms a 284 * loop. 285 * 286 * @param graph 287 * Pointer to the internal graph object. 288 * 289 * @return 290 * - 0: Node has an edge to itself. 291 * - 1: Node doesn't have an edge to itself. 292 */ 293 int graph_node_has_loop_edge(struct graph *graph); 294 295 /** 296 * @internal 297 * 298 * Get the count of source nodes in the graph. 299 * 300 * @param graph 301 * Pointer to the internal graph object. 302 * 303 * @return 304 * Number of source nodes. 305 */ 306 rte_node_t graph_src_nodes_count(struct graph *graph); 307 308 /** 309 * @internal 310 * 311 * Get the count of total number of nodes in the graph. 312 * 313 * @param graph 314 * Pointer to the internal graph object. 315 * 316 * @return 317 * Number of nodes. 318 */ 319 rte_node_t graph_nodes_count(struct graph *graph); 320 321 /** 322 * @internal 323 * 324 * Clear the visited flag of all the nodes in the graph. 325 * 326 * @param graph 327 * Pointer to the internal graph object. 328 */ 329 void graph_mark_nodes_as_not_visited(struct graph *graph); 330 331 /* Fast path graph memory populate unctions */ 332 333 /** 334 * @internal 335 * 336 * Create fast-path memory for the graph and nodes. 337 * 338 * @param graph 339 * Pointer to the internal graph object. 340 * 341 * @return 342 * - 0: Success. 343 * - -ENOMEM: Not enough for graph and nodes. 344 * - -EINVAL: Graph nodes not found. 345 */ 346 int graph_fp_mem_create(struct graph *graph); 347 348 /** 349 * @internal 350 * 351 * Free fast-path memory used by graph and nodes. 352 * 353 * @param graph 354 * Pointer to the internal graph object. 355 * 356 * @return 357 * - 0: Success. 358 * - <0: Graph memzone related error. 359 */ 360 int graph_fp_mem_destroy(struct graph *graph); 361 362 /* Lookup functions */ 363 /** 364 * @internal 365 * 366 * Get graph node object from node id. 367 * 368 * @param graph 369 * Pointer to rte_graph object. 370 * @param id 371 * Node Identifier. 372 * 373 * @return 374 * Pointer to rte_node if identifier is valid else NULL. 375 */ 376 struct rte_node *graph_node_id_to_ptr(const struct rte_graph *graph, 377 rte_node_t id); 378 379 /** 380 * @internal 381 * 382 * Get graph node object from node name. 383 * 384 * @param graph 385 * Pointer to rte_graph object. 386 * @param node_name 387 * Pointer to character string holding the node name. 388 * 389 * @return 390 * Pointer to rte_node if identifier is valid else NULL. 391 */ 392 struct rte_node *graph_node_name_to_ptr(const struct rte_graph *graph, 393 const char *node_name); 394 395 /* Debug functions */ 396 /** 397 * @internal 398 * 399 * Dump internal graph object data. 400 * 401 * @param f 402 * FILE pointer to dump the data. 403 * @param g 404 * Pointer to the internal graph object. 405 */ 406 void graph_dump(FILE *f, struct graph *g); 407 408 /** 409 * @internal 410 * 411 * Dump internal node object data. 412 * 413 * @param f 414 * FILE pointer to dump the info. 415 * @param g 416 * Pointer to the internal node object. 417 */ 418 void node_dump(FILE *f, struct node *n); 419 420 /** 421 * @internal 422 * 423 * Create the graph schedule work queue for mcore dispatch model. 424 * All cloned graphs attached to the parent graph MUST be destroyed together 425 * for fast schedule design limitation. 426 * 427 * @param _graph 428 * The graph object 429 * @param _parent_graph 430 * The parent graph object which holds the run-queue head. 431 * @param prm 432 * Graph parameter, includes model-specific parameters in this graph. 433 * 434 * @return 435 * - 0: Success. 436 * - <0: Graph schedule work queue related error. 437 */ 438 int graph_sched_wq_create(struct graph *_graph, struct graph *_parent_graph, 439 struct rte_graph_param *prm); 440 441 /** 442 * @internal 443 * 444 * Destroy the graph schedule work queue for mcore dispatch model. 445 * 446 * @param _graph 447 * The graph object 448 */ 449 void graph_sched_wq_destroy(struct graph *_graph); 450 451 #endif /* _RTE_GRAPH_PRIVATE_H_ */ 452