dpdk/examples/qos_sched/cfg_file.c
<<
>>
Prefs
   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
  23uint32_t active_queues[RTE_SCHED_QUEUES_PER_PIPE];
  24uint32_t n_active_queues;
  25
  26int
  27cfg_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
  45int
  46cfg_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
 145int
 146cfg_load_subport_profile(struct rte_cfgfile *cfg,
 147        struct rte_sched_subport_profile_params *subport_profile)
 148{
 149        int i;
 150        const char *entry;
 151        int profiles;
 152
 153        if (!cfg || !subport_profile)
 154                return -1;
 155
 156        profiles = rte_cfgfile_num_sections(cfg, "subport profile",
 157                                           sizeof("subport profile") - 1);
 158        subport_params[0].n_pipe_profiles = profiles;
 159
 160        for (i = 0; i < profiles; i++) {
 161                char sec_name[32];
 162                snprintf(sec_name, sizeof(sec_name), "subport profile %d", i);
 163
 164                entry = rte_cfgfile_get_entry(cfg, sec_name, "tb rate");
 165                if (entry)
 166                        subport_profile[i].tb_rate = (uint64_t)atoi(entry);
 167
 168                entry = rte_cfgfile_get_entry(cfg, sec_name, "tb size");
 169                if (entry)
 170                        subport_profile[i].tb_size = (uint64_t)atoi(entry);
 171
 172                entry = rte_cfgfile_get_entry(cfg, sec_name, "tc period");
 173                if (entry)
 174                        subport_profile[i].tc_period = (uint64_t)atoi(entry);
 175
 176                entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 0 rate");
 177                if (entry)
 178                        subport_profile[i].tc_rate[0] = (uint64_t)atoi(entry);
 179
 180                entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 1 rate");
 181                if (entry)
 182                        subport_profile[i].tc_rate[1] = (uint64_t)atoi(entry);
 183
 184                entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 2 rate");
 185                if (entry)
 186                        subport_profile[i].tc_rate[2] = (uint64_t)atoi(entry);
 187
 188                entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 3 rate");
 189                if (entry)
 190                        subport_profile[i].tc_rate[3] = (uint64_t)atoi(entry);
 191
 192                entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 4 rate");
 193                if (entry)
 194                        subport_profile[i].tc_rate[4] = (uint64_t)atoi(entry);
 195
 196                entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 5 rate");
 197                if (entry)
 198                        subport_profile[i].tc_rate[5] = (uint64_t)atoi(entry);
 199
 200                entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 6 rate");
 201                if (entry)
 202                        subport_profile[i].tc_rate[6] = (uint64_t)atoi(entry);
 203
 204                entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 7 rate");
 205                if (entry)
 206                        subport_profile[i].tc_rate[7] = (uint64_t)atoi(entry);
 207
 208                entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 8 rate");
 209                if (entry)
 210                        subport_profile[i].tc_rate[8] = (uint64_t)atoi(entry);
 211
 212                entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 9 rate");
 213                if (entry)
 214                        subport_profile[i].tc_rate[9] = (uint64_t)atoi(entry);
 215
 216                entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 10 rate");
 217                if (entry)
 218                        subport_profile[i].tc_rate[10] = (uint64_t)atoi(entry);
 219
 220                entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 11 rate");
 221                if (entry)
 222                        subport_profile[i].tc_rate[11] = (uint64_t)atoi(entry);
 223
 224                entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 12 rate");
 225                if (entry)
 226                        subport_profile[i].tc_rate[12] = (uint64_t)atoi(entry);
 227        }
 228
 229        return 0;
 230}
 231
 232int
 233cfg_load_subport(struct rte_cfgfile *cfg, struct rte_sched_subport_params *subport_params)
 234{
 235        const char *entry;
 236        int i, j, k;
 237
 238        if (!cfg || !subport_params)
 239                return -1;
 240
 241        memset(app_pipe_to_profile, -1, sizeof(app_pipe_to_profile));
 242        memset(active_queues, 0, sizeof(active_queues));
 243        n_active_queues = 0;
 244
 245#ifdef RTE_SCHED_RED
 246        char sec_name[CFG_NAME_LEN];
 247        struct rte_red_params red_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS];
 248
 249        snprintf(sec_name, sizeof(sec_name), "red");
 250
 251        if (rte_cfgfile_has_section(cfg, sec_name)) {
 252
 253                for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) {
 254                        char str[32];
 255
 256                        /* Parse WRED min thresholds */
 257                        snprintf(str, sizeof(str), "tc %d wred min", i);
 258                        entry = rte_cfgfile_get_entry(cfg, sec_name, str);
 259                        if (entry) {
 260                                char *next;
 261                                /* for each packet colour (green, yellow, red) */
 262                                for (j = 0; j < RTE_COLORS; j++) {
 263                                        red_params[i][j].min_th
 264                                                = (uint16_t)strtol(entry, &next, 10);
 265                                        if (next == NULL)
 266                                                break;
 267                                        entry = next;
 268                                }
 269                        }
 270
 271                        /* Parse WRED max thresholds */
 272                        snprintf(str, sizeof(str), "tc %d wred max", i);
 273                        entry = rte_cfgfile_get_entry(cfg, "red", str);
 274                        if (entry) {
 275                                char *next;
 276                                /* for each packet colour (green, yellow, red) */
 277                                for (j = 0; j < RTE_COLORS; j++) {
 278                                        red_params[i][j].max_th
 279                                                = (uint16_t)strtol(entry, &next, 10);
 280                                        if (next == NULL)
 281                                                break;
 282                                        entry = next;
 283                                }
 284                        }
 285
 286                        /* Parse WRED inverse mark probabilities */
 287                        snprintf(str, sizeof(str), "tc %d wred inv prob", i);
 288                        entry = rte_cfgfile_get_entry(cfg, "red", str);
 289                        if (entry) {
 290                                char *next;
 291                                /* for each packet colour (green, yellow, red) */
 292                                for (j = 0; j < RTE_COLORS; j++) {
 293                                        red_params[i][j].maxp_inv
 294                                                = (uint8_t)strtol(entry, &next, 10);
 295
 296                                        if (next == NULL)
 297                                                break;
 298                                        entry = next;
 299                                }
 300                        }
 301
 302                        /* Parse WRED EWMA filter weights */
 303                        snprintf(str, sizeof(str), "tc %d wred weight", i);
 304                        entry = rte_cfgfile_get_entry(cfg, "red", str);
 305                        if (entry) {
 306                                char *next;
 307                                /* for each packet colour (green, yellow, red) */
 308                                for (j = 0; j < RTE_COLORS; j++) {
 309                                        red_params[i][j].wq_log2
 310                                                = (uint8_t)strtol(entry, &next, 10);
 311                                        if (next == NULL)
 312                                                break;
 313                                        entry = next;
 314                                }
 315                        }
 316                }
 317        }
 318#endif /* RTE_SCHED_RED */
 319
 320        for (i = 0; i < MAX_SCHED_SUBPORTS; i++) {
 321                char sec_name[CFG_NAME_LEN];
 322                snprintf(sec_name, sizeof(sec_name), "subport %d", i);
 323
 324                if (rte_cfgfile_has_section(cfg, sec_name)) {
 325                        entry = rte_cfgfile_get_entry(cfg, sec_name,
 326                                "number of pipes per subport");
 327                        if (entry)
 328                                subport_params[i].n_pipes_per_subport_enabled =
 329                                        (uint32_t)atoi(entry);
 330
 331                        entry = rte_cfgfile_get_entry(cfg, sec_name, "queue sizes");
 332                        if (entry) {
 333                                char *next;
 334
 335                                for (j = 0; j < RTE_SCHED_TRAFFIC_CLASS_BE; j++) {
 336                                        subport_params[i].qsize[j] =
 337                                                (uint16_t)strtol(entry, &next, 10);
 338                                        if (subport_params[i].qsize[j] != 0) {
 339                                                active_queues[n_active_queues] = j;
 340                                                n_active_queues++;
 341                                        }
 342                                        if (next == NULL)
 343                                                break;
 344                                        entry = next;
 345                                }
 346
 347                                subport_params[i].qsize[RTE_SCHED_TRAFFIC_CLASS_BE] =
 348                                        (uint16_t)strtol(entry, &next, 10);
 349
 350                                for (j = 0; j < RTE_SCHED_BE_QUEUES_PER_PIPE; j++) {
 351                                        active_queues[n_active_queues] =
 352                                                RTE_SCHED_TRAFFIC_CLASS_BE + j;
 353                                        n_active_queues++;
 354                                }
 355                        }
 356
 357                        int n_entries = rte_cfgfile_section_num_entries(cfg, sec_name);
 358                        struct rte_cfgfile_entry entries[n_entries];
 359
 360                        rte_cfgfile_section_entries(cfg, sec_name, entries, n_entries);
 361
 362                        for (j = 0; j < n_entries; j++) {
 363                                if (strncmp("pipe", entries[j].name, sizeof("pipe") - 1) == 0) {
 364                                        int profile;
 365                                        char *tokens[2] = {NULL, NULL};
 366                                        int n_tokens;
 367                                        int begin, end;
 368
 369                                        profile = atoi(entries[j].value);
 370                                        n_tokens = rte_strsplit(&entries[j].name[sizeof("pipe")],
 371                                                        strnlen(entries[j].name, CFG_NAME_LEN), tokens, 2, '-');
 372
 373                                        begin =  atoi(tokens[0]);
 374                                        if (n_tokens == 2)
 375                                                end = atoi(tokens[1]);
 376                                        else
 377                                                end = begin;
 378
 379                                        if (end >= MAX_SCHED_PIPES || begin > end)
 380                                                return -1;
 381
 382                                        for (k = begin; k <= end; k++) {
 383                                                char profile_name[CFG_NAME_LEN];
 384
 385                                                snprintf(profile_name, sizeof(profile_name),
 386                                                                "pipe profile %d", profile);
 387                                                if (rte_cfgfile_has_section(cfg, profile_name))
 388                                                        app_pipe_to_profile[i][k] = profile;
 389                                                else
 390                                                        rte_exit(EXIT_FAILURE, "Wrong pipe profile %s\n",
 391                                                                        entries[j].value);
 392
 393                                        }
 394                                }
 395                        }
 396#ifdef RTE_SCHED_RED
 397                        for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) {
 398                                for (k = 0; k < RTE_COLORS; k++) {
 399                                        subport_params[i].red_params[j][k].min_th =
 400                                                red_params[j][k].min_th;
 401                                        subport_params[i].red_params[j][k].max_th =
 402                                                red_params[j][k].max_th;
 403                                        subport_params[i].red_params[j][k].maxp_inv =
 404                                                red_params[j][k].maxp_inv;
 405                                        subport_params[i].red_params[j][k].wq_log2 =
 406                                                red_params[j][k].wq_log2;
 407                                }
 408                        }
 409#endif
 410                }
 411        }
 412
 413        return 0;
 414}
 415