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