Branch data Line data Source code
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 : 13 : 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 : 13 : sz += sizeof(rte_graph_off_t) * graph->src_node_count;
25 : : /* Circular buffer for pending streams of size number of nodes */
26 : 13 : val = rte_align32pow2(graph->node_count * sizeof(rte_graph_off_t));
27 : 13 : sz = RTE_ALIGN(sz, val);
28 : 13 : graph->cir_start = sz;
29 : 13 : graph->cir_mask = rte_align32pow2(graph->node_count) - 1;
30 : 13 : sz += val;
31 : : /* Fence */
32 : : sz += sizeof(RTE_GRAPH_FENCE);
33 : 13 : sz = RTE_ALIGN(sz, RTE_CACHE_LINE_SIZE);
34 : 13 : graph->nodes_start = sz;
35 : : /* For 0..N node objects with fence */
36 [ + + ]: 96 : STAILQ_FOREACH(graph_node, &graph->node_list, next) {
37 : 83 : sz = RTE_ALIGN(sz, RTE_CACHE_LINE_SIZE);
38 : 83 : sz += sizeof(struct rte_node);
39 : : /* Pointer to next nodes(edges) */
40 : 83 : sz += sizeof(struct rte_node *) * graph_node->node->nb_edges;
41 : : }
42 : 13 : sz = RTE_ALIGN(sz, RTE_CACHE_LINE_SIZE);
43 : 13 : graph->xstats_start = sz;
44 : : /* For 0..N node objects with xstats */
45 [ + + ]: 96 : STAILQ_FOREACH(graph_node, &graph->node_list, next) {
46 [ + - ]: 83 : if (graph_node->node->xstats == NULL)
47 : 83 : continue;
48 : 0 : sz = RTE_ALIGN(sz, RTE_CACHE_LINE_SIZE);
49 : 0 : sz += sizeof(uint64_t) * graph_node->node->xstats->nb_xstats;
50 : : }
51 : :
52 : 13 : graph->mem_sz = sz;
53 : 13 : return sz;
54 : : }
55 : :
56 : : static void
57 : 13 : graph_header_popluate(struct graph *_graph)
58 : : {
59 : 13 : struct rte_graph *graph = _graph->graph;
60 : :
61 : 13 : graph->tail = 0;
62 : 13 : graph->head = (int32_t)-_graph->src_node_count;
63 : 13 : graph->cir_mask = _graph->cir_mask;
64 : 13 : graph->nb_nodes = _graph->node_count;
65 : 13 : graph->cir_start = RTE_PTR_ADD(graph, _graph->cir_start);
66 : 13 : graph->nodes_start = _graph->nodes_start;
67 : 13 : graph->socket = _graph->socket;
68 : 13 : graph->id = _graph->id;
69 : 13 : memcpy(graph->name, _graph->name, RTE_GRAPH_NAMESIZE);
70 : 13 : graph->fence = RTE_GRAPH_FENCE;
71 : 13 : }
72 : :
73 : : static void
74 : 13 : graph_nodes_populate(struct graph *_graph)
75 : : {
76 : 13 : rte_graph_off_t xstat_off = _graph->xstats_start;
77 : 13 : rte_graph_off_t off = _graph->nodes_start;
78 : 13 : struct rte_graph *graph = _graph->graph;
79 : : struct graph_node *graph_node;
80 : : rte_edge_t count, nb_edges;
81 : : rte_node_t pid;
82 : :
83 [ + + ]: 96 : STAILQ_FOREACH(graph_node, &_graph->node_list, next) {
84 : 83 : struct rte_node *node = RTE_PTR_ADD(graph, off);
85 : : memset(node, 0, sizeof(*node));
86 : 83 : node->fence = RTE_GRAPH_FENCE;
87 : 83 : node->off = off;
88 [ - + ]: 83 : if (graph_pcap_is_enable()) {
89 : 0 : node->process = graph_pcap_dispatch;
90 : 0 : node->original_process = graph_node->node->process;
91 : : } else
92 : 83 : node->process = graph_node->node->process;
93 [ + + ]: 83 : memcpy(node->name, graph_node->node->name, RTE_GRAPH_NAMESIZE);
94 : 83 : pid = graph_node->node->parent_id;
95 [ + + ]: 83 : if (pid != RTE_NODE_ID_INVALID) { /* Cloned node */
96 : : struct node *pnode;
97 : :
98 [ + - ]: 60 : STAILQ_FOREACH(pnode, node_list_head_get(), next) {
99 [ + + ]: 60 : if (pnode->id == pid) {
100 : 30 : memcpy(node->parent, pnode->name, RTE_GRAPH_NAMESIZE);
101 : : break;
102 : : }
103 : : }
104 : : }
105 : 83 : node->id = graph_node->node->id;
106 : 83 : node->parent_id = pid;
107 : 83 : node->dispatch.lcore_id = graph_node->node->lcore_id;
108 : 83 : nb_edges = graph_node->node->nb_edges;
109 : 83 : node->nb_edges = nb_edges;
110 : 83 : off += sizeof(struct rte_node);
111 : : /* Copy the name in first pass to replace with rte_node* later*/
112 [ + + ]: 240 : for (count = 0; count < nb_edges; count++)
113 : 157 : node->nodes[count] = (struct rte_node *)&graph_node
114 : 157 : ->adjacency_list[count]
115 : 157 : ->node->name[0];
116 : :
117 [ - + ]: 83 : if (graph_node->node->xstats != NULL) {
118 : 0 : node->xstat_off = xstat_off - off;
119 : 0 : xstat_off += sizeof(uint64_t) * graph_node->node->xstats->nb_xstats;
120 : 0 : xstat_off = RTE_ALIGN(xstat_off, RTE_CACHE_LINE_SIZE);
121 : : }
122 : :
123 : 83 : off += sizeof(struct rte_node *) * nb_edges;
124 : 83 : off = RTE_ALIGN(off, RTE_CACHE_LINE_SIZE);
125 : 83 : node->next = off;
126 : 83 : __rte_node_stream_alloc(graph, node);
127 : : }
128 : 13 : }
129 : :
130 : : struct rte_node *
131 : 5 : graph_node_id_to_ptr(const struct rte_graph *graph, rte_node_t id)
132 : : {
133 : : rte_node_t count;
134 : : rte_graph_off_t off;
135 : : struct rte_node *node;
136 : :
137 [ + - ]: 15 : rte_graph_foreach_node(count, off, graph, node)
138 [ + + ]: 15 : if (unlikely(node->id == id))
139 : 5 : return node;
140 : :
141 : : return NULL;
142 : : }
143 : :
144 : : struct rte_node *
145 : 253 : graph_node_name_to_ptr(const struct rte_graph *graph, const char *name)
146 : : {
147 : : rte_node_t count;
148 : : rte_graph_off_t off;
149 : : struct rte_node *node;
150 : :
151 [ + - ]: 1191 : rte_graph_foreach_node(count, off, graph, node)
152 [ + + ]: 1191 : if (strncmp(name, node->name, RTE_NODE_NAMESIZE) == 0)
153 : 253 : return node;
154 : :
155 : : return NULL;
156 : : }
157 : :
158 : : static int
159 : 13 : graph_node_nexts_populate(struct graph *_graph)
160 : : {
161 : : rte_node_t count, val;
162 : : rte_graph_off_t off;
163 : : struct rte_node *node;
164 : 13 : const struct rte_graph *graph = _graph->graph;
165 : : const char *name;
166 : :
167 [ + + ]: 96 : rte_graph_foreach_node(count, off, graph, node) {
168 [ + + ]: 240 : for (val = 0; val < node->nb_edges; val++) {
169 : 157 : name = (const char *)node->nodes[val];
170 : 157 : node->nodes[val] = graph_node_name_to_ptr(graph, name);
171 [ - + ]: 157 : if (node->nodes[val] == NULL)
172 : 0 : SET_ERR_JMP(EINVAL, fail, "%s not found", name);
173 : : }
174 : : }
175 : :
176 : : return 0;
177 : : fail:
178 : 0 : return -rte_errno;
179 : : }
180 : :
181 : : static int
182 : 13 : graph_src_nodes_offset_populate(struct graph *_graph)
183 : : {
184 : 13 : struct rte_graph *graph = _graph->graph;
185 : : struct graph_node *graph_node;
186 : : struct rte_node *node;
187 : : int32_t head = -1;
188 : : const char *name;
189 : :
190 [ + + ]: 96 : STAILQ_FOREACH(graph_node, &_graph->node_list, next) {
191 [ + + ]: 83 : if (graph_node->node->flags & RTE_NODE_SOURCE_F) {
192 : 13 : name = graph_node->node->name;
193 : 13 : node = graph_node_name_to_ptr(graph, name);
194 [ - + ]: 13 : if (node == NULL)
195 : 0 : SET_ERR_JMP(EINVAL, fail, "%s not found", name);
196 : :
197 : 13 : __rte_node_stream_alloc(graph, node);
198 : 13 : graph->cir_start[head--] = node->off;
199 : : }
200 : : }
201 : :
202 : : return 0;
203 : : fail:
204 : 0 : return -rte_errno;
205 : : }
206 : :
207 : : static int
208 : 13 : graph_fp_mem_populate(struct graph *graph)
209 : : {
210 : : int rc;
211 : :
212 : 13 : graph_header_popluate(graph);
213 [ - + ]: 13 : if (graph_pcap_is_enable())
214 : 0 : graph_pcap_init(graph);
215 : 13 : graph_nodes_populate(graph);
216 : 13 : rc = graph_node_nexts_populate(graph);
217 : 13 : rc |= graph_src_nodes_offset_populate(graph);
218 : :
219 : 13 : return rc;
220 : : }
221 : :
222 : : int
223 : 13 : graph_fp_mem_create(struct graph *graph)
224 : : {
225 : : const struct rte_memzone *mz;
226 : : size_t sz;
227 : :
228 : 13 : sz = graph_fp_mem_calc_size(graph);
229 : 13 : mz = rte_memzone_reserve(graph->name, sz, graph->socket, 0);
230 [ - + ]: 13 : if (mz == NULL)
231 : 0 : SET_ERR_JMP(ENOMEM, fail, "Memzone %s reserve failed",
232 : : graph->name);
233 : :
234 : 13 : graph->graph = mz->addr;
235 : 13 : graph->mz = mz;
236 : :
237 : 13 : return graph_fp_mem_populate(graph);
238 : : fail:
239 : 0 : return -rte_errno;
240 : : }
241 : :
242 : : static void
243 : 13 : graph_nodes_mem_destroy(struct rte_graph *graph)
244 : : {
245 : : rte_node_t count;
246 : : rte_graph_off_t off;
247 : : struct rte_node *node;
248 : :
249 [ + - ]: 13 : if (graph == NULL)
250 : : return;
251 : :
252 [ + + ]: 96 : rte_graph_foreach_node(count, off, graph, node)
253 : 83 : rte_free(node->objs);
254 : : }
255 : :
256 : : int
257 : 13 : graph_fp_mem_destroy(struct graph *graph)
258 : : {
259 [ - + ]: 13 : if (graph_pcap_is_enable())
260 : 0 : graph_pcap_exit(graph->graph);
261 : :
262 : 13 : graph_nodes_mem_destroy(graph->graph);
263 : 13 : return rte_memzone_free(graph->mz);
264 : : }
|