13998e2a0SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 23998e2a0SBruce Richardson * Copyright(c) 2010-2014 Intel Corporation 3de3cfa2cSIntel */ 4de3cfa2cSIntel 5de3cfa2cSIntel #include <stdio.h> 6de3cfa2cSIntel #include <string.h> 7de3cfa2cSIntel #include <stdlib.h> 8de3cfa2cSIntel #include <stdint.h> 9de3cfa2cSIntel #include <locale.h> 10de3cfa2cSIntel #include <unistd.h> 11de3cfa2cSIntel #include <limits.h> 12de3cfa2cSIntel #include <getopt.h> 13de3cfa2cSIntel 14de3cfa2cSIntel #include <rte_log.h> 15de3cfa2cSIntel #include <rte_eal.h> 16de3cfa2cSIntel #include <rte_lcore.h> 17de3cfa2cSIntel #include <rte_string_fns.h> 18de3cfa2cSIntel 19de3cfa2cSIntel #include "main.h" 20de3cfa2cSIntel 21de3cfa2cSIntel #define APP_NAME "qos_sched" 22de3cfa2cSIntel #define MAX_OPT_VALUES 8 23de3cfa2cSIntel #define SYS_CPU_DIR "/sys/devices/system/cpu/cpu%u/topology/" 24de3cfa2cSIntel 25cb056611SStephen Hemminger static uint32_t app_main_core = 1; 26de3cfa2cSIntel static uint32_t app_numa_mask; 27de3cfa2cSIntel static uint64_t app_used_port_mask = 0; 28de3cfa2cSIntel static uint64_t app_used_rx_port_mask = 0; 29de3cfa2cSIntel static uint64_t app_used_tx_port_mask = 0; 30de3cfa2cSIntel 31de3cfa2cSIntel 32de3cfa2cSIntel static const char usage[] = 33de3cfa2cSIntel " \n" 34de3cfa2cSIntel " %s <APP PARAMS> \n" 35de3cfa2cSIntel " \n" 36de3cfa2cSIntel "Application mandatory parameters: \n" 37de3cfa2cSIntel " --pfc \"RX PORT, TX PORT, RX LCORE, WT LCORE\" : Packet flow configuration \n" 38de3cfa2cSIntel " multiple pfc can be configured in command line \n" 39de3cfa2cSIntel " \n" 40de3cfa2cSIntel "Application optional parameters: \n" 41fc48d8a5SIbtisam Tariq " -i : run in interactive mode (default value is %u) \n" 42cb056611SStephen Hemminger " --mnc I : main core index (default value is %u) \n" 43de3cfa2cSIntel " --rsz \"A, B, C\" : Ring sizes \n" 44de3cfa2cSIntel " A = Size (in number of buffer descriptors) of each of the NIC RX \n" 45de3cfa2cSIntel " rings read by the I/O RX lcores (default value is %u) \n" 46de3cfa2cSIntel " B = Size (in number of elements) of each of the SW rings used by the\n" 47de3cfa2cSIntel " I/O RX lcores to send packets to worker lcores (default value is\n" 48de3cfa2cSIntel " %u) \n" 49de3cfa2cSIntel " C = Size (in number of buffer descriptors) of each of the NIC TX \n" 50de3cfa2cSIntel " rings written by worker lcores (default value is %u) \n" 51de3cfa2cSIntel " --bsz \"A, B, C, D\": Burst sizes \n" 52de3cfa2cSIntel " A = I/O RX lcore read burst size from NIC RX (default value is %u) \n" 53de3cfa2cSIntel " B = I/O RX lcore write burst size to output SW rings, \n" 54de3cfa2cSIntel " Worker lcore read burst size from input SW rings, \n" 55de3cfa2cSIntel " QoS enqueue size (default value is %u) \n" 56de3cfa2cSIntel " C = QoS dequeue size (default value is %u) \n" 57de3cfa2cSIntel " D = Worker lcore write burst size to NIC TX (default value is %u) \n" 58e93b24a3SIntel " --msz M : Mempool size (in number of mbufs) for each pfc (default %u) \n" 59de3cfa2cSIntel " --rth \"A, B, C\" : RX queue threshold parameters \n" 60de3cfa2cSIntel " A = RX prefetch threshold (default value is %u) \n" 61de3cfa2cSIntel " B = RX host threshold (default value is %u) \n" 62de3cfa2cSIntel " C = RX write-back threshold (default value is %u) \n" 63de3cfa2cSIntel " --tth \"A, B, C\" : TX queue threshold parameters \n" 64de3cfa2cSIntel " A = TX prefetch threshold (default value is %u) \n" 65de3cfa2cSIntel " B = TX host threshold (default value is %u) \n" 66de3cfa2cSIntel " C = TX write-back threshold (default value is %u) \n" 67de3cfa2cSIntel " --cfg FILE : profile configuration to load \n" 68de3cfa2cSIntel ; 69de3cfa2cSIntel 70de3cfa2cSIntel /* display usage */ 71de3cfa2cSIntel static void 72de3cfa2cSIntel app_usage(const char *prgname) 73de3cfa2cSIntel { 74cb056611SStephen Hemminger printf(usage, prgname, APP_INTERACTIVE_DEFAULT, app_main_core, 75de3cfa2cSIntel APP_RX_DESC_DEFAULT, APP_RING_SIZE, APP_TX_DESC_DEFAULT, 76e93b24a3SIntel MAX_PKT_RX_BURST, PKT_ENQUEUE, PKT_DEQUEUE, 77e93b24a3SIntel MAX_PKT_TX_BURST, NB_MBUF, 78de3cfa2cSIntel RX_PTHRESH, RX_HTHRESH, RX_WTHRESH, 79de3cfa2cSIntel TX_PTHRESH, TX_HTHRESH, TX_WTHRESH 80de3cfa2cSIntel ); 81de3cfa2cSIntel } 82de3cfa2cSIntel 83de3cfa2cSIntel 84de3cfa2cSIntel 85de3cfa2cSIntel /* returns: 86de3cfa2cSIntel number of values parsed 87de3cfa2cSIntel -1 in case of error 88de3cfa2cSIntel */ 89de3cfa2cSIntel static int 90de3cfa2cSIntel app_parse_opt_vals(const char *conf_str, char separator, uint32_t n_vals, uint32_t *opt_vals) 91de3cfa2cSIntel { 92de3cfa2cSIntel char *string; 93cb923408SSlawomir Mrozowicz int i, n_tokens; 94de3cfa2cSIntel char *tokens[MAX_OPT_VALUES]; 95de3cfa2cSIntel 96de3cfa2cSIntel if (conf_str == NULL || opt_vals == NULL || n_vals == 0 || n_vals > MAX_OPT_VALUES) 97de3cfa2cSIntel return -1; 98de3cfa2cSIntel 99de3cfa2cSIntel /* duplicate configuration string before splitting it to tokens */ 100de3cfa2cSIntel string = strdup(conf_str); 101de3cfa2cSIntel if (string == NULL) 102de3cfa2cSIntel return -1; 103de3cfa2cSIntel 104de3cfa2cSIntel n_tokens = rte_strsplit(string, strnlen(string, 32), tokens, n_vals, separator); 105de3cfa2cSIntel 106db8aee15SChengwen Feng if (n_tokens > MAX_OPT_VALUES) { 107db8aee15SChengwen Feng free(string); 108035b6a4fSSlawomir Mrozowicz return -1; 109db8aee15SChengwen Feng } 110035b6a4fSSlawomir Mrozowicz 111035b6a4fSSlawomir Mrozowicz for (i = 0; i < n_tokens; i++) 112de3cfa2cSIntel opt_vals[i] = (uint32_t)atol(tokens[i]); 113de3cfa2cSIntel 114de3cfa2cSIntel free(string); 115de3cfa2cSIntel 116de3cfa2cSIntel return n_tokens; 117de3cfa2cSIntel } 118de3cfa2cSIntel 119de3cfa2cSIntel static int 120de3cfa2cSIntel app_parse_ring_conf(const char *conf_str) 121de3cfa2cSIntel { 122de3cfa2cSIntel int ret; 123de3cfa2cSIntel uint32_t vals[3]; 124de3cfa2cSIntel 125de3cfa2cSIntel ret = app_parse_opt_vals(conf_str, ',', 3, vals); 126de3cfa2cSIntel if (ret != 3) 127de3cfa2cSIntel return ret; 128de3cfa2cSIntel 129de3cfa2cSIntel ring_conf.rx_size = vals[0]; 130de3cfa2cSIntel ring_conf.ring_size = vals[1]; 131de3cfa2cSIntel ring_conf.tx_size = vals[2]; 132de3cfa2cSIntel 133de3cfa2cSIntel return 0; 134de3cfa2cSIntel } 135de3cfa2cSIntel 136de3cfa2cSIntel static int 137de3cfa2cSIntel app_parse_rth_conf(const char *conf_str) 138de3cfa2cSIntel { 139de3cfa2cSIntel int ret; 140de3cfa2cSIntel uint32_t vals[3]; 141de3cfa2cSIntel 142de3cfa2cSIntel ret = app_parse_opt_vals(conf_str, ',', 3, vals); 143de3cfa2cSIntel if (ret != 3) 144de3cfa2cSIntel return ret; 145de3cfa2cSIntel 146de3cfa2cSIntel rx_thresh.pthresh = (uint8_t)vals[0]; 147de3cfa2cSIntel rx_thresh.hthresh = (uint8_t)vals[1]; 148de3cfa2cSIntel rx_thresh.wthresh = (uint8_t)vals[2]; 149de3cfa2cSIntel 150de3cfa2cSIntel return 0; 151de3cfa2cSIntel } 152de3cfa2cSIntel 153de3cfa2cSIntel static int 154de3cfa2cSIntel app_parse_tth_conf(const char *conf_str) 155de3cfa2cSIntel { 156de3cfa2cSIntel int ret; 157de3cfa2cSIntel uint32_t vals[3]; 158de3cfa2cSIntel 159de3cfa2cSIntel ret = app_parse_opt_vals(conf_str, ',', 3, vals); 160de3cfa2cSIntel if (ret != 3) 161de3cfa2cSIntel return ret; 162de3cfa2cSIntel 163de3cfa2cSIntel tx_thresh.pthresh = (uint8_t)vals[0]; 164de3cfa2cSIntel tx_thresh.hthresh = (uint8_t)vals[1]; 165de3cfa2cSIntel tx_thresh.wthresh = (uint8_t)vals[2]; 166de3cfa2cSIntel 167de3cfa2cSIntel return 0; 168de3cfa2cSIntel } 169de3cfa2cSIntel 170de3cfa2cSIntel static int 171de3cfa2cSIntel app_parse_flow_conf(const char *conf_str) 172de3cfa2cSIntel { 173de3cfa2cSIntel int ret; 174de3cfa2cSIntel uint32_t vals[5]; 175de3cfa2cSIntel struct flow_conf *pconf; 176de3cfa2cSIntel uint64_t mask; 177de3cfa2cSIntel 17835f30466SJerin Jacob memset(vals, 0, sizeof(vals)); 179de3cfa2cSIntel ret = app_parse_opt_vals(conf_str, ',', 6, vals); 180de3cfa2cSIntel if (ret < 4 || ret > 5) 181de3cfa2cSIntel return ret; 182de3cfa2cSIntel 183de3cfa2cSIntel pconf = &qos_conf[nb_pfc]; 184de3cfa2cSIntel 185f8244c63SZhiyong Yang pconf->rx_port = vals[0]; 186f8244c63SZhiyong Yang pconf->tx_port = vals[1]; 187*4b978938SSivaprasad Tummala pconf->rx_core = vals[2]; 188*4b978938SSivaprasad Tummala pconf->wt_core = vals[3]; 189de3cfa2cSIntel if (ret == 5) 190*4b978938SSivaprasad Tummala pconf->tx_core = vals[4]; 191de3cfa2cSIntel else 192de3cfa2cSIntel pconf->tx_core = pconf->wt_core; 193de3cfa2cSIntel 194de3cfa2cSIntel if (pconf->rx_core == pconf->wt_core) { 195de3cfa2cSIntel RTE_LOG(ERR, APP, "pfc %u: rx thread and worker thread cannot share same core\n", nb_pfc); 196de3cfa2cSIntel return -1; 197de3cfa2cSIntel } 198de3cfa2cSIntel 199de3cfa2cSIntel if (pconf->rx_port >= RTE_MAX_ETHPORTS) { 200f8244c63SZhiyong Yang RTE_LOG(ERR, APP, "pfc %u: invalid rx port %"PRIu16" index\n", 201e8ed6c78SBruce Richardson nb_pfc, pconf->rx_port); 202de3cfa2cSIntel return -1; 203de3cfa2cSIntel } 204de3cfa2cSIntel if (pconf->tx_port >= RTE_MAX_ETHPORTS) { 205f8244c63SZhiyong Yang RTE_LOG(ERR, APP, "pfc %u: invalid tx port %"PRIu16" index\n", 206f2c41f26SSlawomir Mrozowicz nb_pfc, pconf->tx_port); 207de3cfa2cSIntel return -1; 208de3cfa2cSIntel } 209de3cfa2cSIntel 210de3cfa2cSIntel mask = 1lu << pconf->rx_port; 211de3cfa2cSIntel if (app_used_rx_port_mask & mask) { 212f8244c63SZhiyong Yang RTE_LOG(ERR, APP, "pfc %u: rx port %"PRIu16" is used already\n", 213e8ed6c78SBruce Richardson nb_pfc, pconf->rx_port); 214de3cfa2cSIntel return -1; 215de3cfa2cSIntel } 216de3cfa2cSIntel app_used_rx_port_mask |= mask; 217de3cfa2cSIntel app_used_port_mask |= mask; 218de3cfa2cSIntel 219de3cfa2cSIntel mask = 1lu << pconf->tx_port; 220de3cfa2cSIntel if (app_used_tx_port_mask & mask) { 221f8244c63SZhiyong Yang RTE_LOG(ERR, APP, "pfc %u: port %"PRIu16" is used already\n", 222e8ed6c78SBruce Richardson nb_pfc, pconf->tx_port); 223de3cfa2cSIntel return -1; 224de3cfa2cSIntel } 225de3cfa2cSIntel app_used_tx_port_mask |= mask; 226de3cfa2cSIntel app_used_port_mask |= mask; 227de3cfa2cSIntel 228de3cfa2cSIntel nb_pfc++; 229de3cfa2cSIntel 230de3cfa2cSIntel return 0; 231de3cfa2cSIntel } 232de3cfa2cSIntel 233de3cfa2cSIntel static int 234de3cfa2cSIntel app_parse_burst_conf(const char *conf_str) 235de3cfa2cSIntel { 236de3cfa2cSIntel int ret; 237de3cfa2cSIntel uint32_t vals[4]; 238de3cfa2cSIntel 239de3cfa2cSIntel ret = app_parse_opt_vals(conf_str, ',', 4, vals); 240de3cfa2cSIntel if (ret != 4) 241de3cfa2cSIntel return ret; 242de3cfa2cSIntel 243de3cfa2cSIntel burst_conf.rx_burst = (uint16_t)vals[0]; 244de3cfa2cSIntel burst_conf.ring_burst = (uint16_t)vals[1]; 245de3cfa2cSIntel burst_conf.qos_dequeue = (uint16_t)vals[2]; 246de3cfa2cSIntel burst_conf.tx_burst = (uint16_t)vals[3]; 247de3cfa2cSIntel 248de3cfa2cSIntel return 0; 249de3cfa2cSIntel } 250de3cfa2cSIntel 251a12daff4SIbtisam Tariq enum { 252a12daff4SIbtisam Tariq #define OPT_PFC "pfc" 253a12daff4SIbtisam Tariq OPT_PFC_NUM = 256, 254a12daff4SIbtisam Tariq #define OPT_MNC "mnc" 255a12daff4SIbtisam Tariq OPT_MNC_NUM, 256a12daff4SIbtisam Tariq #define OPT_RSZ "rsz" 257a12daff4SIbtisam Tariq OPT_RSZ_NUM, 258a12daff4SIbtisam Tariq #define OPT_BSZ "bsz" 259a12daff4SIbtisam Tariq OPT_BSZ_NUM, 260a12daff4SIbtisam Tariq #define OPT_MSZ "msz" 261a12daff4SIbtisam Tariq OPT_MSZ_NUM, 262a12daff4SIbtisam Tariq #define OPT_RTH "rth" 263a12daff4SIbtisam Tariq OPT_RTH_NUM, 264a12daff4SIbtisam Tariq #define OPT_TTH "tth" 265a12daff4SIbtisam Tariq OPT_TTH_NUM, 266a12daff4SIbtisam Tariq #define OPT_CFG "cfg" 267a12daff4SIbtisam Tariq OPT_CFG_NUM, 268a12daff4SIbtisam Tariq }; 269a12daff4SIbtisam Tariq 270de3cfa2cSIntel /* 271de3cfa2cSIntel * Parses the argument given in the command line of the application, 272de3cfa2cSIntel * calculates mask for used cores and initializes EAL with calculated core mask 273de3cfa2cSIntel */ 274de3cfa2cSIntel int 275de3cfa2cSIntel app_parse_args(int argc, char **argv) 276de3cfa2cSIntel { 277de3cfa2cSIntel int opt, ret; 278de3cfa2cSIntel int option_index; 279de3cfa2cSIntel char *prgname = argv[0]; 2804e43299dSBruce Richardson uint32_t i; 281de3cfa2cSIntel 282de3cfa2cSIntel static struct option lgopts[] = { 283a12daff4SIbtisam Tariq {OPT_PFC, 1, NULL, OPT_PFC_NUM}, 284a12daff4SIbtisam Tariq {OPT_MNC, 1, NULL, OPT_MNC_NUM}, 285a12daff4SIbtisam Tariq {OPT_RSZ, 1, NULL, OPT_RSZ_NUM}, 286a12daff4SIbtisam Tariq {OPT_BSZ, 1, NULL, OPT_BSZ_NUM}, 287a12daff4SIbtisam Tariq {OPT_MSZ, 1, NULL, OPT_MSZ_NUM}, 288a12daff4SIbtisam Tariq {OPT_RTH, 1, NULL, OPT_RTH_NUM}, 289a12daff4SIbtisam Tariq {OPT_TTH, 1, NULL, OPT_TTH_NUM}, 290a12daff4SIbtisam Tariq {OPT_CFG, 1, NULL, OPT_CFG_NUM}, 291de3cfa2cSIntel {NULL, 0, 0, 0 } 292de3cfa2cSIntel }; 293de3cfa2cSIntel 294de3cfa2cSIntel /* initialize EAL first */ 295de3cfa2cSIntel ret = rte_eal_init(argc, argv); 296de3cfa2cSIntel if (ret < 0) 297de3cfa2cSIntel return -1; 298de3cfa2cSIntel 299de3cfa2cSIntel argc -= ret; 300de3cfa2cSIntel argv += ret; 301de3cfa2cSIntel 302de3cfa2cSIntel /* set en_US locale to print big numbers with ',' */ 303de3cfa2cSIntel setlocale(LC_NUMERIC, "en_US.utf-8"); 304de3cfa2cSIntel 305cfd5c971SIntel while ((opt = getopt_long(argc, argv, "i", 306de3cfa2cSIntel lgopts, &option_index)) != EOF) { 307de3cfa2cSIntel 308de3cfa2cSIntel switch (opt) { 309cfd5c971SIntel case 'i': 310cfd5c971SIntel printf("Interactive-mode selected\n"); 311cfd5c971SIntel interactive = 1; 312cfd5c971SIntel break; 313de3cfa2cSIntel /* long options */ 314a12daff4SIbtisam Tariq 315a12daff4SIbtisam Tariq case OPT_PFC_NUM: 316de3cfa2cSIntel ret = app_parse_flow_conf(optarg); 317de3cfa2cSIntel if (ret) { 318a12daff4SIbtisam Tariq RTE_LOG(ERR, APP, "Invalid pipe configuration %s\n", 319a12daff4SIbtisam Tariq optarg); 320de3cfa2cSIntel return -1; 321de3cfa2cSIntel } 322de3cfa2cSIntel break; 323a12daff4SIbtisam Tariq 324a12daff4SIbtisam Tariq case OPT_MNC_NUM: 325cb056611SStephen Hemminger app_main_core = (uint32_t)atoi(optarg); 326de3cfa2cSIntel break; 327a12daff4SIbtisam Tariq 328a12daff4SIbtisam Tariq case OPT_RSZ_NUM: 329de3cfa2cSIntel ret = app_parse_ring_conf(optarg); 330de3cfa2cSIntel if (ret) { 331a12daff4SIbtisam Tariq RTE_LOG(ERR, APP, "Invalid ring configuration %s\n", 332a12daff4SIbtisam Tariq optarg); 333de3cfa2cSIntel return -1; 334de3cfa2cSIntel } 335de3cfa2cSIntel break; 336a12daff4SIbtisam Tariq 337a12daff4SIbtisam Tariq case OPT_BSZ_NUM: 338de3cfa2cSIntel ret = app_parse_burst_conf(optarg); 339de3cfa2cSIntel if (ret) { 340a12daff4SIbtisam Tariq RTE_LOG(ERR, APP, "Invalid burst configuration %s\n", 341a12daff4SIbtisam Tariq optarg); 342de3cfa2cSIntel return -1; 343de3cfa2cSIntel } 344de3cfa2cSIntel break; 345a12daff4SIbtisam Tariq 346a12daff4SIbtisam Tariq case OPT_MSZ_NUM: 347e93b24a3SIntel mp_size = atoi(optarg); 348e93b24a3SIntel if (mp_size <= 0) { 349a12daff4SIbtisam Tariq RTE_LOG(ERR, APP, "Invalid mempool size %s\n", 350a12daff4SIbtisam Tariq optarg); 351e93b24a3SIntel return -1; 352e93b24a3SIntel } 353e93b24a3SIntel break; 354a12daff4SIbtisam Tariq 355a12daff4SIbtisam Tariq case OPT_RTH_NUM: 356de3cfa2cSIntel ret = app_parse_rth_conf(optarg); 357de3cfa2cSIntel if (ret) { 358a12daff4SIbtisam Tariq RTE_LOG(ERR, APP, "Invalid RX threshold configuration %s\n", 359a12daff4SIbtisam Tariq optarg); 360de3cfa2cSIntel return -1; 361de3cfa2cSIntel } 362de3cfa2cSIntel break; 363a12daff4SIbtisam Tariq 364a12daff4SIbtisam Tariq case OPT_TTH_NUM: 365de3cfa2cSIntel ret = app_parse_tth_conf(optarg); 366de3cfa2cSIntel if (ret) { 367a12daff4SIbtisam Tariq RTE_LOG(ERR, APP, "Invalid TX threshold configuration %s\n", 368a12daff4SIbtisam Tariq optarg); 369de3cfa2cSIntel return -1; 370de3cfa2cSIntel } 371de3cfa2cSIntel break; 372a12daff4SIbtisam Tariq 373a12daff4SIbtisam Tariq case OPT_CFG_NUM: 374de3cfa2cSIntel cfg_profile = optarg; 375de3cfa2cSIntel break; 376de3cfa2cSIntel 377de3cfa2cSIntel default: 378de3cfa2cSIntel app_usage(prgname); 379de3cfa2cSIntel return -1; 380de3cfa2cSIntel } 381de3cfa2cSIntel } 382de3cfa2cSIntel 383de3cfa2cSIntel if (nb_pfc == 0) { 384de3cfa2cSIntel RTE_LOG(ERR, APP, "Packet flow not configured!\n"); 385de3cfa2cSIntel app_usage(prgname); 386de3cfa2cSIntel return -1; 387de3cfa2cSIntel } 388de3cfa2cSIntel 389de3cfa2cSIntel /* sanity check for cores assignment */ 390de3cfa2cSIntel for(i = 0; i < nb_pfc; i++) { 3914e43299dSBruce Richardson if (qos_conf[i].rx_core >= RTE_MAX_LCORE) { 392de3cfa2cSIntel RTE_LOG(ERR, APP, "pfc %u: invalid RX lcore index %u\n", i + 1, 393de3cfa2cSIntel qos_conf[i].rx_core); 394de3cfa2cSIntel return -1; 395de3cfa2cSIntel } 3964e43299dSBruce Richardson if (qos_conf[i].wt_core >= RTE_MAX_LCORE) { 397de3cfa2cSIntel RTE_LOG(ERR, APP, "pfc %u: invalid WT lcore index %u\n", i + 1, 398de3cfa2cSIntel qos_conf[i].wt_core); 399de3cfa2cSIntel return -1; 400de3cfa2cSIntel } 401de3cfa2cSIntel uint32_t rx_sock = rte_lcore_to_socket_id(qos_conf[i].rx_core); 402de3cfa2cSIntel uint32_t wt_sock = rte_lcore_to_socket_id(qos_conf[i].wt_core); 403de3cfa2cSIntel if (rx_sock != wt_sock) { 404de3cfa2cSIntel RTE_LOG(ERR, APP, "pfc %u: RX and WT must be on the same socket\n", i + 1); 405de3cfa2cSIntel return -1; 406de3cfa2cSIntel } 407de3cfa2cSIntel app_numa_mask |= 1 << rte_lcore_to_socket_id(qos_conf[i].rx_core); 408de3cfa2cSIntel } 409de3cfa2cSIntel 410de3cfa2cSIntel return 0; 411de3cfa2cSIntel } 412