1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2020 Marvell International Ltd. 3 */ 4 5 6 #include <rte_common.h> 7 #include <rte_errno.h> 8 #include <rte_malloc.h> 9 #include <rte_memzone.h> 10 11 #include "graph_private.h" 12 13 static size_t 14 graph_fp_mem_calc_size(struct graph *graph) 15 { 16 struct graph_node *graph_node; 17 rte_node_t val; 18 size_t sz; 19 20 /* Graph header */ 21 sz = sizeof(struct rte_graph); 22 /* Source nodes list */ 23 sz += sizeof(rte_graph_off_t) * graph->src_node_count; 24 /* Circular buffer for pending streams of size number of nodes */ 25 val = rte_align32pow2(graph->node_count * sizeof(rte_graph_off_t)); 26 sz = RTE_ALIGN(sz, val); 27 graph->cir_start = sz; 28 graph->cir_mask = rte_align32pow2(graph->node_count) - 1; 29 sz += val; 30 /* Fence */ 31 sz += sizeof(RTE_GRAPH_FENCE); 32 sz = RTE_ALIGN(sz, RTE_CACHE_LINE_SIZE); 33 graph->nodes_start = sz; 34 /* For 0..N node objects with fence */ 35 STAILQ_FOREACH(graph_node, &graph->node_list, next) { 36 sz = RTE_ALIGN(sz, RTE_CACHE_LINE_SIZE); 37 sz += sizeof(struct rte_node); 38 /* Pointer to next nodes(edges) */ 39 sz += sizeof(struct rte_node *) * graph_node->node->nb_edges; 40 } 41 42 graph->mem_sz = sz; 43 return sz; 44 } 45 46 static void 47 graph_header_popluate(struct graph *_graph) 48 { 49 struct rte_graph *graph = _graph->graph; 50 51 graph->tail = 0; 52 graph->head = (int32_t)-_graph->src_node_count; 53 graph->cir_mask = _graph->cir_mask; 54 graph->nb_nodes = _graph->node_count; 55 graph->cir_start = RTE_PTR_ADD(graph, _graph->cir_start); 56 graph->nodes_start = _graph->nodes_start; 57 graph->socket = _graph->socket; 58 graph->id = _graph->id; 59 memcpy(graph->name, _graph->name, RTE_GRAPH_NAMESIZE); 60 graph->fence = RTE_GRAPH_FENCE; 61 } 62 63 static void 64 graph_nodes_populate(struct graph *_graph) 65 { 66 rte_graph_off_t off = _graph->nodes_start; 67 struct rte_graph *graph = _graph->graph; 68 struct graph_node *graph_node; 69 rte_edge_t count, nb_edges; 70 const char *parent; 71 rte_node_t pid; 72 73 STAILQ_FOREACH(graph_node, &_graph->node_list, next) { 74 struct rte_node *node = RTE_PTR_ADD(graph, off); 75 memset(node, 0, sizeof(*node)); 76 node->fence = RTE_GRAPH_FENCE; 77 node->off = off; 78 node->process = graph_node->node->process; 79 memcpy(node->name, graph_node->node->name, RTE_GRAPH_NAMESIZE); 80 pid = graph_node->node->parent_id; 81 if (pid != RTE_NODE_ID_INVALID) { /* Cloned node */ 82 parent = rte_node_id_to_name(pid); 83 memcpy(node->parent, parent, RTE_GRAPH_NAMESIZE); 84 } 85 node->id = graph_node->node->id; 86 node->parent_id = pid; 87 nb_edges = graph_node->node->nb_edges; 88 node->nb_edges = nb_edges; 89 off += sizeof(struct rte_node); 90 /* Copy the name in first pass to replace with rte_node* later*/ 91 for (count = 0; count < nb_edges; count++) 92 node->nodes[count] = (struct rte_node *)&graph_node 93 ->adjacency_list[count] 94 ->node->name[0]; 95 96 off += sizeof(struct rte_node *) * nb_edges; 97 off = RTE_ALIGN(off, RTE_CACHE_LINE_SIZE); 98 node->next = off; 99 __rte_node_stream_alloc(graph, node); 100 } 101 } 102 103 struct rte_node * 104 graph_node_id_to_ptr(const struct rte_graph *graph, rte_node_t id) 105 { 106 rte_node_t count; 107 rte_graph_off_t off; 108 struct rte_node *node; 109 110 rte_graph_foreach_node(count, off, graph, node) 111 if (unlikely(node->id == id)) 112 return node; 113 114 return NULL; 115 } 116 117 struct rte_node * 118 graph_node_name_to_ptr(const struct rte_graph *graph, const char *name) 119 { 120 rte_node_t count; 121 rte_graph_off_t off; 122 struct rte_node *node; 123 124 rte_graph_foreach_node(count, off, graph, node) 125 if (strncmp(name, node->name, RTE_NODE_NAMESIZE) == 0) 126 return node; 127 128 return NULL; 129 } 130 131 static int 132 graph_node_nexts_populate(struct graph *_graph) 133 { 134 rte_node_t count, val; 135 rte_graph_off_t off; 136 struct rte_node *node; 137 const struct rte_graph *graph = _graph->graph; 138 const char *name; 139 140 rte_graph_foreach_node(count, off, graph, node) { 141 for (val = 0; val < node->nb_edges; val++) { 142 name = (const char *)node->nodes[val]; 143 node->nodes[val] = graph_node_name_to_ptr(graph, name); 144 if (node->nodes[val] == NULL) 145 SET_ERR_JMP(EINVAL, fail, "%s not found", name); 146 } 147 } 148 149 return 0; 150 fail: 151 return -rte_errno; 152 } 153 154 static int 155 graph_src_nodes_populate(struct graph *_graph) 156 { 157 struct rte_graph *graph = _graph->graph; 158 struct graph_node *graph_node; 159 struct rte_node *node; 160 int32_t head = -1; 161 const char *name; 162 163 STAILQ_FOREACH(graph_node, &_graph->node_list, next) { 164 if (graph_node->node->flags & RTE_NODE_SOURCE_F) { 165 name = graph_node->node->name; 166 node = graph_node_name_to_ptr(graph, name); 167 if (node == NULL) 168 SET_ERR_JMP(EINVAL, fail, "%s not found", name); 169 170 __rte_node_stream_alloc(graph, node); 171 graph->cir_start[head--] = node->off; 172 } 173 } 174 175 return 0; 176 fail: 177 return -rte_errno; 178 } 179 180 static int 181 graph_fp_mem_populate(struct graph *graph) 182 { 183 int rc; 184 185 graph_header_popluate(graph); 186 graph_nodes_populate(graph); 187 rc = graph_node_nexts_populate(graph); 188 rc |= graph_src_nodes_populate(graph); 189 190 return rc; 191 } 192 193 int 194 graph_fp_mem_create(struct graph *graph) 195 { 196 const struct rte_memzone *mz; 197 size_t sz; 198 199 sz = graph_fp_mem_calc_size(graph); 200 mz = rte_memzone_reserve(graph->name, sz, graph->socket, 0); 201 if (mz == NULL) 202 SET_ERR_JMP(ENOMEM, fail, "Memzone %s reserve failed", 203 graph->name); 204 205 graph->graph = mz->addr; 206 graph->mz = mz; 207 208 return graph_fp_mem_populate(graph); 209 fail: 210 return -rte_errno; 211 } 212 213 static void 214 graph_nodes_mem_destroy(struct rte_graph *graph) 215 { 216 rte_node_t count; 217 rte_graph_off_t off; 218 struct rte_node *node; 219 220 if (graph == NULL) 221 return; 222 223 rte_graph_foreach_node(count, off, graph, node) 224 rte_free(node->objs); 225 } 226 227 int 228 graph_fp_mem_destroy(struct graph *graph) 229 { 230 graph_nodes_mem_destroy(graph->graph); 231 return rte_memzone_free(graph->mz); 232 } 233