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