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