5714c3f36d15e2a999c1ebc649ad520939238676
[dpdk.git] / examples / qos_sched / cfg_file.c
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 }