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