xref: /dpdk/examples/qos_sched/cfg_file.c (revision 1f41d98c207aee8982ced709864c96c463d4503a)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4 
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <ctype.h>
9 #include <rte_string_fns.h>
10 #include <rte_sched.h>
11 
12 #include "cfg_file.h"
13 #include "main.h"
14 
15 
16 /** when we resize a file structure, how many extra entries
17  * for new sections do we add in */
18 #define CFG_ALLOC_SECTION_BATCH 8
19 /** when we resize a section structure, how many extra entries
20  * for new entries do we add in */
21 #define CFG_ALLOC_ENTRY_BATCH 16
22 
23 int
24 cfg_load_port(struct rte_cfgfile *cfg, struct rte_sched_port_params *port_params)
25 {
26 	const char *entry;
27 
28 	if (!cfg || !port_params)
29 		return -1;
30 
31 	entry = rte_cfgfile_get_entry(cfg, "port", "frame overhead");
32 	if (entry)
33 		port_params->frame_overhead = (uint32_t)atoi(entry);
34 
35 	entry = rte_cfgfile_get_entry(cfg, "port", "number of subports per port");
36 	if (entry)
37 		port_params->n_subports_per_port = (uint32_t)atoi(entry);
38 
39 	return 0;
40 }
41 
42 int
43 cfg_load_pipe(struct rte_cfgfile *cfg, struct rte_sched_pipe_params *pipe_params)
44 {
45 	int i, j;
46 	char *next;
47 	const char *entry;
48 	int profiles;
49 
50 	if (!cfg || !pipe_params)
51 		return -1;
52 
53 	profiles = rte_cfgfile_num_sections(cfg, "pipe profile", sizeof("pipe profile") - 1);
54 	subport_params[0].n_pipe_profiles = profiles;
55 
56 	for (j = 0; j < profiles; j++) {
57 		char pipe_name[32];
58 		snprintf(pipe_name, sizeof(pipe_name), "pipe profile %d", j);
59 
60 		entry = rte_cfgfile_get_entry(cfg, pipe_name, "tb rate");
61 		if (entry)
62 			pipe_params[j].tb_rate = (uint64_t)atoi(entry);
63 
64 		entry = rte_cfgfile_get_entry(cfg, pipe_name, "tb size");
65 		if (entry)
66 			pipe_params[j].tb_size = (uint64_t)atoi(entry);
67 
68 		entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc period");
69 		if (entry)
70 			pipe_params[j].tc_period = (uint64_t)atoi(entry);
71 
72 		entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 0 rate");
73 		if (entry)
74 			pipe_params[j].tc_rate[0] = (uint64_t)atoi(entry);
75 
76 		entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 1 rate");
77 		if (entry)
78 			pipe_params[j].tc_rate[1] = (uint64_t)atoi(entry);
79 
80 		entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 2 rate");
81 		if (entry)
82 			pipe_params[j].tc_rate[2] = (uint64_t)atoi(entry);
83 
84 		entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 3 rate");
85 		if (entry)
86 			pipe_params[j].tc_rate[3] = (uint64_t)atoi(entry);
87 
88 		entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 4 rate");
89 		if (entry)
90 			pipe_params[j].tc_rate[4] = (uint64_t)atoi(entry);
91 
92 		entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 5 rate");
93 		if (entry)
94 			pipe_params[j].tc_rate[5] = (uint64_t)atoi(entry);
95 
96 		entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 6 rate");
97 		if (entry)
98 			pipe_params[j].tc_rate[6] = (uint64_t)atoi(entry);
99 
100 		entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 7 rate");
101 		if (entry)
102 			pipe_params[j].tc_rate[7] = (uint64_t)atoi(entry);
103 
104 		entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 8 rate");
105 		if (entry)
106 			pipe_params[j].tc_rate[8] = (uint64_t)atoi(entry);
107 
108 		entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 9 rate");
109 		if (entry)
110 			pipe_params[j].tc_rate[9] = (uint64_t)atoi(entry);
111 
112 		entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 10 rate");
113 		if (entry)
114 			pipe_params[j].tc_rate[10] = (uint64_t)atoi(entry);
115 
116 		entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 11 rate");
117 		if (entry)
118 			pipe_params[j].tc_rate[11] = (uint64_t)atoi(entry);
119 
120 		entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 12 rate");
121 		if (entry)
122 			pipe_params[j].tc_rate[12] = (uint64_t)atoi(entry);
123 
124 		entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 12 oversubscription weight");
125 		if (entry)
126 			pipe_params[j].tc_ov_weight = (uint8_t)atoi(entry);
127 
128 		entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 12 wrr weights");
129 		if (entry) {
130 			for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) {
131 				pipe_params[j].wrr_weights[i] =
132 					(uint8_t)strtol(entry, &next, 10);
133 				if (next == NULL)
134 					break;
135 				entry = next;
136 			}
137 		}
138 	}
139 	return 0;
140 }
141 
142 int
143 cfg_load_subport(struct rte_cfgfile *cfg, struct rte_sched_subport_params *subport_params)
144 {
145 	const char *entry;
146 	int i, j, k;
147 
148 	if (!cfg || !subport_params)
149 		return -1;
150 
151 	memset(app_pipe_to_profile, -1, sizeof(app_pipe_to_profile));
152 	memset(active_queues, 0, sizeof(active_queues));
153 	n_active_queues = 0;
154 
155 #ifdef RTE_SCHED_RED
156 	char sec_name[CFG_NAME_LEN];
157 	struct rte_red_params red_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS];
158 
159 	snprintf(sec_name, sizeof(sec_name), "red");
160 
161 	if (rte_cfgfile_has_section(cfg, sec_name)) {
162 
163 		for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) {
164 			char str[32];
165 
166 			/* Parse WRED min thresholds */
167 			snprintf(str, sizeof(str), "tc %d wred min", i);
168 			entry = rte_cfgfile_get_entry(cfg, sec_name, str);
169 			if (entry) {
170 				char *next;
171 				/* for each packet colour (green, yellow, red) */
172 				for (j = 0; j < RTE_COLORS; j++) {
173 					red_params[i][j].min_th
174 						= (uint16_t)strtol(entry, &next, 10);
175 					if (next == NULL)
176 						break;
177 					entry = next;
178 				}
179 			}
180 
181 			/* Parse WRED max thresholds */
182 			snprintf(str, sizeof(str), "tc %d wred max", i);
183 			entry = rte_cfgfile_get_entry(cfg, "red", str);
184 			if (entry) {
185 				char *next;
186 				/* for each packet colour (green, yellow, red) */
187 				for (j = 0; j < RTE_COLORS; j++) {
188 					red_params[i][j].max_th
189 						= (uint16_t)strtol(entry, &next, 10);
190 					if (next == NULL)
191 						break;
192 					entry = next;
193 				}
194 			}
195 
196 			/* Parse WRED inverse mark probabilities */
197 			snprintf(str, sizeof(str), "tc %d wred inv prob", i);
198 			entry = rte_cfgfile_get_entry(cfg, "red", str);
199 			if (entry) {
200 				char *next;
201 				/* for each packet colour (green, yellow, red) */
202 				for (j = 0; j < RTE_COLORS; j++) {
203 					red_params[i][j].maxp_inv
204 						= (uint8_t)strtol(entry, &next, 10);
205 
206 					if (next == NULL)
207 						break;
208 					entry = next;
209 				}
210 			}
211 
212 			/* Parse WRED EWMA filter weights */
213 			snprintf(str, sizeof(str), "tc %d wred weight", i);
214 			entry = rte_cfgfile_get_entry(cfg, "red", str);
215 			if (entry) {
216 				char *next;
217 				/* for each packet colour (green, yellow, red) */
218 				for (j = 0; j < RTE_COLORS; j++) {
219 					red_params[i][j].wq_log2
220 						= (uint8_t)strtol(entry, &next, 10);
221 					if (next == NULL)
222 						break;
223 					entry = next;
224 				}
225 			}
226 		}
227 	}
228 #endif /* RTE_SCHED_RED */
229 
230 	for (i = 0; i < MAX_SCHED_SUBPORTS; i++) {
231 		char sec_name[CFG_NAME_LEN];
232 		snprintf(sec_name, sizeof(sec_name), "subport %d", i);
233 
234 		if (rte_cfgfile_has_section(cfg, sec_name)) {
235 			entry = rte_cfgfile_get_entry(cfg, sec_name,
236 				"number of pipes per subport");
237 			if (entry)
238 				subport_params[i].n_pipes_per_subport_enabled =
239 					(uint32_t)atoi(entry);
240 
241 			entry = rte_cfgfile_get_entry(cfg, sec_name, "queue sizes");
242 			if (entry) {
243 				char *next;
244 
245 				for (j = 0; j < RTE_SCHED_TRAFFIC_CLASS_BE; j++) {
246 					subport_params[i].qsize[j] =
247 						(uint16_t)strtol(entry, &next, 10);
248 					if (subport_params[i].qsize[j] != 0) {
249 						active_queues[n_active_queues] = j;
250 						n_active_queues++;
251 					}
252 					if (next == NULL)
253 						break;
254 					entry = next;
255 				}
256 
257 				subport_params[i].qsize[RTE_SCHED_TRAFFIC_CLASS_BE] =
258 					(uint16_t)strtol(entry, &next, 10);
259 
260 				for (j = 0; j < RTE_SCHED_BE_QUEUES_PER_PIPE; j++) {
261 					active_queues[n_active_queues] =
262 						RTE_SCHED_TRAFFIC_CLASS_BE + j;
263 					n_active_queues++;
264 				}
265 			}
266 
267 			entry = rte_cfgfile_get_entry(cfg, sec_name, "tb rate");
268 			if (entry)
269 				subport_params[i].tb_rate = (uint64_t)atoi(entry);
270 
271 			entry = rte_cfgfile_get_entry(cfg, sec_name, "tb size");
272 			if (entry)
273 				subport_params[i].tb_size = (uint64_t)atoi(entry);
274 
275 			entry = rte_cfgfile_get_entry(cfg, sec_name, "tc period");
276 			if (entry)
277 				subport_params[i].tc_period = (uint64_t)atoi(entry);
278 
279 			entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 0 rate");
280 			if (entry)
281 				subport_params[i].tc_rate[0] = (uint64_t)atoi(entry);
282 
283 			entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 1 rate");
284 			if (entry)
285 				subport_params[i].tc_rate[1] = (uint64_t)atoi(entry);
286 
287 			entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 2 rate");
288 			if (entry)
289 				subport_params[i].tc_rate[2] = (uint64_t)atoi(entry);
290 
291 			entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 3 rate");
292 			if (entry)
293 				subport_params[i].tc_rate[3] = (uint64_t)atoi(entry);
294 
295 			entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 4 rate");
296 			if (entry)
297 				subport_params[i].tc_rate[4] = (uint64_t)atoi(entry);
298 
299 			entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 5 rate");
300 			if (entry)
301 				subport_params[i].tc_rate[5] = (uint64_t)atoi(entry);
302 
303 			entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 6 rate");
304 			if (entry)
305 				subport_params[i].tc_rate[6] = (uint64_t)atoi(entry);
306 
307 			entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 7 rate");
308 			if (entry)
309 				subport_params[i].tc_rate[7] = (uint64_t)atoi(entry);
310 
311 			entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 8 rate");
312 			if (entry)
313 				subport_params[i].tc_rate[8] = (uint64_t)atoi(entry);
314 
315 			entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 9 rate");
316 			if (entry)
317 				subport_params[i].tc_rate[9] = (uint64_t)atoi(entry);
318 
319 			entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 10 rate");
320 			if (entry)
321 				subport_params[i].tc_rate[10] = (uint64_t)atoi(entry);
322 
323 			entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 11 rate");
324 			if (entry)
325 				subport_params[i].tc_rate[11] = (uint64_t)atoi(entry);
326 
327 			entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 12 rate");
328 			if (entry)
329 				subport_params[i].tc_rate[12] = (uint64_t)atoi(entry);
330 
331 			int n_entries = rte_cfgfile_section_num_entries(cfg, sec_name);
332 			struct rte_cfgfile_entry entries[n_entries];
333 
334 			rte_cfgfile_section_entries(cfg, sec_name, entries, n_entries);
335 
336 			for (j = 0; j < n_entries; j++) {
337 				if (strncmp("pipe", entries[j].name, sizeof("pipe") - 1) == 0) {
338 					int profile;
339 					char *tokens[2] = {NULL, NULL};
340 					int n_tokens;
341 					int begin, end;
342 
343 					profile = atoi(entries[j].value);
344 					n_tokens = rte_strsplit(&entries[j].name[sizeof("pipe")],
345 							strnlen(entries[j].name, CFG_NAME_LEN), tokens, 2, '-');
346 
347 					begin =  atoi(tokens[0]);
348 					if (n_tokens == 2)
349 						end = atoi(tokens[1]);
350 					else
351 						end = begin;
352 
353 					if (end >= MAX_SCHED_PIPES || begin > end)
354 						return -1;
355 
356 					for (k = begin; k <= end; k++) {
357 						char profile_name[CFG_NAME_LEN];
358 
359 						snprintf(profile_name, sizeof(profile_name),
360 								"pipe profile %d", profile);
361 						if (rte_cfgfile_has_section(cfg, profile_name))
362 							app_pipe_to_profile[i][k] = profile;
363 						else
364 							rte_exit(EXIT_FAILURE, "Wrong pipe profile %s\n",
365 									entries[j].value);
366 
367 					}
368 				}
369 			}
370 #ifdef RTE_SCHED_RED
371 			for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) {
372 				for (k = 0; k < RTE_COLORS; k++) {
373 					subport_params[i].red_params[j][k].min_th =
374 						red_params[j][k].min_th;
375 					subport_params[i].red_params[j][k].max_th =
376 						red_params[j][k].max_th;
377 					subport_params[i].red_params[j][k].maxp_inv =
378 						red_params[j][k].maxp_inv;
379 					subport_params[i].red_params[j][k].wq_log2 =
380 						red_params[j][k].wq_log2;
381 				}
382 			}
383 #endif
384 		}
385 	}
386 
387 	return 0;
388 }
389