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