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