test/mem: disable ASan when accessing unallocated memory
[dpdk.git] / lib / graph / graph_populate.c
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 }