2 // Copyright (c) 2017 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
27 #include <rte_errno.h>
28 #include <rte_cfgfile.h>
29 #include <rte_string_fns.h>
34 tm_cfgfile_load_sched_port(
35 struct rte_cfgfile *file,
36 struct rte_sched_port_params *port_params)
41 entry = rte_cfgfile_get_entry(file, "port", "frame overhead");
43 port_params->frame_overhead = (uint32_t)atoi(entry);
45 entry = rte_cfgfile_get_entry(file, "port", "mtu");
47 port_params->mtu = (uint32_t)atoi(entry);
49 entry = rte_cfgfile_get_entry(file,
51 "number of subports per port");
53 port_params->n_subports_per_port = (uint32_t) atoi(entry);
55 entry = rte_cfgfile_get_entry(file,
57 "number of pipes per subport");
59 port_params->n_pipes_per_subport = (uint32_t) atoi(entry);
61 entry = rte_cfgfile_get_entry(file, "port", "queue sizes");
65 for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) {
66 port_params->qsize[j] = (uint16_t)
67 strtol(entry, &next, 10);
75 for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) {
78 /* Parse WRED min thresholds */
79 snprintf(str, sizeof(str), "tc %" PRId32 " wred min", j);
80 entry = rte_cfgfile_get_entry(file, "red", str);
85 /* for each packet colour (green, yellow, red) */
86 for (k = 0; k < e_RTE_METER_COLORS; k++) {
87 port_params->red_params[j][k].min_th
88 = (uint16_t)strtol(entry, &next, 10);
95 /* Parse WRED max thresholds */
96 snprintf(str, sizeof(str), "tc %" PRId32 " wred max", j);
97 entry = rte_cfgfile_get_entry(file, "red", str);
102 /* for each packet colour (green, yellow, red) */
103 for (k = 0; k < e_RTE_METER_COLORS; k++) {
104 port_params->red_params[j][k].max_th
105 = (uint16_t)strtol(entry, &next, 10);
112 /* Parse WRED inverse mark probabilities */
113 snprintf(str, sizeof(str), "tc %" PRId32 " wred inv prob", j);
114 entry = rte_cfgfile_get_entry(file, "red", str);
119 /* for each packet colour (green, yellow, red) */
120 for (k = 0; k < e_RTE_METER_COLORS; k++) {
121 port_params->red_params[j][k].maxp_inv
122 = (uint8_t)strtol(entry, &next, 10);
130 /* Parse WRED EWMA filter weights */
131 snprintf(str, sizeof(str), "tc %" PRId32 " wred weight", j);
132 entry = rte_cfgfile_get_entry(file, "red", str);
137 /* for each packet colour (green, yellow, red) */
138 for (k = 0; k < e_RTE_METER_COLORS; k++) {
139 port_params->red_params[j][k].wq_log2
140 = (uint8_t)strtol(entry, &next, 10);
147 #endif /* RTE_SCHED_RED */
153 tm_cfgfile_load_sched_pipe(
154 struct rte_cfgfile *file,
155 struct rte_sched_port_params *port_params,
156 struct rte_sched_pipe_params *pipe_params)
163 profiles = rte_cfgfile_num_sections(file,
164 "pipe profile", sizeof("pipe profile") - 1);
165 port_params->n_pipe_profiles = profiles;
167 for (j = 0; j < profiles; j++) {
170 snprintf(pipe_name, sizeof(pipe_name),
171 "pipe profile %" PRId32, j);
173 entry = rte_cfgfile_get_entry(file, pipe_name, "tb rate");
175 pipe_params[j].tb_rate = (uint32_t) atoi(entry);
177 entry = rte_cfgfile_get_entry(file, pipe_name, "tb size");
179 pipe_params[j].tb_size = (uint32_t) atoi(entry);
181 entry = rte_cfgfile_get_entry(file, pipe_name, "tc period");
183 pipe_params[j].tc_period = (uint32_t) atoi(entry);
185 entry = rte_cfgfile_get_entry(file, pipe_name, "tc 0 rate");
187 pipe_params[j].tc_rate[0] = (uint32_t) atoi(entry);
189 entry = rte_cfgfile_get_entry(file, pipe_name, "tc 1 rate");
191 pipe_params[j].tc_rate[1] = (uint32_t) atoi(entry);
193 entry = rte_cfgfile_get_entry(file, pipe_name, "tc 2 rate");
195 pipe_params[j].tc_rate[2] = (uint32_t) atoi(entry);
197 entry = rte_cfgfile_get_entry(file, pipe_name, "tc 3 rate");
199 pipe_params[j].tc_rate[3] = (uint32_t) atoi(entry);
201 #ifdef RTE_SCHED_SUBPORT_TC_OV
202 entry = rte_cfgfile_get_entry(file, pipe_name,
203 "tc 3 oversubscription weight");
205 pipe_params[j].tc_ov_weight = (uint8_t)atoi(entry);
208 entry = rte_cfgfile_get_entry(file,
212 for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) {
213 pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*0 + i] =
214 (uint8_t) strtol(entry, &next, 10);
220 entry = rte_cfgfile_get_entry(file, pipe_name, "tc 1 wrr weights");
222 for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) {
223 pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*1 + i] =
224 (uint8_t) strtol(entry, &next, 10);
230 entry = rte_cfgfile_get_entry(file, pipe_name, "tc 2 wrr weights");
232 for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) {
233 pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*2 + i] =
234 (uint8_t) strtol(entry, &next, 10);
240 entry = rte_cfgfile_get_entry(file, pipe_name, "tc 3 wrr weights");
242 for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) {
243 pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*3 + i] =
244 (uint8_t) strtol(entry, &next, 10);
254 tm_cfgfile_load_sched_subport(
255 struct rte_cfgfile *file,
256 struct rte_sched_subport_params *subport_params,
257 int *pipe_to_profile)
262 for (i = 0; i < APP_MAX_SCHED_SUBPORTS; i++) {
263 char sec_name[CFG_NAME_LEN];
265 snprintf(sec_name, sizeof(sec_name),
266 "subport %" PRId32, i);
268 if (rte_cfgfile_has_section(file, sec_name)) {
269 entry = rte_cfgfile_get_entry(file,
273 subport_params[i].tb_rate =
274 (uint32_t) atoi(entry);
276 entry = rte_cfgfile_get_entry(file,
280 subport_params[i].tb_size =
281 (uint32_t) atoi(entry);
283 entry = rte_cfgfile_get_entry(file,
287 subport_params[i].tc_period =
288 (uint32_t) atoi(entry);
290 entry = rte_cfgfile_get_entry(file,
294 subport_params[i].tc_rate[0] =
295 (uint32_t) atoi(entry);
297 entry = rte_cfgfile_get_entry(file,
301 subport_params[i].tc_rate[1] =
302 (uint32_t) atoi(entry);
304 entry = rte_cfgfile_get_entry(file,
308 subport_params[i].tc_rate[2] =
309 (uint32_t) atoi(entry);
311 entry = rte_cfgfile_get_entry(file,
315 subport_params[i].tc_rate[3] =
316 (uint32_t) atoi(entry);
318 int n_entries = rte_cfgfile_section_num_entries(file,
320 struct rte_cfgfile_entry entries[n_entries];
322 rte_cfgfile_section_entries(file,
327 for (j = 0; j < n_entries; j++)
330 sizeof("pipe") - 1) == 0) {
332 char *tokens[2] = {NULL, NULL};
335 char name[CFG_NAME_LEN + 1];
337 profile = atoi(entries[j].value);
341 n_tokens = rte_strsplit(
342 &name[sizeof("pipe")],
343 strnlen(name, CFG_NAME_LEN),
346 begin = atoi(tokens[0]);
348 end = atoi(tokens[1]);
352 if ((end >= APP_MAX_SCHED_PIPES) ||
356 for (k = begin; k <= end; k++) {
357 char profile_name[CFG_NAME_LEN];
359 snprintf(profile_name,
360 sizeof(profile_name),
361 "pipe profile %" PRId32,
363 if (rte_cfgfile_has_section(file, profile_name))
364 pipe_to_profile[i * APP_MAX_SCHED_PIPES + k] = profile;
366 rte_exit(EXIT_FAILURE,
367 "Wrong pipe profile %s\n",
378 tm_cfgfile_load(struct app_pktq_tm_params *tm)
380 struct rte_cfgfile *file;
383 memset(tm->sched_subport_params, 0, sizeof(tm->sched_subport_params));
384 memset(tm->sched_pipe_profiles, 0, sizeof(tm->sched_pipe_profiles));
385 memset(&tm->sched_port_params, 0, sizeof(tm->sched_port_params));
386 for (i = 0; i < APP_MAX_SCHED_SUBPORTS * APP_MAX_SCHED_PIPES; i++)
387 tm->sched_pipe_to_profile[i] = -1;
389 tm->sched_port_params.pipe_profiles = &tm->sched_pipe_profiles[0];
391 if (tm->file_name[0] == '\0')
394 file = rte_cfgfile_load(tm->file_name, 0);
398 tm_cfgfile_load_sched_port(file,
399 &tm->sched_port_params);
400 tm_cfgfile_load_sched_subport(file,
401 tm->sched_subport_params,
402 tm->sched_pipe_to_profile);
403 tm_cfgfile_load_sched_pipe(file,
404 &tm->sched_port_params,
405 tm->sched_pipe_profiles);
407 rte_cfgfile_close(file);
412 app_config_parse_tm(struct app_params *app)
416 for (i = 0; i < RTE_DIM(app->tm_params); i++) {
417 struct app_pktq_tm_params *p = &app->tm_params[i];
420 if (!APP_PARAM_VALID(p))
423 status = tm_cfgfile_load(p);
424 APP_CHECK(status == 0,
425 "Parse error for %s configuration file \"%s\"\n",