xref: /dpdk/lib/graph/graph_populate.c (revision 33584c19ddc20468ba19e209c88fd5b342e9e8e5)
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