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