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