xref: /dpdk/lib/graph/graph_populate.c (revision 455a771fd6f1a9cb6edc8711ff278ad31709cf7c)
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 		node->dispatch.lcore_id = graph_node->node->lcore_id;
93 		nb_edges = graph_node->node->nb_edges;
94 		node->nb_edges = nb_edges;
95 		off += sizeof(struct rte_node);
96 		/* Copy the name in first pass to replace with rte_node* later*/
97 		for (count = 0; count < nb_edges; count++)
98 			node->nodes[count] = (struct rte_node *)&graph_node
99 						     ->adjacency_list[count]
100 						     ->node->name[0];
101 
102 		off += sizeof(struct rte_node *) * nb_edges;
103 		off = RTE_ALIGN(off, RTE_CACHE_LINE_SIZE);
104 		node->next = off;
105 		__rte_node_stream_alloc(graph, node);
106 	}
107 }
108 
109 struct rte_node *
110 graph_node_id_to_ptr(const struct rte_graph *graph, rte_node_t id)
111 {
112 	rte_node_t count;
113 	rte_graph_off_t off;
114 	struct rte_node *node;
115 
116 	rte_graph_foreach_node(count, off, graph, node)
117 		if (unlikely(node->id == id))
118 			return node;
119 
120 	return NULL;
121 }
122 
123 struct rte_node *
124 graph_node_name_to_ptr(const struct rte_graph *graph, const char *name)
125 {
126 	rte_node_t count;
127 	rte_graph_off_t off;
128 	struct rte_node *node;
129 
130 	rte_graph_foreach_node(count, off, graph, node)
131 		if (strncmp(name, node->name, RTE_NODE_NAMESIZE) == 0)
132 			return node;
133 
134 	return NULL;
135 }
136 
137 static int
138 graph_node_nexts_populate(struct graph *_graph)
139 {
140 	rte_node_t count, val;
141 	rte_graph_off_t off;
142 	struct rte_node *node;
143 	const struct rte_graph *graph = _graph->graph;
144 	const char *name;
145 
146 	rte_graph_foreach_node(count, off, graph, node) {
147 		for (val = 0; val < node->nb_edges; val++) {
148 			name = (const char *)node->nodes[val];
149 			node->nodes[val] = graph_node_name_to_ptr(graph, name);
150 			if (node->nodes[val] == NULL)
151 				SET_ERR_JMP(EINVAL, fail, "%s not found", name);
152 		}
153 	}
154 
155 	return 0;
156 fail:
157 	return -rte_errno;
158 }
159 
160 static int
161 graph_src_nodes_populate(struct graph *_graph)
162 {
163 	struct rte_graph *graph = _graph->graph;
164 	struct graph_node *graph_node;
165 	struct rte_node *node;
166 	int32_t head = -1;
167 	const char *name;
168 
169 	STAILQ_FOREACH(graph_node, &_graph->node_list, next) {
170 		if (graph_node->node->flags & RTE_NODE_SOURCE_F) {
171 			name = graph_node->node->name;
172 			node = graph_node_name_to_ptr(graph, name);
173 			if (node == NULL)
174 				SET_ERR_JMP(EINVAL, fail, "%s not found", name);
175 
176 			__rte_node_stream_alloc(graph, node);
177 			graph->cir_start[head--] = node->off;
178 		}
179 	}
180 
181 	return 0;
182 fail:
183 	return -rte_errno;
184 }
185 
186 static int
187 graph_fp_mem_populate(struct graph *graph)
188 {
189 	int rc;
190 
191 	graph_header_popluate(graph);
192 	if (graph_pcap_is_enable())
193 		graph_pcap_init(graph);
194 	graph_nodes_populate(graph);
195 	rc = graph_node_nexts_populate(graph);
196 	rc |= graph_src_nodes_populate(graph);
197 
198 	return rc;
199 }
200 
201 int
202 graph_fp_mem_create(struct graph *graph)
203 {
204 	const struct rte_memzone *mz;
205 	size_t sz;
206 
207 	sz = graph_fp_mem_calc_size(graph);
208 	mz = rte_memzone_reserve(graph->name, sz, graph->socket, 0);
209 	if (mz == NULL)
210 		SET_ERR_JMP(ENOMEM, fail, "Memzone %s reserve failed",
211 			    graph->name);
212 
213 	graph->graph = mz->addr;
214 	graph->mz = mz;
215 
216 	return graph_fp_mem_populate(graph);
217 fail:
218 	return -rte_errno;
219 }
220 
221 static void
222 graph_nodes_mem_destroy(struct rte_graph *graph)
223 {
224 	rte_node_t count;
225 	rte_graph_off_t off;
226 	struct rte_node *node;
227 
228 	if (graph == NULL)
229 		return;
230 
231 	rte_graph_foreach_node(count, off, graph, node)
232 		rte_free(node->objs);
233 }
234 
235 int
236 graph_fp_mem_destroy(struct graph *graph)
237 {
238 	if (graph_pcap_is_enable())
239 		graph_pcap_exit(graph->graph);
240 
241 	graph_nodes_mem_destroy(graph->graph);
242 	return rte_memzone_free(graph->mz);
243 }
244