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