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
 232#ifdef RTE_SCHED_CMAN
 233void set_subport_cman_params(struct rte_sched_subport_params *subport_p,
 234                                        struct rte_sched_cman_params cman_p)
 235{
 236        int j, k;
 237        subport_p->cman_params->cman_mode = cman_p.cman_mode;
 238
 239        for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) {
 240                if (subport_p->cman_params->cman_mode ==
 241                                        RTE_SCHED_CMAN_RED) {
 242                        for (k = 0; k < RTE_COLORS; k++) {
 243                                subport_p->cman_params->red_params[j][k].min_th =
 244                                        cman_p.red_params[j][k].min_th;
 245                                subport_p->cman_params->red_params[j][k].max_th =
 246                                        cman_p.red_params[j][k].max_th;
 247                                subport_p->cman_params->red_params[j][k].maxp_inv =
 248                                        cman_p.red_params[j][k].maxp_inv;
 249                                subport_p->cman_params->red_params[j][k].wq_log2 =
 250                                        cman_p.red_params[j][k].wq_log2;
 251                        }
 252                } else {
 253                        subport_p->cman_params->pie_params[j].qdelay_ref =
 254                                cman_p.pie_params[j].qdelay_ref;
 255                        subport_p->cman_params->pie_params[j].dp_update_interval =
 256                                cman_p.pie_params[j].dp_update_interval;
 257                        subport_p->cman_params->pie_params[j].max_burst =
 258                                cman_p.pie_params[j].max_burst;
 259                        subport_p->cman_params->pie_params[j].tailq_th =
 260                                cman_p.pie_params[j].tailq_th;
 261                }
 262        }
 263}
 264#endif
 265
 266int
 267cfg_load_subport(struct rte_cfgfile *cfg, struct rte_sched_subport_params *subport_params)
 268{
 269        const char *entry;
 270        int i, j, k;
 271
 272        if (!cfg || !subport_params)
 273                return -1;
 274
 275        memset(app_pipe_to_profile, -1, sizeof(app_pipe_to_profile));
 276        memset(active_queues, 0, sizeof(active_queues));
 277        n_active_queues = 0;
 278
 279#ifdef RTE_SCHED_CMAN
 280        struct rte_sched_cman_params cman_params = {
 281                .cman_mode = RTE_SCHED_CMAN_RED,
 282                .red_params = { },
 283        };
 284
 285        if (rte_cfgfile_has_section(cfg, "red")) {
 286                cman_params.cman_mode = RTE_SCHED_CMAN_RED;
 287
 288                for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) {
 289                        char str[32];
 290
 291                        /* Parse RED min thresholds */
 292                        snprintf(str, sizeof(str), "tc %d red min", i);
 293                        entry = rte_cfgfile_get_entry(cfg, "red", str);
 294                        if (entry) {
 295                                char *next;
 296                                /* for each packet colour (green, yellow, red) */
 297                                for (j = 0; j < RTE_COLORS; j++) {
 298                                        cman_params.red_params[i][j].min_th
 299                                                = (uint16_t)strtol(entry, &next, 10);
 300                                        if (next == NULL)
 301                                                break;
 302                                        entry = next;
 303                                }
 304                        }
 305
 306                        /* Parse RED max thresholds */
 307                        snprintf(str, sizeof(str), "tc %d red max", i);
 308                        entry = rte_cfgfile_get_entry(cfg, "red", str);
 309                        if (entry) {
 310                                char *next;
 311                                /* for each packet colour (green, yellow, red) */
 312                                for (j = 0; j < RTE_COLORS; j++) {
 313                                        cman_params.red_params[i][j].max_th
 314                                                = (uint16_t)strtol(entry, &next, 10);
 315                                        if (next == NULL)
 316                                                break;
 317                                        entry = next;
 318                                }
 319                        }
 320
 321                        /* Parse RED inverse mark probabilities */
 322                        snprintf(str, sizeof(str), "tc %d red inv prob", i);
 323                        entry = rte_cfgfile_get_entry(cfg, "red", str);
 324                        if (entry) {
 325                                char *next;
 326                                /* for each packet colour (green, yellow, red) */
 327                                for (j = 0; j < RTE_COLORS; j++) {
 328                                        cman_params.red_params[i][j].maxp_inv
 329                                                = (uint8_t)strtol(entry, &next, 10);
 330
 331                                        if (next == NULL)
 332                                                break;
 333                                        entry = next;
 334                                }
 335                        }
 336
 337                        /* Parse RED EWMA filter weights */
 338                        snprintf(str, sizeof(str), "tc %d red weight", i);
 339                        entry = rte_cfgfile_get_entry(cfg, "red", str);
 340                        if (entry) {
 341                                char *next;
 342                                /* for each packet colour (green, yellow, red) */
 343                                for (j = 0; j < RTE_COLORS; j++) {
 344                                        cman_params.red_params[i][j].wq_log2
 345                                                = (uint8_t)strtol(entry, &next, 10);
 346                                        if (next == NULL)
 347                                                break;
 348                                        entry = next;
 349                                }
 350                        }
 351                }
 352        }
 353
 354        if (rte_cfgfile_has_section(cfg, "pie")) {
 355                cman_params.cman_mode = RTE_SCHED_CMAN_PIE;
 356
 357                for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) {
 358                        char str[32];
 359
 360                        /* Parse Queue Delay Ref value */
 361                        snprintf(str, sizeof(str), "tc %d qdelay ref", i);
 362                        entry = rte_cfgfile_get_entry(cfg, "pie", str);
 363                        if (entry)
 364                                cman_params.pie_params[i].qdelay_ref =
 365                                        (uint16_t) atoi(entry);
 366
 367                        /* Parse Max Burst value */
 368                        snprintf(str, sizeof(str), "tc %d max burst", i);
 369                        entry = rte_cfgfile_get_entry(cfg, "pie", str);
 370                        if (entry)
 371                                cman_params.pie_params[i].max_burst =
 372                                        (uint16_t) atoi(entry);
 373
 374                        /* Parse Update Interval Value */
 375                        snprintf(str, sizeof(str), "tc %d update interval", i);
 376                        entry = rte_cfgfile_get_entry(cfg, "pie", str);
 377                        if (entry)
 378                                cman_params.pie_params[i].dp_update_interval =
 379                                        (uint16_t) atoi(entry);
 380
 381                        /* Parse Tailq Threshold Value */
 382                        snprintf(str, sizeof(str), "tc %d tailq th", i);
 383                        entry = rte_cfgfile_get_entry(cfg, "pie", str);
 384                        if (entry)
 385                                cman_params.pie_params[i].tailq_th =
 386                                        (uint16_t) atoi(entry);
 387
 388                }
 389        }
 390#endif /* RTE_SCHED_CMAN */
 391
 392        for (i = 0; i < MAX_SCHED_SUBPORTS; i++) {
 393                char sec_name[CFG_NAME_LEN];
 394                snprintf(sec_name, sizeof(sec_name), "subport %d", i);
 395
 396                if (rte_cfgfile_has_section(cfg, sec_name)) {
 397                        entry = rte_cfgfile_get_entry(cfg, sec_name,
 398                                "number of pipes per subport");
 399                        if (entry)
 400                                subport_params[i].n_pipes_per_subport_enabled =
 401                                        (uint32_t)atoi(entry);
 402
 403                        entry = rte_cfgfile_get_entry(cfg, sec_name, "queue sizes");
 404                        if (entry) {
 405                                char *next;
 406
 407                                for (j = 0; j < RTE_SCHED_TRAFFIC_CLASS_BE; j++) {
 408                                        subport_params[i].qsize[j] =
 409                                                (uint16_t)strtol(entry, &next, 10);
 410                                        if (subport_params[i].qsize[j] != 0) {
 411                                                active_queues[n_active_queues] = j;
 412                                                n_active_queues++;
 413                                        }
 414                                        if (next == NULL)
 415                                                break;
 416                                        entry = next;
 417                                }
 418
 419                                subport_params[i].qsize[RTE_SCHED_TRAFFIC_CLASS_BE] =
 420                                        (uint16_t)strtol(entry, &next, 10);
 421
 422                                for (j = 0; j < RTE_SCHED_BE_QUEUES_PER_PIPE; j++) {
 423                                        active_queues[n_active_queues] =
 424                                                RTE_SCHED_TRAFFIC_CLASS_BE + j;
 425                                        n_active_queues++;
 426                                }
 427                        }
 428
 429                        int n_entries = rte_cfgfile_section_num_entries(cfg, sec_name);
 430                        struct rte_cfgfile_entry entries[n_entries];
 431
 432                        rte_cfgfile_section_entries(cfg, sec_name, entries, n_entries);
 433
 434                        for (j = 0; j < n_entries; j++) {
 435                                if (strncmp("pipe", entries[j].name, sizeof("pipe") - 1) == 0) {
 436                                        int profile;
 437                                        char *tokens[2] = {NULL, NULL};
 438                                        int n_tokens;
 439                                        int begin, end;
 440
 441                                        profile = atoi(entries[j].value);
 442                                        n_tokens = rte_strsplit(&entries[j].name[sizeof("pipe")],
 443                                                        strnlen(entries[j].name, CFG_NAME_LEN), tokens, 2, '-');
 444
 445                                        begin =  atoi(tokens[0]);
 446                                        if (n_tokens == 2)
 447                                                end = atoi(tokens[1]);
 448                                        else
 449                                                end = begin;
 450
 451                                        if (end >= MAX_SCHED_PIPES || begin > end)
 452                                                return -1;
 453
 454                                        for (k = begin; k <= end; k++) {
 455                                                char profile_name[CFG_NAME_LEN];
 456
 457                                                snprintf(profile_name, sizeof(profile_name),
 458                                                                "pipe profile %d", profile);
 459                                                if (rte_cfgfile_has_section(cfg, profile_name))
 460                                                        app_pipe_to_profile[i][k] = profile;
 461                                                else
 462                                                        rte_exit(EXIT_FAILURE, "Wrong pipe profile %s\n",
 463                                                                        entries[j].value);
 464
 465                                        }
 466                                }
 467                        }
 468#ifdef RTE_SCHED_CMAN
 469                        set_subport_cman_params(subport_params+i, cman_params);
 470#endif
 471                }
 472        }
 473
 474        return 0;
 475}
 476