4 * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 #include <rte_errno.h>
45 #include <rte_cfgfile.h>
46 #include <rte_string_fns.h>
51 tm_cfgfile_load_sched_port(
52 struct rte_cfgfile *file,
53 struct rte_sched_port_params *port_params)
58 entry = rte_cfgfile_get_entry(file, "port", "frame overhead");
60 port_params->frame_overhead = (uint32_t)atoi(entry);
62 entry = rte_cfgfile_get_entry(file, "port", "mtu");
64 port_params->mtu = (uint32_t)atoi(entry);
66 entry = rte_cfgfile_get_entry(file,
68 "number of subports per port");
70 port_params->n_subports_per_port = (uint32_t) atoi(entry);
72 entry = rte_cfgfile_get_entry(file,
74 "number of pipes per subport");
76 port_params->n_pipes_per_subport = (uint32_t) atoi(entry);
78 entry = rte_cfgfile_get_entry(file, "port", "queue sizes");
82 for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) {
83 port_params->qsize[j] = (uint16_t)
84 strtol(entry, &next, 10);
92 for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) {
95 /* Parse WRED min thresholds */
96 snprintf(str, sizeof(str), "tc %" PRId32 " wred min", 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].min_th
105 = (uint16_t)strtol(entry, &next, 10);
112 /* Parse WRED max thresholds */
113 snprintf(str, sizeof(str), "tc %" PRId32 " wred max", 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].max_th
122 = (uint16_t)strtol(entry, &next, 10);
129 /* Parse WRED inverse mark probabilities */
130 snprintf(str, sizeof(str), "tc %" PRId32 " wred inv prob", j);
131 entry = rte_cfgfile_get_entry(file, "red", str);
136 /* for each packet colour (green, yellow, red) */
137 for (k = 0; k < e_RTE_METER_COLORS; k++) {
138 port_params->red_params[j][k].maxp_inv
139 = (uint8_t)strtol(entry, &next, 10);
147 /* Parse WRED EWMA filter weights */
148 snprintf(str, sizeof(str), "tc %" PRId32 " wred weight", j);
149 entry = rte_cfgfile_get_entry(file, "red", str);
154 /* for each packet colour (green, yellow, red) */
155 for (k = 0; k < e_RTE_METER_COLORS; k++) {
156 port_params->red_params[j][k].wq_log2
157 = (uint8_t)strtol(entry, &next, 10);
164 #endif /* RTE_SCHED_RED */
170 tm_cfgfile_load_sched_pipe(
171 struct rte_cfgfile *file,
172 struct rte_sched_port_params *port_params,
173 struct rte_sched_pipe_params *pipe_params)
180 profiles = rte_cfgfile_num_sections(file,
181 "pipe profile", sizeof("pipe profile") - 1);
182 port_params->n_pipe_profiles = profiles;
184 for (j = 0; j < profiles; j++) {
187 snprintf(pipe_name, sizeof(pipe_name),
188 "pipe profile %" PRId32, j);
190 entry = rte_cfgfile_get_entry(file, pipe_name, "tb rate");
192 pipe_params[j].tb_rate = (uint32_t) atoi(entry);
194 entry = rte_cfgfile_get_entry(file, pipe_name, "tb size");
196 pipe_params[j].tb_size = (uint32_t) atoi(entry);
198 entry = rte_cfgfile_get_entry(file, pipe_name, "tc period");
200 pipe_params[j].tc_period = (uint32_t) atoi(entry);
202 entry = rte_cfgfile_get_entry(file, pipe_name, "tc 0 rate");
204 pipe_params[j].tc_rate[0] = (uint32_t) atoi(entry);
206 entry = rte_cfgfile_get_entry(file, pipe_name, "tc 1 rate");
208 pipe_params[j].tc_rate[1] = (uint32_t) atoi(entry);
210 entry = rte_cfgfile_get_entry(file, pipe_name, "tc 2 rate");
212 pipe_params[j].tc_rate[2] = (uint32_t) atoi(entry);
214 entry = rte_cfgfile_get_entry(file, pipe_name, "tc 3 rate");
216 pipe_params[j].tc_rate[3] = (uint32_t) atoi(entry);
218 #ifdef RTE_SCHED_SUBPORT_TC_OV
219 entry = rte_cfgfile_get_entry(file, pipe_name,
220 "tc 3 oversubscription weight");
222 pipe_params[j].tc_ov_weight = (uint8_t)atoi(entry);
225 entry = rte_cfgfile_get_entry(file,
229 for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) {
230 pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*0 + i] =
231 (uint8_t) strtol(entry, &next, 10);
237 entry = rte_cfgfile_get_entry(file, pipe_name, "tc 1 wrr weights");
239 for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) {
240 pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*1 + i] =
241 (uint8_t) strtol(entry, &next, 10);
247 entry = rte_cfgfile_get_entry(file, pipe_name, "tc 2 wrr weights");
249 for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) {
250 pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*2 + i] =
251 (uint8_t) strtol(entry, &next, 10);
257 entry = rte_cfgfile_get_entry(file, pipe_name, "tc 3 wrr weights");
259 for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) {
260 pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*3 + i] =
261 (uint8_t) strtol(entry, &next, 10);
271 tm_cfgfile_load_sched_subport(
272 struct rte_cfgfile *file,
273 struct rte_sched_subport_params *subport_params,
274 int *pipe_to_profile)
279 for (i = 0; i < APP_MAX_SCHED_SUBPORTS; i++) {
280 char sec_name[CFG_NAME_LEN];
282 snprintf(sec_name, sizeof(sec_name),
283 "subport %" PRId32, i);
285 if (rte_cfgfile_has_section(file, sec_name)) {
286 entry = rte_cfgfile_get_entry(file,
290 subport_params[i].tb_rate =
291 (uint32_t) atoi(entry);
293 entry = rte_cfgfile_get_entry(file,
297 subport_params[i].tb_size =
298 (uint32_t) atoi(entry);
300 entry = rte_cfgfile_get_entry(file,
304 subport_params[i].tc_period =
305 (uint32_t) atoi(entry);
307 entry = rte_cfgfile_get_entry(file,
311 subport_params[i].tc_rate[0] =
312 (uint32_t) atoi(entry);
314 entry = rte_cfgfile_get_entry(file,
318 subport_params[i].tc_rate[1] =
319 (uint32_t) atoi(entry);
321 entry = rte_cfgfile_get_entry(file,
325 subport_params[i].tc_rate[2] =
326 (uint32_t) atoi(entry);
328 entry = rte_cfgfile_get_entry(file,
332 subport_params[i].tc_rate[3] =
333 (uint32_t) atoi(entry);
335 int n_entries = rte_cfgfile_section_num_entries(file,
337 struct rte_cfgfile_entry entries[n_entries];
339 rte_cfgfile_section_entries(file,
344 for (j = 0; j < n_entries; j++)
347 sizeof("pipe") - 1) == 0) {
349 char *tokens[2] = {NULL, NULL};
352 char name[CFG_NAME_LEN];
354 profile = atoi(entries[j].value);
358 n_tokens = rte_strsplit(
359 &name[sizeof("pipe")],
360 strnlen(name, CFG_NAME_LEN),
363 begin = atoi(tokens[0]);
365 end = atoi(tokens[1]);
369 if ((end >= APP_MAX_SCHED_PIPES) ||
373 for (k = begin; k <= end; k++) {
374 char profile_name[CFG_NAME_LEN];
376 snprintf(profile_name,
377 sizeof(profile_name),
378 "pipe profile %" PRId32,
380 if (rte_cfgfile_has_section(file, profile_name))
381 pipe_to_profile[i * APP_MAX_SCHED_PIPES + k] = profile;
383 rte_exit(EXIT_FAILURE,
384 "Wrong pipe profile %s\n",
395 tm_cfgfile_load(struct app_pktq_tm_params *tm)
397 struct rte_cfgfile *file;
400 memset(tm->sched_subport_params, 0, sizeof(tm->sched_subport_params));
401 memset(tm->sched_pipe_profiles, 0, sizeof(tm->sched_pipe_profiles));
402 memset(&tm->sched_port_params, 0, sizeof(tm->sched_pipe_profiles));
403 for (i = 0; i < APP_MAX_SCHED_SUBPORTS * APP_MAX_SCHED_PIPES; i++)
404 tm->sched_pipe_to_profile[i] = -1;
406 tm->sched_port_params.pipe_profiles = &tm->sched_pipe_profiles[0];
408 if (tm->file_name[0] == '\0')
411 file = rte_cfgfile_load(tm->file_name, 0);
415 tm_cfgfile_load_sched_port(file,
416 &tm->sched_port_params);
417 tm_cfgfile_load_sched_subport(file,
418 tm->sched_subport_params,
419 tm->sched_pipe_to_profile);
420 tm_cfgfile_load_sched_pipe(file,
421 &tm->sched_port_params,
422 tm->sched_pipe_profiles);
424 rte_cfgfile_close(file);
429 app_config_parse_tm(struct app_params *app)
433 for (i = 0; i < RTE_DIM(app->tm_params); i++) {
434 struct app_pktq_tm_params *p = &app->tm_params[i];
437 if (!APP_PARAM_VALID(p))
440 status = tm_cfgfile_load(p);
441 APP_CHECK(status == 0,
442 "Parse error for %s configuration file \"%s\"\n",