Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2010-2018 Intel Corporation
3 : : */
4 : :
5 : : #include <stdlib.h>
6 : : #include <string.h>
7 : :
8 : : #include <rte_common.h>
9 : : #include <rte_string_fns.h>
10 : :
11 : : #include "rte_eth_softnic_internals.h"
12 : :
13 : : int
14 : 0 : softnic_pipeline_init(struct pmd_internals *p)
15 : : {
16 : 0 : TAILQ_INIT(&p->pipeline_list);
17 : :
18 : 0 : return 0;
19 : : }
20 : :
21 : : void
22 : 0 : softnic_pipeline_free(struct pmd_internals *p)
23 : : {
24 : 0 : for ( ; ; ) {
25 : : struct pipeline *pipeline;
26 : :
27 : 0 : pipeline = TAILQ_FIRST(&p->pipeline_list);
28 [ # # ]: 0 : if (pipeline == NULL)
29 : : break;
30 : :
31 [ # # ]: 0 : TAILQ_REMOVE(&p->pipeline_list, pipeline, node);
32 : 0 : rte_swx_ctl_pipeline_free(pipeline->ctl);
33 : 0 : rte_swx_pipeline_free(pipeline->p);
34 : 0 : free(pipeline);
35 : : }
36 : 0 : }
37 : :
38 : : void
39 : 0 : softnic_pipeline_disable_all(struct pmd_internals *p)
40 : : {
41 : : struct pipeline *pipeline;
42 : :
43 [ # # ]: 0 : TAILQ_FOREACH(pipeline, &p->pipeline_list, node)
44 [ # # ]: 0 : if (pipeline->enabled)
45 : 0 : softnic_thread_pipeline_disable(p,
46 : : pipeline->thread_id,
47 : : pipeline);
48 : 0 : }
49 : :
50 : : uint32_t
51 : 0 : softnic_pipeline_thread_count(struct pmd_internals *p, uint32_t thread_id)
52 : : {
53 : : struct pipeline *pipeline;
54 : : uint32_t count = 0;
55 : :
56 [ # # ]: 0 : TAILQ_FOREACH(pipeline, &p->pipeline_list, node)
57 [ # # # # ]: 0 : if ((pipeline->enabled) && (pipeline->thread_id == thread_id))
58 : 0 : count++;
59 : :
60 : 0 : return count;
61 : : }
62 : :
63 : : struct pipeline *
64 : 0 : softnic_pipeline_find(struct pmd_internals *p,
65 : : const char *name)
66 : : {
67 : : struct pipeline *pipeline;
68 : :
69 [ # # ]: 0 : if (name == NULL)
70 : : return NULL;
71 : :
72 [ # # ]: 0 : TAILQ_FOREACH(pipeline, &p->pipeline_list, node)
73 [ # # ]: 0 : if (strcmp(name, pipeline->name) == 0)
74 : 0 : return pipeline;
75 : :
76 : : return NULL;
77 : : }
78 : :
79 : : #ifndef MAX_LINE_LENGTH
80 : : #define MAX_LINE_LENGTH 2048
81 : : #endif
82 : :
83 : : /* The Soft NIC device internal resources such as mempools, rings or pipelines are globally visible,
84 : : * hence they need to have globally unique names. In order to apply the same configuration scripts
85 : : * unmodified to all the Soft NIC devices that instantiate the same program, the pipeline I/O
86 : : * configuration files are silently translated internally to prefix the name of the above resources
87 : : * with the Soft NIC device name, thus making the resource names globally unique.
88 : : */
89 : : static int
90 : 0 : iospec_translate(struct pmd_internals *softnic __rte_unused,
91 : : const char *file_in_name,
92 : : const char *file_out_name)
93 : : {
94 : : FILE *fi = NULL, *fo = NULL;
95 : : char *line = NULL;
96 : : int status = 0;
97 : :
98 : : /* File open. */
99 : 0 : fi = fopen(file_in_name, "r");
100 : 0 : fo = fopen(file_out_name, "w");
101 [ # # ]: 0 : if (!fi || !fo) {
102 : : status = -EIO;
103 : 0 : goto free;
104 : : }
105 : :
106 : : /* Memory allocation. */
107 : 0 : line = malloc(MAX_LINE_LENGTH);
108 [ # # ]: 0 : if (!line) {
109 : : status = -ENOMEM;
110 : 0 : goto free;
111 : : }
112 : :
113 : : /* Read from the input file and write to the output file. */
114 : : for ( ; ; ) {
115 [ # # ]: 0 : char *ptr = line;
116 : : uint32_t n_tokens;
117 : : int flag = 0;
118 : :
119 : : /* Read next line. */
120 [ # # ]: 0 : if (!fgets(line, MAX_LINE_LENGTH, fi))
121 : : break;
122 : :
123 : : /* Parse the line into tokens. */
124 : 0 : for (n_tokens = 0; ; n_tokens++) {
125 : : char *token;
126 : :
127 : : /* Read token. */
128 : 0 : token = strtok_r(ptr, " \f\n\r\t\v", &ptr);
129 [ # # ]: 0 : if (!token)
130 : : break;
131 : :
132 : : /* Handle comments. */
133 [ # # ]: 0 : if (!n_tokens &&
134 [ # # ]: 0 : ((token[0] == '#') ||
135 [ # # ]: 0 : (token[0] == ';') ||
136 [ # # ]: 0 : ((token[0] == '/') && (token[1] == '/'))))
137 : : break;
138 : :
139 : : /* Process token. */
140 [ # # ]: 0 : if (flag) {
141 : 0 : fprintf(fo, "%s_%s ", softnic->params.name, token);
142 : : flag = 0;
143 : 0 : continue;
144 : : }
145 : :
146 [ # # ]: 0 : if (!strcmp(token, "mempool") ||
147 [ # # ]: 0 : !strcmp(token, "ring")) {
148 : : flag = 1;
149 : : fprintf(fo, "%s ", token);
150 : 0 : continue;
151 : : }
152 : :
153 : : /* Default action: write token. */
154 : : fprintf(fo, "%s ", token);
155 : : }
156 : :
157 : : /* Handle empty or comment lines. */
158 [ # # ]: 0 : if (!n_tokens)
159 : 0 : continue;
160 : :
161 : : /* Write newline. */
162 : : fprintf(fo, "\n");
163 : : }
164 : :
165 : 0 : free:
166 : : /* Memory free. */
167 : 0 : free(line);
168 : :
169 : : /* File close. */
170 [ # # ]: 0 : if (fi)
171 : 0 : fclose(fi);
172 [ # # ]: 0 : if (fo)
173 : 0 : fclose(fo);
174 : 0 : return status;
175 : : }
176 : :
177 : : struct pipeline *
178 : 0 : softnic_pipeline_create(struct pmd_internals *softnic,
179 : : const char *name,
180 : : const char *lib_file_name,
181 : : const char *iospec_file_name,
182 : : int numa_node)
183 : : {
184 : : char global_name[NAME_MAX];
185 : : FILE *iospec_file = NULL;
186 : : struct pipeline *pipeline = NULL;
187 : 0 : struct rte_swx_pipeline *p = NULL;
188 : : struct rte_swx_ctl_pipeline *ctl = NULL;
189 : : int status = 0;
190 : :
191 : : /* Check input params */
192 [ # # # # : 0 : if (!name || !name[0] || softnic_pipeline_find(softnic, name))
# # ]
193 : 0 : goto error;
194 : :
195 : : /* Resource create */
196 : 0 : snprintf(global_name, sizeof(global_name), "/tmp/%s_%s.io", softnic->params.name, name);
197 : :
198 : 0 : status = iospec_translate(softnic, iospec_file_name, global_name);
199 [ # # ]: 0 : if (status)
200 : 0 : goto error;
201 : :
202 : 0 : iospec_file = fopen(global_name, "r");
203 [ # # ]: 0 : if (!iospec_file)
204 : 0 : goto error;
205 : :
206 : : snprintf(global_name, sizeof(global_name), "%s_%s", softnic->params.name, name);
207 : :
208 : 0 : status = rte_swx_pipeline_build_from_lib(&p,
209 : : global_name,
210 : : lib_file_name,
211 : : iospec_file,
212 : : numa_node);
213 [ # # ]: 0 : if (status)
214 : 0 : goto error;
215 : :
216 : 0 : fclose(iospec_file);
217 : : iospec_file = NULL;
218 : :
219 : 0 : ctl = rte_swx_ctl_pipeline_create(p);
220 [ # # ]: 0 : if (!ctl)
221 : 0 : goto error;
222 : :
223 : : /* Node allocation */
224 : 0 : pipeline = calloc(1, sizeof(struct pipeline));
225 [ # # ]: 0 : if (!pipeline)
226 : 0 : goto error;
227 : :
228 : : /* Node fill in */
229 : 0 : strlcpy(pipeline->name, name, sizeof(pipeline->name));
230 : 0 : pipeline->p = p;
231 : 0 : pipeline->ctl = ctl;
232 : :
233 : : /* Node add to list */
234 : 0 : TAILQ_INSERT_TAIL(&softnic->pipeline_list, pipeline, node);
235 : :
236 : 0 : return pipeline;
237 : :
238 : 0 : error:
239 : : free(pipeline);
240 : 0 : rte_swx_ctl_pipeline_free(ctl);
241 : 0 : rte_swx_pipeline_free(p);
242 [ # # ]: 0 : if (iospec_file)
243 : 0 : fclose(iospec_file);
244 : : return NULL;
245 : : }
|