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