1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation
9 #include <rte_string_fns.h>
10 #include <rte_sched.h>
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
24 cfg_load_port(struct rte_cfgfile *cfg, struct rte_sched_port_params *port_params)
28 if (!cfg || !port_params)
31 entry = rte_cfgfile_get_entry(cfg, "port", "frame overhead");
33 port_params->frame_overhead = (uint32_t)atoi(entry);
35 entry = rte_cfgfile_get_entry(cfg, "port", "number of subports per port");
37 port_params->n_subports_per_port = (uint32_t)atoi(entry);
43 cfg_load_pipe(struct rte_cfgfile *cfg, struct rte_sched_pipe_params *pipe_params)
50 if (!cfg || !pipe_params)
53 profiles = rte_cfgfile_num_sections(cfg, "pipe profile", sizeof("pipe profile") - 1);
54 subport_params[0].n_pipe_profiles = profiles;
56 for (j = 0; j < profiles; j++) {
58 snprintf(pipe_name, sizeof(pipe_name), "pipe profile %d", j);
60 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tb rate");
62 pipe_params[j].tb_rate = (uint64_t)atoi(entry);
64 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tb size");
66 pipe_params[j].tb_size = (uint64_t)atoi(entry);
68 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc period");
70 pipe_params[j].tc_period = (uint64_t)atoi(entry);
72 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 0 rate");
74 pipe_params[j].tc_rate[0] = (uint64_t)atoi(entry);
76 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 1 rate");
78 pipe_params[j].tc_rate[1] = (uint64_t)atoi(entry);
80 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 2 rate");
82 pipe_params[j].tc_rate[2] = (uint64_t)atoi(entry);
84 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 3 rate");
86 pipe_params[j].tc_rate[3] = (uint64_t)atoi(entry);
88 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 4 rate");
90 pipe_params[j].tc_rate[4] = (uint64_t)atoi(entry);
92 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 5 rate");
94 pipe_params[j].tc_rate[5] = (uint64_t)atoi(entry);
96 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 6 rate");
98 pipe_params[j].tc_rate[6] = (uint64_t)atoi(entry);
100 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 7 rate");
102 pipe_params[j].tc_rate[7] = (uint64_t)atoi(entry);
104 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 8 rate");
106 pipe_params[j].tc_rate[8] = (uint64_t)atoi(entry);
108 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 9 rate");
110 pipe_params[j].tc_rate[9] = (uint64_t)atoi(entry);
112 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 10 rate");
114 pipe_params[j].tc_rate[10] = (uint64_t)atoi(entry);
116 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 11 rate");
118 pipe_params[j].tc_rate[11] = (uint64_t)atoi(entry);
120 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 12 rate");
122 pipe_params[j].tc_rate[12] = (uint64_t)atoi(entry);
124 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 12 oversubscription weight");
126 pipe_params[j].tc_ov_weight = (uint8_t)atoi(entry);
128 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 12 wrr weights");
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);
143 cfg_load_subport(struct rte_cfgfile *cfg, struct rte_sched_subport_params *subport_params)
148 if (!cfg || !subport_params)
151 memset(app_pipe_to_profile, -1, sizeof(app_pipe_to_profile));
152 memset(active_queues, 0, sizeof(active_queues));
156 char sec_name[CFG_NAME_LEN];
157 struct rte_red_params red_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS];
159 snprintf(sec_name, sizeof(sec_name), "red");
161 if (rte_cfgfile_has_section(cfg, sec_name)) {
163 for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) {
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);
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);
181 /* Parse WRED max thresholds */
182 snprintf(str, sizeof(str), "tc %d wred max", i);
183 entry = rte_cfgfile_get_entry(cfg, "red", str);
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);
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);
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);
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);
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);
228 #endif /* RTE_SCHED_RED */
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);
234 if (rte_cfgfile_has_section(cfg, sec_name)) {
235 entry = rte_cfgfile_get_entry(cfg, sec_name,
236 "number of pipes per subport");
238 subport_params[i].n_pipes_per_subport_enabled =
239 (uint32_t)atoi(entry);
241 entry = rte_cfgfile_get_entry(cfg, sec_name, "queue sizes");
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;
257 subport_params[i].qsize[RTE_SCHED_TRAFFIC_CLASS_BE] =
258 (uint16_t)strtol(entry, &next, 10);
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;
267 entry = rte_cfgfile_get_entry(cfg, sec_name, "tb rate");
269 subport_params[i].tb_rate = (uint64_t)atoi(entry);
271 entry = rte_cfgfile_get_entry(cfg, sec_name, "tb size");
273 subport_params[i].tb_size = (uint64_t)atoi(entry);
275 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc period");
277 subport_params[i].tc_period = (uint64_t)atoi(entry);
279 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 0 rate");
281 subport_params[i].tc_rate[0] = (uint64_t)atoi(entry);
283 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 1 rate");
285 subport_params[i].tc_rate[1] = (uint64_t)atoi(entry);
287 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 2 rate");
289 subport_params[i].tc_rate[2] = (uint64_t)atoi(entry);
291 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 3 rate");
293 subport_params[i].tc_rate[3] = (uint64_t)atoi(entry);
295 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 4 rate");
297 subport_params[i].tc_rate[4] = (uint64_t)atoi(entry);
299 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 5 rate");
301 subport_params[i].tc_rate[5] = (uint64_t)atoi(entry);
303 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 6 rate");
305 subport_params[i].tc_rate[6] = (uint64_t)atoi(entry);
307 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 7 rate");
309 subport_params[i].tc_rate[7] = (uint64_t)atoi(entry);
311 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 8 rate");
313 subport_params[i].tc_rate[8] = (uint64_t)atoi(entry);
315 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 9 rate");
317 subport_params[i].tc_rate[9] = (uint64_t)atoi(entry);
319 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 10 rate");
321 subport_params[i].tc_rate[10] = (uint64_t)atoi(entry);
323 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 11 rate");
325 subport_params[i].tc_rate[11] = (uint64_t)atoi(entry);
327 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 12 rate");
329 subport_params[i].tc_rate[12] = (uint64_t)atoi(entry);
331 int n_entries = rte_cfgfile_section_num_entries(cfg, sec_name);
332 struct rte_cfgfile_entry entries[n_entries];
334 rte_cfgfile_section_entries(cfg, sec_name, entries, n_entries);
336 for (j = 0; j < n_entries; j++) {
337 if (strncmp("pipe", entries[j].name, sizeof("pipe") - 1) == 0) {
339 char *tokens[2] = {NULL, NULL};
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, '-');
347 begin = atoi(tokens[0]);
349 end = atoi(tokens[1]);
353 if (end >= MAX_SCHED_PIPES || begin > end)
356 for (k = begin; k <= end; k++) {
357 char profile_name[CFG_NAME_LEN];
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;
364 rte_exit(EXIT_FAILURE, "Wrong pipe profile %s\n",
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;