eal: add telemetry as dependency
[dpdk.git] / lib / librte_eal / common / eal_common_options.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation.
3  * Copyright(c) 2014 6WIND S.A.
4  */
5
6 #include <stdlib.h>
7 #include <unistd.h>
8 #include <string.h>
9 #ifndef RTE_EXEC_ENV_WINDOWS
10 #include <syslog.h>
11 #endif
12 #include <ctype.h>
13 #include <limits.h>
14 #include <errno.h>
15 #include <getopt.h>
16 #ifndef RTE_EXEC_ENV_WINDOWS
17 #include <dlfcn.h>
18 #endif
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <dirent.h>
22
23 #include <rte_string_fns.h>
24 #include <rte_eal.h>
25 #include <rte_log.h>
26 #include <rte_lcore.h>
27 #include <rte_memory.h>
28 #include <rte_tailq.h>
29 #include <rte_version.h>
30 #include <rte_devargs.h>
31 #include <rte_memcpy.h>
32
33 #include "eal_internal_cfg.h"
34 #include "eal_options.h"
35 #include "eal_filesystem.h"
36 #include "eal_private.h"
37 #ifndef RTE_EXEC_ENV_WINDOWS
38 #include "eal_trace.h"
39 #endif
40
41 #define BITS_PER_HEX 4
42 #define LCORE_OPT_LST 1
43 #define LCORE_OPT_MSK 2
44 #define LCORE_OPT_MAP 3
45
46 const char
47 eal_short_options[] =
48         "b:" /* pci-blacklist */
49         "c:" /* coremask */
50         "s:" /* service coremask */
51         "d:" /* driver */
52         "h"  /* help */
53         "l:" /* corelist */
54         "S:" /* service corelist */
55         "m:" /* memory size */
56         "n:" /* memory channels */
57         "r:" /* memory ranks */
58         "v"  /* version */
59         "w:" /* pci-whitelist */
60         ;
61
62 const struct option
63 eal_long_options[] = {
64         {OPT_BASE_VIRTADDR,     1, NULL, OPT_BASE_VIRTADDR_NUM    },
65         {OPT_CREATE_UIO_DEV,    0, NULL, OPT_CREATE_UIO_DEV_NUM   },
66         {OPT_FILE_PREFIX,       1, NULL, OPT_FILE_PREFIX_NUM      },
67         {OPT_HELP,              0, NULL, OPT_HELP_NUM             },
68         {OPT_HUGE_DIR,          1, NULL, OPT_HUGE_DIR_NUM         },
69         {OPT_HUGE_UNLINK,       0, NULL, OPT_HUGE_UNLINK_NUM      },
70         {OPT_IOVA_MODE,         1, NULL, OPT_IOVA_MODE_NUM        },
71         {OPT_LCORES,            1, NULL, OPT_LCORES_NUM           },
72         {OPT_LOG_LEVEL,         1, NULL, OPT_LOG_LEVEL_NUM        },
73         {OPT_TRACE,             1, NULL, OPT_TRACE_NUM            },
74         {OPT_TRACE_DIR,         1, NULL, OPT_TRACE_DIR_NUM        },
75         {OPT_TRACE_BUF_SIZE,    1, NULL, OPT_TRACE_BUF_SIZE_NUM   },
76         {OPT_TRACE_MODE,        1, NULL, OPT_TRACE_MODE_NUM       },
77         {OPT_MASTER_LCORE,      1, NULL, OPT_MASTER_LCORE_NUM     },
78         {OPT_MBUF_POOL_OPS_NAME, 1, NULL, OPT_MBUF_POOL_OPS_NAME_NUM},
79         {OPT_NO_HPET,           0, NULL, OPT_NO_HPET_NUM          },
80         {OPT_NO_HUGE,           0, NULL, OPT_NO_HUGE_NUM          },
81         {OPT_NO_PCI,            0, NULL, OPT_NO_PCI_NUM           },
82         {OPT_NO_SHCONF,         0, NULL, OPT_NO_SHCONF_NUM        },
83         {OPT_IN_MEMORY,         0, NULL, OPT_IN_MEMORY_NUM        },
84         {OPT_PCI_BLACKLIST,     1, NULL, OPT_PCI_BLACKLIST_NUM    },
85         {OPT_PCI_WHITELIST,     1, NULL, OPT_PCI_WHITELIST_NUM    },
86         {OPT_PROC_TYPE,         1, NULL, OPT_PROC_TYPE_NUM        },
87         {OPT_SOCKET_MEM,        1, NULL, OPT_SOCKET_MEM_NUM       },
88         {OPT_SOCKET_LIMIT,      1, NULL, OPT_SOCKET_LIMIT_NUM     },
89         {OPT_SYSLOG,            1, NULL, OPT_SYSLOG_NUM           },
90         {OPT_VDEV,              1, NULL, OPT_VDEV_NUM             },
91         {OPT_VFIO_INTR,         1, NULL, OPT_VFIO_INTR_NUM        },
92         {OPT_VMWARE_TSC_MAP,    0, NULL, OPT_VMWARE_TSC_MAP_NUM   },
93         {OPT_LEGACY_MEM,        0, NULL, OPT_LEGACY_MEM_NUM       },
94         {OPT_SINGLE_FILE_SEGMENTS, 0, NULL, OPT_SINGLE_FILE_SEGMENTS_NUM},
95         {OPT_MATCH_ALLOCATIONS, 0, NULL, OPT_MATCH_ALLOCATIONS_NUM},
96         {OPT_TELEMETRY,         0, NULL, OPT_TELEMETRY_NUM        },
97         {OPT_NO_TELEMETRY,      0, NULL, OPT_NO_TELEMETRY_NUM     },
98         {0,                     0, NULL, 0                        }
99 };
100
101 TAILQ_HEAD(shared_driver_list, shared_driver);
102
103 /* Definition for shared object drivers. */
104 struct shared_driver {
105         TAILQ_ENTRY(shared_driver) next;
106
107         char    name[PATH_MAX];
108         void*   lib_handle;
109 };
110
111 /* List of external loadable drivers */
112 static struct shared_driver_list solib_list =
113 TAILQ_HEAD_INITIALIZER(solib_list);
114
115 /* Default path of external loadable drivers */
116 static const char *default_solib_dir = RTE_EAL_PMD_PATH;
117
118 /*
119  * Stringified version of solib path used by dpdk-pmdinfo.py
120  * Note: PLEASE DO NOT ALTER THIS without making a corresponding
121  * change to usertools/dpdk-pmdinfo.py
122  */
123 static const char dpdk_solib_path[] __rte_used =
124 "DPDK_PLUGIN_PATH=" RTE_EAL_PMD_PATH;
125
126 TAILQ_HEAD(device_option_list, device_option);
127
128 struct device_option {
129         TAILQ_ENTRY(device_option) next;
130
131         enum rte_devtype type;
132         char arg[];
133 };
134
135 static struct device_option_list devopt_list =
136 TAILQ_HEAD_INITIALIZER(devopt_list);
137
138 static int master_lcore_parsed;
139 static int mem_parsed;
140 static int core_parsed;
141
142 static int
143 eal_option_device_add(enum rte_devtype type, const char *optarg)
144 {
145         struct device_option *devopt;
146         size_t optlen;
147         int ret;
148
149         optlen = strlen(optarg) + 1;
150         devopt = calloc(1, sizeof(*devopt) + optlen);
151         if (devopt == NULL) {
152                 RTE_LOG(ERR, EAL, "Unable to allocate device option\n");
153                 return -ENOMEM;
154         }
155
156         devopt->type = type;
157         ret = strlcpy(devopt->arg, optarg, optlen);
158         if (ret < 0) {
159                 RTE_LOG(ERR, EAL, "Unable to copy device option\n");
160                 free(devopt);
161                 return -EINVAL;
162         }
163         TAILQ_INSERT_TAIL(&devopt_list, devopt, next);
164         return 0;
165 }
166
167 int
168 eal_option_device_parse(void)
169 {
170         struct device_option *devopt;
171         void *tmp;
172         int ret = 0;
173
174         TAILQ_FOREACH_SAFE(devopt, &devopt_list, next, tmp) {
175                 if (ret == 0) {
176                         ret = rte_devargs_add(devopt->type, devopt->arg);
177                         if (ret)
178                                 RTE_LOG(ERR, EAL, "Unable to parse device '%s'\n",
179                                         devopt->arg);
180                 }
181                 TAILQ_REMOVE(&devopt_list, devopt, next);
182                 free(devopt);
183         }
184         return ret;
185 }
186
187 const char *
188 eal_get_hugefile_prefix(void)
189 {
190         if (internal_config.hugefile_prefix != NULL)
191                 return internal_config.hugefile_prefix;
192         return HUGEFILE_PREFIX_DEFAULT;
193 }
194
195 void
196 eal_reset_internal_config(struct internal_config *internal_cfg)
197 {
198         int i;
199
200         internal_cfg->memory = 0;
201         internal_cfg->force_nrank = 0;
202         internal_cfg->force_nchannel = 0;
203         internal_cfg->hugefile_prefix = NULL;
204         internal_cfg->hugepage_dir = NULL;
205         internal_cfg->force_sockets = 0;
206         /* zero out the NUMA config */
207         for (i = 0; i < RTE_MAX_NUMA_NODES; i++)
208                 internal_cfg->socket_mem[i] = 0;
209         internal_cfg->force_socket_limits = 0;
210         /* zero out the NUMA limits config */
211         for (i = 0; i < RTE_MAX_NUMA_NODES; i++)
212                 internal_cfg->socket_limit[i] = 0;
213         /* zero out hugedir descriptors */
214         for (i = 0; i < MAX_HUGEPAGE_SIZES; i++) {
215                 memset(&internal_cfg->hugepage_info[i], 0,
216                                 sizeof(internal_cfg->hugepage_info[0]));
217                 internal_cfg->hugepage_info[i].lock_descriptor = -1;
218         }
219         internal_cfg->base_virtaddr = 0;
220
221 #ifdef LOG_DAEMON
222         internal_cfg->syslog_facility = LOG_DAEMON;
223 #endif
224
225         /* if set to NONE, interrupt mode is determined automatically */
226         internal_cfg->vfio_intr_mode = RTE_INTR_MODE_NONE;
227
228 #ifdef RTE_LIBEAL_USE_HPET
229         internal_cfg->no_hpet = 0;
230 #else
231         internal_cfg->no_hpet = 1;
232 #endif
233         internal_cfg->vmware_tsc_map = 0;
234         internal_cfg->create_uio_dev = 0;
235         internal_cfg->iova_mode = RTE_IOVA_DC;
236         internal_cfg->user_mbuf_pool_ops_name = NULL;
237         CPU_ZERO(&internal_cfg->ctrl_cpuset);
238         internal_cfg->init_complete = 0;
239 }
240
241 static int
242 eal_plugin_add(const char *path)
243 {
244         struct shared_driver *solib;
245
246         solib = malloc(sizeof(*solib));
247         if (solib == NULL) {
248                 RTE_LOG(ERR, EAL, "malloc(solib) failed\n");
249                 return -1;
250         }
251         memset(solib, 0, sizeof(*solib));
252         strlcpy(solib->name, path, PATH_MAX-1);
253         solib->name[PATH_MAX-1] = 0;
254         TAILQ_INSERT_TAIL(&solib_list, solib, next);
255
256         return 0;
257 }
258
259 static int
260 eal_plugindir_init(const char *path)
261 {
262         DIR *d = NULL;
263         struct dirent *dent = NULL;
264         char sopath[PATH_MAX];
265
266         if (path == NULL || *path == '\0')
267                 return 0;
268
269         d = opendir(path);
270         if (d == NULL) {
271                 RTE_LOG(ERR, EAL, "failed to open directory %s: %s\n",
272                         path, strerror(errno));
273                 return -1;
274         }
275
276         while ((dent = readdir(d)) != NULL) {
277                 struct stat sb;
278
279                 snprintf(sopath, sizeof(sopath), "%s/%s", path, dent->d_name);
280
281                 if (!(stat(sopath, &sb) == 0 && S_ISREG(sb.st_mode)))
282                         continue;
283
284                 if (eal_plugin_add(sopath) == -1)
285                         break;
286         }
287
288         closedir(d);
289         /* XXX this ignores failures from readdir() itself */
290         return (dent == NULL) ? 0 : -1;
291 }
292
293 int
294 eal_plugins_init(void)
295 {
296 #ifndef RTE_EXEC_ENV_WINDOWS
297         struct shared_driver *solib = NULL;
298         struct stat sb;
299
300         if (*default_solib_dir != '\0' && stat(default_solib_dir, &sb) == 0 &&
301                                 S_ISDIR(sb.st_mode))
302                 eal_plugin_add(default_solib_dir);
303
304         TAILQ_FOREACH(solib, &solib_list, next) {
305
306                 if (stat(solib->name, &sb) == 0 && S_ISDIR(sb.st_mode)) {
307                         if (eal_plugindir_init(solib->name) == -1) {
308                                 RTE_LOG(ERR, EAL,
309                                         "Cannot init plugin directory %s\n",
310                                         solib->name);
311                                 return -1;
312                         }
313                 } else {
314                         RTE_LOG(DEBUG, EAL, "open shared lib %s\n",
315                                 solib->name);
316                         solib->lib_handle = dlopen(solib->name, RTLD_NOW);
317                         if (solib->lib_handle == NULL) {
318                                 RTE_LOG(ERR, EAL, "%s\n", dlerror());
319                                 return -1;
320                         }
321                 }
322
323         }
324         return 0;
325 #endif
326 }
327
328 /*
329  * Parse the coremask given as argument (hexadecimal string) and fill
330  * the global configuration (core role and core count) with the parsed
331  * value.
332  */
333 static int xdigit2val(unsigned char c)
334 {
335         int val;
336
337         if (isdigit(c))
338                 val = c - '0';
339         else if (isupper(c))
340                 val = c - 'A' + 10;
341         else
342                 val = c - 'a' + 10;
343         return val;
344 }
345
346 static int
347 eal_parse_service_coremask(const char *coremask)
348 {
349         struct rte_config *cfg = rte_eal_get_configuration();
350         int i, j, idx = 0;
351         unsigned int count = 0;
352         char c;
353         int val;
354         uint32_t taken_lcore_count = 0;
355
356         if (coremask == NULL)
357                 return -1;
358         /* Remove all blank characters ahead and after .
359          * Remove 0x/0X if exists.
360          */
361         while (isblank(*coremask))
362                 coremask++;
363         if (coremask[0] == '0' && ((coremask[1] == 'x')
364                 || (coremask[1] == 'X')))
365                 coremask += 2;
366         i = strlen(coremask);
367         while ((i > 0) && isblank(coremask[i - 1]))
368                 i--;
369
370         if (i == 0)
371                 return -1;
372
373         for (i = i - 1; i >= 0 && idx < RTE_MAX_LCORE; i--) {
374                 c = coremask[i];
375                 if (isxdigit(c) == 0) {
376                         /* invalid characters */
377                         return -1;
378                 }
379                 val = xdigit2val(c);
380                 for (j = 0; j < BITS_PER_HEX && idx < RTE_MAX_LCORE;
381                                 j++, idx++) {
382                         if ((1 << j) & val) {
383                                 /* handle master lcore already parsed */
384                                 uint32_t lcore = idx;
385                                 if (master_lcore_parsed &&
386                                                 cfg->master_lcore == lcore) {
387                                         RTE_LOG(ERR, EAL,
388                                                 "lcore %u is master lcore, cannot use as service core\n",
389                                                 idx);
390                                         return -1;
391                                 }
392
393                                 if (eal_cpu_detected(idx) == 0) {
394                                         RTE_LOG(ERR, EAL,
395                                                 "lcore %u unavailable\n", idx);
396                                         return -1;
397                                 }
398
399                                 if (cfg->lcore_role[idx] == ROLE_RTE)
400                                         taken_lcore_count++;
401
402                                 lcore_config[idx].core_role = ROLE_SERVICE;
403                                 count++;
404                         }
405                 }
406         }
407
408         for (; i >= 0; i--)
409                 if (coremask[i] != '0')
410                         return -1;
411
412         for (; idx < RTE_MAX_LCORE; idx++)
413                 lcore_config[idx].core_index = -1;
414
415         if (count == 0)
416                 return -1;
417
418         if (core_parsed && taken_lcore_count != count) {
419                 RTE_LOG(WARNING, EAL,
420                         "Not all service cores are in the coremask. "
421                         "Please ensure -c or -l includes service cores\n");
422         }
423
424         cfg->service_lcore_count = count;
425         return 0;
426 }
427
428 static int
429 eal_service_cores_parsed(void)
430 {
431         int idx;
432         for (idx = 0; idx < RTE_MAX_LCORE; idx++) {
433                 if (lcore_config[idx].core_role == ROLE_SERVICE)
434                         return 1;
435         }
436         return 0;
437 }
438
439 static int
440 update_lcore_config(int *cores)
441 {
442         struct rte_config *cfg = rte_eal_get_configuration();
443         unsigned int count = 0;
444         unsigned int i;
445         int ret = 0;
446
447         for (i = 0; i < RTE_MAX_LCORE; i++) {
448                 if (cores[i] != -1) {
449                         if (eal_cpu_detected(i) == 0) {
450                                 RTE_LOG(ERR, EAL, "lcore %u unavailable\n", i);
451                                 ret = -1;
452                                 continue;
453                         }
454                         cfg->lcore_role[i] = ROLE_RTE;
455                         count++;
456                 } else {
457                         cfg->lcore_role[i] = ROLE_OFF;
458                 }
459                 lcore_config[i].core_index = cores[i];
460         }
461         if (!ret)
462                 cfg->lcore_count = count;
463         return ret;
464 }
465
466 static int
467 eal_parse_coremask(const char *coremask, int *cores)
468 {
469         unsigned count = 0;
470         int i, j, idx;
471         int val;
472         char c;
473
474         for (idx = 0; idx < RTE_MAX_LCORE; idx++)
475                 cores[idx] = -1;
476         idx = 0;
477
478         /* Remove all blank characters ahead and after .
479          * Remove 0x/0X if exists.
480          */
481         while (isblank(*coremask))
482                 coremask++;
483         if (coremask[0] == '0' && ((coremask[1] == 'x')
484                 || (coremask[1] == 'X')))
485                 coremask += 2;
486         i = strlen(coremask);
487         while ((i > 0) && isblank(coremask[i - 1]))
488                 i--;
489         if (i == 0)
490                 return -1;
491
492         for (i = i - 1; i >= 0 && idx < RTE_MAX_LCORE; i--) {
493                 c = coremask[i];
494                 if (isxdigit(c) == 0) {
495                         /* invalid characters */
496                         return -1;
497                 }
498                 val = xdigit2val(c);
499                 for (j = 0; j < BITS_PER_HEX && idx < RTE_MAX_LCORE; j++, idx++)
500                 {
501                         if ((1 << j) & val) {
502                                 cores[idx] = count;
503                                 count++;
504                         }
505                 }
506         }
507         for (; i >= 0; i--)
508                 if (coremask[i] != '0')
509                         return -1;
510         if (count == 0)
511                 return -1;
512         return 0;
513 }
514
515 static int
516 eal_parse_service_corelist(const char *corelist)
517 {
518         struct rte_config *cfg = rte_eal_get_configuration();
519         int i, idx = 0;
520         unsigned count = 0;
521         char *end = NULL;
522         int min, max;
523         uint32_t taken_lcore_count = 0;
524
525         if (corelist == NULL)
526                 return -1;
527
528         /* Remove all blank characters ahead and after */
529         while (isblank(*corelist))
530                 corelist++;
531         i = strlen(corelist);
532         while ((i > 0) && isblank(corelist[i - 1]))
533                 i--;
534
535         /* Get list of cores */
536         min = RTE_MAX_LCORE;
537         do {
538                 while (isblank(*corelist))
539                         corelist++;
540                 if (*corelist == '\0')
541                         return -1;
542                 errno = 0;
543                 idx = strtoul(corelist, &end, 10);
544                 if (errno || end == NULL)
545                         return -1;
546                 while (isblank(*end))
547                         end++;
548                 if (*end == '-') {
549                         min = idx;
550                 } else if ((*end == ',') || (*end == '\0')) {
551                         max = idx;
552                         if (min == RTE_MAX_LCORE)
553                                 min = idx;
554                         for (idx = min; idx <= max; idx++) {
555                                 if (cfg->lcore_role[idx] != ROLE_SERVICE) {
556                                         /* handle master lcore already parsed */
557                                         uint32_t lcore = idx;
558                                         if (cfg->master_lcore == lcore &&
559                                                         master_lcore_parsed) {
560                                                 RTE_LOG(ERR, EAL,
561                                                         "Error: lcore %u is master lcore, cannot use as service core\n",
562                                                         idx);
563                                                 return -1;
564                                         }
565                                         if (cfg->lcore_role[idx] == ROLE_RTE)
566                                                 taken_lcore_count++;
567
568                                         lcore_config[idx].core_role =
569                                                         ROLE_SERVICE;
570                                         count++;
571                                 }
572                         }
573                         min = RTE_MAX_LCORE;
574                 } else
575                         return -1;
576                 corelist = end + 1;
577         } while (*end != '\0');
578
579         if (count == 0)
580                 return -1;
581
582         if (core_parsed && taken_lcore_count != count) {
583                 RTE_LOG(WARNING, EAL,
584                         "Not all service cores were in the coremask. "
585                         "Please ensure -c or -l includes service cores\n");
586         }
587
588         return 0;
589 }
590
591 static int
592 eal_parse_corelist(const char *corelist, int *cores)
593 {
594         unsigned count = 0;
595         char *end = NULL;
596         int min, max;
597         int idx;
598
599         for (idx = 0; idx < RTE_MAX_LCORE; idx++)
600                 cores[idx] = -1;
601
602         /* Remove all blank characters ahead */
603         while (isblank(*corelist))
604                 corelist++;
605
606         /* Get list of cores */
607         min = RTE_MAX_LCORE;
608         do {
609                 while (isblank(*corelist))
610                         corelist++;
611                 if (*corelist == '\0')
612                         return -1;
613                 errno = 0;
614                 idx = strtol(corelist, &end, 10);
615                 if (errno || end == NULL)
616                         return -1;
617                 if (idx < 0 || idx >= RTE_MAX_LCORE)
618                         return -1;
619                 while (isblank(*end))
620                         end++;
621                 if (*end == '-') {
622                         min = idx;
623                 } else if ((*end == ',') || (*end == '\0')) {
624                         max = idx;
625                         if (min == RTE_MAX_LCORE)
626                                 min = idx;
627                         for (idx = min; idx <= max; idx++) {
628                                 if (cores[idx] == -1) {
629                                         cores[idx] = count;
630                                         count++;
631                                 }
632                         }
633                         min = RTE_MAX_LCORE;
634                 } else
635                         return -1;
636                 corelist = end + 1;
637         } while (*end != '\0');
638
639         if (count == 0)
640                 return -1;
641         return 0;
642 }
643
644 /* Changes the lcore id of the master thread */
645 static int
646 eal_parse_master_lcore(const char *arg)
647 {
648         char *parsing_end;
649         struct rte_config *cfg = rte_eal_get_configuration();
650
651         errno = 0;
652         cfg->master_lcore = (uint32_t) strtol(arg, &parsing_end, 0);
653         if (errno || parsing_end[0] != 0)
654                 return -1;
655         if (cfg->master_lcore >= RTE_MAX_LCORE)
656                 return -1;
657         master_lcore_parsed = 1;
658
659         /* ensure master core is not used as service core */
660         if (lcore_config[cfg->master_lcore].core_role == ROLE_SERVICE) {
661                 RTE_LOG(ERR, EAL,
662                         "Error: Master lcore is used as a service core\n");
663                 return -1;
664         }
665
666         return 0;
667 }
668
669 /*
670  * Parse elem, the elem could be single number/range or '(' ')' group
671  * 1) A single number elem, it's just a simple digit. e.g. 9
672  * 2) A single range elem, two digits with a '-' between. e.g. 2-6
673  * 3) A group elem, combines multiple 1) or 2) with '( )'. e.g (0,2-4,6)
674  *    Within group elem, '-' used for a range separator;
675  *                       ',' used for a single number.
676  */
677 static int
678 eal_parse_set(const char *input, rte_cpuset_t *set)
679 {
680         unsigned idx;
681         const char *str = input;
682         char *end = NULL;
683         unsigned min, max;
684
685         CPU_ZERO(set);
686
687         while (isblank(*str))
688                 str++;
689
690         /* only digit or left bracket is qualify for start point */
691         if ((!isdigit(*str) && *str != '(') || *str == '\0')
692                 return -1;
693
694         /* process single number or single range of number */
695         if (*str != '(') {
696                 errno = 0;
697                 idx = strtoul(str, &end, 10);
698                 if (errno || end == NULL || idx >= CPU_SETSIZE)
699                         return -1;
700                 else {
701                         while (isblank(*end))
702                                 end++;
703
704                         min = idx;
705                         max = idx;
706                         if (*end == '-') {
707                                 /* process single <number>-<number> */
708                                 end++;
709                                 while (isblank(*end))
710                                         end++;
711                                 if (!isdigit(*end))
712                                         return -1;
713
714                                 errno = 0;
715                                 idx = strtoul(end, &end, 10);
716                                 if (errno || end == NULL || idx >= CPU_SETSIZE)
717                                         return -1;
718                                 max = idx;
719                                 while (isblank(*end))
720                                         end++;
721                                 if (*end != ',' && *end != '\0')
722                                         return -1;
723                         }
724
725                         if (*end != ',' && *end != '\0' &&
726                             *end != '@')
727                                 return -1;
728
729                         for (idx = RTE_MIN(min, max);
730                              idx <= RTE_MAX(min, max); idx++)
731                                 CPU_SET(idx, set);
732
733                         return end - input;
734                 }
735         }
736
737         /* process set within bracket */
738         str++;
739         while (isblank(*str))
740                 str++;
741         if (*str == '\0')
742                 return -1;
743
744         min = RTE_MAX_LCORE;
745         do {
746
747                 /* go ahead to the first digit */
748                 while (isblank(*str))
749                         str++;
750                 if (!isdigit(*str))
751                         return -1;
752
753                 /* get the digit value */
754                 errno = 0;
755                 idx = strtoul(str, &end, 10);
756                 if (errno || end == NULL || idx >= CPU_SETSIZE)
757                         return -1;
758
759                 /* go ahead to separator '-',',' and ')' */
760                 while (isblank(*end))
761                         end++;
762                 if (*end == '-') {
763                         if (min == RTE_MAX_LCORE)
764                                 min = idx;
765                         else /* avoid continuous '-' */
766                                 return -1;
767                 } else if ((*end == ',') || (*end == ')')) {
768                         max = idx;
769                         if (min == RTE_MAX_LCORE)
770                                 min = idx;
771                         for (idx = RTE_MIN(min, max);
772                              idx <= RTE_MAX(min, max); idx++)
773                                 CPU_SET(idx, set);
774
775                         min = RTE_MAX_LCORE;
776                 } else
777                         return -1;
778
779                 str = end + 1;
780         } while (*end != '\0' && *end != ')');
781
782         /*
783          * to avoid failure that tail blank makes end character check fail
784          * in eal_parse_lcores( )
785          */
786         while (isblank(*str))
787                 str++;
788
789         return str - input;
790 }
791
792 static int
793 check_cpuset(rte_cpuset_t *set)
794 {
795         unsigned int idx;
796
797         for (idx = 0; idx < CPU_SETSIZE; idx++) {
798                 if (!CPU_ISSET(idx, set))
799                         continue;
800
801                 if (eal_cpu_detected(idx) == 0) {
802                         RTE_LOG(ERR, EAL, "core %u "
803                                 "unavailable\n", idx);
804                         return -1;
805                 }
806         }
807         return 0;
808 }
809
810 /*
811  * The format pattern: --lcores='<lcores[@cpus]>[<,lcores[@cpus]>...]'
812  * lcores, cpus could be a single digit/range or a group.
813  * '(' and ')' are necessary if it's a group.
814  * If not supply '@cpus', the value of cpus uses the same as lcores.
815  * e.g. '1,2@(5-7),(3-5)@(0,2),(0,6),7-8' means start 9 EAL thread as below
816  *   lcore 0 runs on cpuset 0x41 (cpu 0,6)
817  *   lcore 1 runs on cpuset 0x2 (cpu 1)
818  *   lcore 2 runs on cpuset 0xe0 (cpu 5,6,7)
819  *   lcore 3,4,5 runs on cpuset 0x5 (cpu 0,2)
820  *   lcore 6 runs on cpuset 0x41 (cpu 0,6)
821  *   lcore 7 runs on cpuset 0x80 (cpu 7)
822  *   lcore 8 runs on cpuset 0x100 (cpu 8)
823  */
824 static int
825 eal_parse_lcores(const char *lcores)
826 {
827         struct rte_config *cfg = rte_eal_get_configuration();
828         rte_cpuset_t lcore_set;
829         unsigned int set_count;
830         unsigned idx = 0;
831         unsigned count = 0;
832         const char *lcore_start = NULL;
833         const char *end = NULL;
834         int offset;
835         rte_cpuset_t cpuset;
836         int lflags;
837         int ret = -1;
838
839         if (lcores == NULL)
840                 return -1;
841
842         /* Remove all blank characters ahead and after */
843         while (isblank(*lcores))
844                 lcores++;
845
846         CPU_ZERO(&cpuset);
847
848         /* Reset lcore config */
849         for (idx = 0; idx < RTE_MAX_LCORE; idx++) {
850                 cfg->lcore_role[idx] = ROLE_OFF;
851                 lcore_config[idx].core_index = -1;
852                 CPU_ZERO(&lcore_config[idx].cpuset);
853         }
854
855         /* Get list of cores */
856         do {
857                 while (isblank(*lcores))
858                         lcores++;
859                 if (*lcores == '\0')
860                         goto err;
861
862                 lflags = 0;
863
864                 /* record lcore_set start point */
865                 lcore_start = lcores;
866
867                 /* go across a complete bracket */
868                 if (*lcore_start == '(') {
869                         lcores += strcspn(lcores, ")");
870                         if (*lcores++ == '\0')
871                                 goto err;
872                 }
873
874                 /* scan the separator '@', ','(next) or '\0'(finish) */
875                 lcores += strcspn(lcores, "@,");
876
877                 if (*lcores == '@') {
878                         /* explicit assign cpuset and update the end cursor */
879                         offset = eal_parse_set(lcores + 1, &cpuset);
880                         if (offset < 0)
881                                 goto err;
882                         end = lcores + 1 + offset;
883                 } else { /* ',' or '\0' */
884                         /* haven't given cpuset, current loop done */
885                         end = lcores;
886
887                         /* go back to check <number>-<number> */
888                         offset = strcspn(lcore_start, "(-");
889                         if (offset < (end - lcore_start) &&
890                             *(lcore_start + offset) != '(')
891                                 lflags = 1;
892                 }
893
894                 if (*end != ',' && *end != '\0')
895                         goto err;
896
897                 /* parse lcore_set from start point */
898                 if (eal_parse_set(lcore_start, &lcore_set) < 0)
899                         goto err;
900
901                 /* without '@', by default using lcore_set as cpuset */
902                 if (*lcores != '@')
903                         rte_memcpy(&cpuset, &lcore_set, sizeof(cpuset));
904
905                 set_count = CPU_COUNT(&lcore_set);
906                 /* start to update lcore_set */
907                 for (idx = 0; idx < RTE_MAX_LCORE; idx++) {
908                         if (!CPU_ISSET(idx, &lcore_set))
909                                 continue;
910                         set_count--;
911
912                         if (cfg->lcore_role[idx] != ROLE_RTE) {
913                                 lcore_config[idx].core_index = count;
914                                 cfg->lcore_role[idx] = ROLE_RTE;
915                                 count++;
916                         }
917
918                         if (lflags) {
919                                 CPU_ZERO(&cpuset);
920                                 CPU_SET(idx, &cpuset);
921                         }
922
923                         if (check_cpuset(&cpuset) < 0)
924                                 goto err;
925                         rte_memcpy(&lcore_config[idx].cpuset, &cpuset,
926                                    sizeof(rte_cpuset_t));
927                 }
928
929                 /* some cores from the lcore_set can't be handled by EAL */
930                 if (set_count != 0)
931                         goto err;
932
933                 lcores = end + 1;
934         } while (*end != '\0');
935
936         if (count == 0)
937                 goto err;
938
939         cfg->lcore_count = count;
940         ret = 0;
941
942 err:
943
944         return ret;
945 }
946
947 #ifndef RTE_EXEC_ENV_WINDOWS
948 static int
949 eal_parse_syslog(const char *facility, struct internal_config *conf)
950 {
951         int i;
952         static const struct {
953                 const char *name;
954                 int value;
955         } map[] = {
956                 { "auth", LOG_AUTH },
957                 { "cron", LOG_CRON },
958                 { "daemon", LOG_DAEMON },
959                 { "ftp", LOG_FTP },
960                 { "kern", LOG_KERN },
961                 { "lpr", LOG_LPR },
962                 { "mail", LOG_MAIL },
963                 { "news", LOG_NEWS },
964                 { "syslog", LOG_SYSLOG },
965                 { "user", LOG_USER },
966                 { "uucp", LOG_UUCP },
967                 { "local0", LOG_LOCAL0 },
968                 { "local1", LOG_LOCAL1 },
969                 { "local2", LOG_LOCAL2 },
970                 { "local3", LOG_LOCAL3 },
971                 { "local4", LOG_LOCAL4 },
972                 { "local5", LOG_LOCAL5 },
973                 { "local6", LOG_LOCAL6 },
974                 { "local7", LOG_LOCAL7 },
975                 { NULL, 0 }
976         };
977
978         for (i = 0; map[i].name; i++) {
979                 if (!strcmp(facility, map[i].name)) {
980                         conf->syslog_facility = map[i].value;
981                         return 0;
982                 }
983         }
984         return -1;
985 }
986 #endif
987
988 static int
989 eal_parse_log_priority(const char *level)
990 {
991         static const char * const levels[] = {
992                 [RTE_LOG_EMERG]   = "emergency",
993                 [RTE_LOG_ALERT]   = "alert",
994                 [RTE_LOG_CRIT]    = "critical",
995                 [RTE_LOG_ERR]     = "error",
996                 [RTE_LOG_WARNING] = "warning",
997                 [RTE_LOG_NOTICE]  = "notice",
998                 [RTE_LOG_INFO]    = "info",
999                 [RTE_LOG_DEBUG]   = "debug",
1000         };
1001         size_t len = strlen(level);
1002         unsigned long tmp;
1003         char *end;
1004         unsigned int i;
1005
1006         if (len == 0)
1007                 return -1;
1008
1009         /* look for named values, skip 0 which is not a valid level */
1010         for (i = 1; i < RTE_DIM(levels); i++) {
1011                 if (strncmp(levels[i], level, len) == 0)
1012                         return i;
1013         }
1014
1015         /* not a string, maybe it is numeric */
1016         errno = 0;
1017         tmp = strtoul(level, &end, 0);
1018
1019         /* check for errors */
1020         if (errno != 0 || end == NULL || *end != '\0' ||
1021             tmp >= UINT32_MAX)
1022                 return -1;
1023
1024         return tmp;
1025 }
1026
1027 static int
1028 eal_parse_log_level(const char *arg)
1029 {
1030         const char *pattern = NULL;
1031         const char *regex = NULL;
1032         char *str, *level;
1033         int priority;
1034
1035         str = strdup(arg);
1036         if (str == NULL)
1037                 return -1;
1038
1039         if ((level = strchr(str, ','))) {
1040                 regex = str;
1041                 *level++ = '\0';
1042         } else if ((level = strchr(str, ':'))) {
1043                 pattern = str;
1044                 *level++ = '\0';
1045         } else {
1046                 level = str;
1047         }
1048
1049         priority = eal_parse_log_priority(level);
1050         if (priority < 0) {
1051                 fprintf(stderr, "invalid log priority: %s\n", level);
1052                 goto fail;
1053         }
1054
1055         if (regex) {
1056                 if (rte_log_set_level_regexp(regex, priority) < 0) {
1057                         fprintf(stderr, "cannot set log level %s,%d\n",
1058                                 regex, priority);
1059                         goto fail;
1060                 }
1061                 if (rte_log_save_regexp(regex, priority) < 0)
1062                         goto fail;
1063         } else if (pattern) {
1064                 if (rte_log_set_level_pattern(pattern, priority) < 0) {
1065                         fprintf(stderr, "cannot set log level %s:%d\n",
1066                                 pattern, priority);
1067                         goto fail;
1068                 }
1069                 if (rte_log_save_pattern(pattern, priority) < 0)
1070                         goto fail;
1071         } else {
1072                 rte_log_set_global_level(priority);
1073         }
1074
1075         free(str);
1076         return 0;
1077
1078 fail:
1079         free(str);
1080         return -1;
1081 }
1082
1083 static enum rte_proc_type_t
1084 eal_parse_proc_type(const char *arg)
1085 {
1086         if (strncasecmp(arg, "primary", sizeof("primary")) == 0)
1087                 return RTE_PROC_PRIMARY;
1088         if (strncasecmp(arg, "secondary", sizeof("secondary")) == 0)
1089                 return RTE_PROC_SECONDARY;
1090         if (strncasecmp(arg, "auto", sizeof("auto")) == 0)
1091                 return RTE_PROC_AUTO;
1092
1093         return RTE_PROC_INVALID;
1094 }
1095
1096 static int
1097 eal_parse_iova_mode(const char *name)
1098 {
1099         int mode;
1100
1101         if (name == NULL)
1102                 return -1;
1103
1104         if (!strcmp("pa", name))
1105                 mode = RTE_IOVA_PA;
1106         else if (!strcmp("va", name))
1107                 mode = RTE_IOVA_VA;
1108         else
1109                 return -1;
1110
1111         internal_config.iova_mode = mode;
1112         return 0;
1113 }
1114
1115 static int
1116 eal_parse_base_virtaddr(const char *arg)
1117 {
1118         char *end;
1119         uint64_t addr;
1120
1121         errno = 0;
1122         addr = strtoull(arg, &end, 16);
1123
1124         /* check for errors */
1125         if ((errno != 0) || (arg[0] == '\0') || end == NULL || (*end != '\0'))
1126                 return -1;
1127
1128         /* make sure we don't exceed 32-bit boundary on 32-bit target */
1129 #ifndef RTE_ARCH_64
1130         if (addr >= UINTPTR_MAX)
1131                 return -1;
1132 #endif
1133
1134         /* align the addr on 16M boundary, 16MB is the minimum huge page
1135          * size on IBM Power architecture. If the addr is aligned to 16MB,
1136          * it can align to 2MB for x86. So this alignment can also be used
1137          * on x86 and other architectures.
1138          */
1139         internal_config.base_virtaddr =
1140                 RTE_PTR_ALIGN_CEIL((uintptr_t)addr, (size_t)RTE_PGSIZE_16M);
1141
1142         return 0;
1143 }
1144
1145 /* caller is responsible for freeing the returned string */
1146 static char *
1147 available_cores(void)
1148 {
1149         char *str = NULL;
1150         int previous;
1151         int sequence;
1152         char *tmp;
1153         int idx;
1154
1155         /* find the first available cpu */
1156         for (idx = 0; idx < RTE_MAX_LCORE; idx++) {
1157                 if (eal_cpu_detected(idx) == 0)
1158                         continue;
1159                 break;
1160         }
1161         if (idx >= RTE_MAX_LCORE)
1162                 return NULL;
1163
1164         /* first sequence */
1165         if (asprintf(&str, "%d", idx) < 0)
1166                 return NULL;
1167         previous = idx;
1168         sequence = 0;
1169
1170         for (idx++ ; idx < RTE_MAX_LCORE; idx++) {
1171                 if (eal_cpu_detected(idx) == 0)
1172                         continue;
1173
1174                 if (idx == previous + 1) {
1175                         previous = idx;
1176                         sequence = 1;
1177                         continue;
1178                 }
1179
1180                 /* finish current sequence */
1181                 if (sequence) {
1182                         if (asprintf(&tmp, "%s-%d", str, previous) < 0) {
1183                                 free(str);
1184                                 return NULL;
1185                         }
1186                         free(str);
1187                         str = tmp;
1188                 }
1189
1190                 /* new sequence */
1191                 if (asprintf(&tmp, "%s,%d", str, idx) < 0) {
1192                         free(str);
1193                         return NULL;
1194                 }
1195                 free(str);
1196                 str = tmp;
1197                 previous = idx;
1198                 sequence = 0;
1199         }
1200
1201         /* finish last sequence */
1202         if (sequence) {
1203                 if (asprintf(&tmp, "%s-%d", str, previous) < 0) {
1204                         free(str);
1205                         return NULL;
1206                 }
1207                 free(str);
1208                 str = tmp;
1209         }
1210
1211         return str;
1212 }
1213
1214 int
1215 eal_parse_common_option(int opt, const char *optarg,
1216                         struct internal_config *conf)
1217 {
1218         static int b_used;
1219         static int w_used;
1220
1221         switch (opt) {
1222         /* blacklist */
1223         case 'b':
1224                 if (w_used)
1225                         goto bw_used;
1226                 if (eal_option_device_add(RTE_DEVTYPE_BLACKLISTED_PCI,
1227                                 optarg) < 0) {
1228                         return -1;
1229                 }
1230                 b_used = 1;
1231                 break;
1232         /* whitelist */
1233         case 'w':
1234                 if (b_used)
1235                         goto bw_used;
1236                 if (eal_option_device_add(RTE_DEVTYPE_WHITELISTED_PCI,
1237                                 optarg) < 0) {
1238                         return -1;
1239                 }
1240                 w_used = 1;
1241                 break;
1242         /* coremask */
1243         case 'c': {
1244                 int lcore_indexes[RTE_MAX_LCORE];
1245
1246                 if (eal_service_cores_parsed())
1247                         RTE_LOG(WARNING, EAL,
1248                                 "Service cores parsed before dataplane cores. Please ensure -c is before -s or -S\n");
1249                 if (eal_parse_coremask(optarg, lcore_indexes) < 0) {
1250                         RTE_LOG(ERR, EAL, "invalid coremask syntax\n");
1251                         return -1;
1252                 }
1253                 if (update_lcore_config(lcore_indexes) < 0) {
1254                         char *available = available_cores();
1255
1256                         RTE_LOG(ERR, EAL,
1257                                 "invalid coremask, please check specified cores are part of %s\n",
1258                                 available);
1259                         free(available);
1260                         return -1;
1261                 }
1262
1263                 if (core_parsed) {
1264                         RTE_LOG(ERR, EAL, "Option -c is ignored, because (%s) is set!\n",
1265                                 (core_parsed == LCORE_OPT_LST) ? "-l" :
1266                                 (core_parsed == LCORE_OPT_MAP) ? "--lcore" :
1267                                 "-c");
1268                         return -1;
1269                 }
1270
1271                 core_parsed = LCORE_OPT_MSK;
1272                 break;
1273         }
1274         /* corelist */
1275         case 'l': {
1276                 int lcore_indexes[RTE_MAX_LCORE];
1277
1278                 if (eal_service_cores_parsed())
1279                         RTE_LOG(WARNING, EAL,
1280                                 "Service cores parsed before dataplane cores. Please ensure -l is before -s or -S\n");
1281
1282                 if (eal_parse_corelist(optarg, lcore_indexes) < 0) {
1283                         RTE_LOG(ERR, EAL, "invalid core list syntax\n");
1284                         return -1;
1285                 }
1286                 if (update_lcore_config(lcore_indexes) < 0) {
1287                         char *available = available_cores();
1288
1289                         RTE_LOG(ERR, EAL,
1290                                 "invalid core list, please check specified cores are part of %s\n",
1291                                 available);
1292                         free(available);
1293                         return -1;
1294                 }
1295
1296                 if (core_parsed) {
1297                         RTE_LOG(ERR, EAL, "Option -l is ignored, because (%s) is set!\n",
1298                                 (core_parsed == LCORE_OPT_MSK) ? "-c" :
1299                                 (core_parsed == LCORE_OPT_MAP) ? "--lcore" :
1300                                 "-l");
1301                         return -1;
1302                 }
1303
1304                 core_parsed = LCORE_OPT_LST;
1305                 break;
1306         }
1307         /* service coremask */
1308         case 's':
1309                 if (eal_parse_service_coremask(optarg) < 0) {
1310                         RTE_LOG(ERR, EAL, "invalid service coremask\n");
1311                         return -1;
1312                 }
1313                 break;
1314         /* service corelist */
1315         case 'S':
1316                 if (eal_parse_service_corelist(optarg) < 0) {
1317                         RTE_LOG(ERR, EAL, "invalid service core list\n");
1318                         return -1;
1319                 }
1320                 break;
1321         /* size of memory */
1322         case 'm':
1323                 conf->memory = atoi(optarg);
1324                 conf->memory *= 1024ULL;
1325                 conf->memory *= 1024ULL;
1326                 mem_parsed = 1;
1327                 break;
1328         /* force number of channels */
1329         case 'n':
1330                 conf->force_nchannel = atoi(optarg);
1331                 if (conf->force_nchannel == 0) {
1332                         RTE_LOG(ERR, EAL, "invalid channel number\n");
1333                         return -1;
1334                 }
1335                 break;
1336         /* force number of ranks */
1337         case 'r':
1338                 conf->force_nrank = atoi(optarg);
1339                 if (conf->force_nrank == 0 ||
1340                     conf->force_nrank > 16) {
1341                         RTE_LOG(ERR, EAL, "invalid rank number\n");
1342                         return -1;
1343                 }
1344                 break;
1345         /* force loading of external driver */
1346         case 'd':
1347                 if (eal_plugin_add(optarg) == -1)
1348                         return -1;
1349                 break;
1350         case 'v':
1351                 /* since message is explicitly requested by user, we
1352                  * write message at highest log level so it can always
1353                  * be seen
1354                  * even if info or warning messages are disabled */
1355                 RTE_LOG(CRIT, EAL, "RTE Version: '%s'\n", rte_version());
1356                 break;
1357
1358         /* long options */
1359         case OPT_HUGE_UNLINK_NUM:
1360                 conf->hugepage_unlink = 1;
1361                 break;
1362
1363         case OPT_NO_HUGE_NUM:
1364                 conf->no_hugetlbfs = 1;
1365                 /* no-huge is legacy mem */
1366                 conf->legacy_mem = 1;
1367                 break;
1368
1369         case OPT_NO_PCI_NUM:
1370                 conf->no_pci = 1;
1371                 break;
1372
1373         case OPT_NO_HPET_NUM:
1374                 conf->no_hpet = 1;
1375                 break;
1376
1377         case OPT_VMWARE_TSC_MAP_NUM:
1378                 conf->vmware_tsc_map = 1;
1379                 break;
1380
1381         case OPT_NO_SHCONF_NUM:
1382                 conf->no_shconf = 1;
1383                 break;
1384
1385         case OPT_IN_MEMORY_NUM:
1386                 conf->in_memory = 1;
1387                 /* in-memory is a superset of noshconf and huge-unlink */
1388                 conf->no_shconf = 1;
1389                 conf->hugepage_unlink = 1;
1390                 break;
1391
1392         case OPT_PROC_TYPE_NUM:
1393                 conf->process_type = eal_parse_proc_type(optarg);
1394                 break;
1395
1396         case OPT_MASTER_LCORE_NUM:
1397                 if (eal_parse_master_lcore(optarg) < 0) {
1398                         RTE_LOG(ERR, EAL, "invalid parameter for --"
1399                                         OPT_MASTER_LCORE "\n");
1400                         return -1;
1401                 }
1402                 break;
1403
1404         case OPT_VDEV_NUM:
1405                 if (eal_option_device_add(RTE_DEVTYPE_VIRTUAL,
1406                                 optarg) < 0) {
1407                         return -1;
1408                 }
1409                 break;
1410
1411 #ifndef RTE_EXEC_ENV_WINDOWS
1412         case OPT_SYSLOG_NUM:
1413                 if (eal_parse_syslog(optarg, conf) < 0) {
1414                         RTE_LOG(ERR, EAL, "invalid parameters for --"
1415                                         OPT_SYSLOG "\n");
1416                         return -1;
1417                 }
1418                 break;
1419 #endif
1420
1421         case OPT_LOG_LEVEL_NUM: {
1422                 if (eal_parse_log_level(optarg) < 0) {
1423                         RTE_LOG(ERR, EAL,
1424                                 "invalid parameters for --"
1425                                 OPT_LOG_LEVEL "\n");
1426                         return -1;
1427                 }
1428                 break;
1429         }
1430
1431 #ifndef RTE_EXEC_ENV_WINDOWS
1432         case OPT_TRACE_NUM: {
1433                 if (eal_trace_args_save(optarg) < 0) {
1434                         RTE_LOG(ERR, EAL, "invalid parameters for --"
1435                                 OPT_TRACE "\n");
1436                         return -1;
1437                 }
1438                 break;
1439         }
1440
1441         case OPT_TRACE_DIR_NUM: {
1442                 if (eal_trace_dir_args_save(optarg) < 0) {
1443                         RTE_LOG(ERR, EAL, "invalid parameters for --"
1444                                 OPT_TRACE_DIR "\n");
1445                         return -1;
1446                 }
1447                 break;
1448         }
1449
1450         case OPT_TRACE_BUF_SIZE_NUM: {
1451                 if (eal_trace_bufsz_args_save(optarg) < 0) {
1452                         RTE_LOG(ERR, EAL, "invalid parameters for --"
1453                                 OPT_TRACE_BUF_SIZE "\n");
1454                         return -1;
1455                 }
1456                 break;
1457         }
1458
1459         case OPT_TRACE_MODE_NUM: {
1460                 if (eal_trace_mode_args_save(optarg) < 0) {
1461                         RTE_LOG(ERR, EAL, "invalid parameters for --"
1462                                 OPT_TRACE_MODE "\n");
1463                         return -1;
1464                 }
1465                 break;
1466         }
1467 #endif /* !RTE_EXEC_ENV_WINDOWS */
1468
1469         case OPT_LCORES_NUM:
1470                 if (eal_parse_lcores(optarg) < 0) {
1471                         RTE_LOG(ERR, EAL, "invalid parameter for --"
1472                                 OPT_LCORES "\n");
1473                         return -1;
1474                 }
1475
1476                 if (core_parsed) {
1477                         RTE_LOG(ERR, EAL, "Option --lcore is ignored, because (%s) is set!\n",
1478                                 (core_parsed == LCORE_OPT_LST) ? "-l" :
1479                                 (core_parsed == LCORE_OPT_MSK) ? "-c" :
1480                                 "--lcore");
1481                         return -1;
1482                 }
1483
1484                 core_parsed = LCORE_OPT_MAP;
1485                 break;
1486         case OPT_LEGACY_MEM_NUM:
1487                 conf->legacy_mem = 1;
1488                 break;
1489         case OPT_SINGLE_FILE_SEGMENTS_NUM:
1490                 conf->single_file_segments = 1;
1491                 break;
1492         case OPT_IOVA_MODE_NUM:
1493                 if (eal_parse_iova_mode(optarg) < 0) {
1494                         RTE_LOG(ERR, EAL, "invalid parameters for --"
1495                                 OPT_IOVA_MODE "\n");
1496                         return -1;
1497                 }
1498                 break;
1499         case OPT_BASE_VIRTADDR_NUM:
1500                 if (eal_parse_base_virtaddr(optarg) < 0) {
1501                         RTE_LOG(ERR, EAL, "invalid parameter for --"
1502                                         OPT_BASE_VIRTADDR "\n");
1503                         return -1;
1504                 }
1505                 break;
1506         case OPT_TELEMETRY_NUM:
1507                 break;
1508         case OPT_NO_TELEMETRY_NUM:
1509                 conf->no_telemetry = 1;
1510                 break;
1511
1512         /* don't know what to do, leave this to caller */
1513         default:
1514                 return 1;
1515
1516         }
1517
1518         return 0;
1519 bw_used:
1520         RTE_LOG(ERR, EAL, "Options blacklist (-b) and whitelist (-w) "
1521                 "cannot be used at the same time\n");
1522         return -1;
1523 }
1524
1525 static void
1526 eal_auto_detect_cores(struct rte_config *cfg)
1527 {
1528         unsigned int lcore_id;
1529         unsigned int removed = 0;
1530         rte_cpuset_t affinity_set;
1531
1532         if (pthread_getaffinity_np(pthread_self(), sizeof(rte_cpuset_t),
1533                                 &affinity_set))
1534                 CPU_ZERO(&affinity_set);
1535
1536         for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
1537                 if (cfg->lcore_role[lcore_id] == ROLE_RTE &&
1538                     !CPU_ISSET(lcore_id, &affinity_set)) {
1539                         cfg->lcore_role[lcore_id] = ROLE_OFF;
1540                         removed++;
1541                 }
1542         }
1543
1544         cfg->lcore_count -= removed;
1545 }
1546
1547 static void
1548 compute_ctrl_threads_cpuset(struct internal_config *internal_cfg)
1549 {
1550         rte_cpuset_t *cpuset = &internal_cfg->ctrl_cpuset;
1551         rte_cpuset_t default_set;
1552         unsigned int lcore_id;
1553
1554         for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
1555                 if (rte_lcore_has_role(lcore_id, ROLE_OFF))
1556                         continue;
1557                 RTE_CPU_OR(cpuset, cpuset, &lcore_config[lcore_id].cpuset);
1558         }
1559         RTE_CPU_NOT(cpuset, cpuset);
1560
1561         if (pthread_getaffinity_np(pthread_self(), sizeof(rte_cpuset_t),
1562                                 &default_set))
1563                 CPU_ZERO(&default_set);
1564
1565         RTE_CPU_AND(cpuset, cpuset, &default_set);
1566
1567         /* if no remaining cpu, use master lcore cpu affinity */
1568         if (!CPU_COUNT(cpuset)) {
1569                 memcpy(cpuset, &lcore_config[rte_get_master_lcore()].cpuset,
1570                         sizeof(*cpuset));
1571         }
1572 }
1573
1574 int
1575 eal_cleanup_config(struct internal_config *internal_cfg)
1576 {
1577         if (internal_cfg->hugefile_prefix != NULL)
1578                 free(internal_cfg->hugefile_prefix);
1579         if (internal_cfg->hugepage_dir != NULL)
1580                 free(internal_cfg->hugepage_dir);
1581         if (internal_cfg->user_mbuf_pool_ops_name != NULL)
1582                 free(internal_cfg->user_mbuf_pool_ops_name);
1583
1584         return 0;
1585 }
1586
1587 int
1588 eal_adjust_config(struct internal_config *internal_cfg)
1589 {
1590         int i;
1591         struct rte_config *cfg = rte_eal_get_configuration();
1592
1593         if (!core_parsed)
1594                 eal_auto_detect_cores(cfg);
1595
1596         if (internal_config.process_type == RTE_PROC_AUTO)
1597                 internal_config.process_type = eal_proc_type_detect();
1598
1599         /* default master lcore is the first one */
1600         if (!master_lcore_parsed) {
1601                 cfg->master_lcore = rte_get_next_lcore(-1, 0, 0);
1602                 if (cfg->master_lcore >= RTE_MAX_LCORE)
1603                         return -1;
1604                 lcore_config[cfg->master_lcore].core_role = ROLE_RTE;
1605         }
1606
1607         compute_ctrl_threads_cpuset(internal_cfg);
1608
1609         /* if no memory amounts were requested, this will result in 0 and
1610          * will be overridden later, right after eal_hugepage_info_init() */
1611         for (i = 0; i < RTE_MAX_NUMA_NODES; i++)
1612                 internal_cfg->memory += internal_cfg->socket_mem[i];
1613
1614         return 0;
1615 }
1616
1617 int
1618 eal_check_common_options(struct internal_config *internal_cfg)
1619 {
1620         struct rte_config *cfg = rte_eal_get_configuration();
1621
1622         if (cfg->lcore_role[cfg->master_lcore] != ROLE_RTE) {
1623                 RTE_LOG(ERR, EAL, "Master lcore is not enabled for DPDK\n");
1624                 return -1;
1625         }
1626
1627         if (internal_cfg->process_type == RTE_PROC_INVALID) {
1628                 RTE_LOG(ERR, EAL, "Invalid process type specified\n");
1629                 return -1;
1630         }
1631         if (internal_cfg->hugefile_prefix != NULL &&
1632                         strlen(internal_cfg->hugefile_prefix) < 1) {
1633                 RTE_LOG(ERR, EAL, "Invalid length of --" OPT_FILE_PREFIX " option\n");
1634                 return -1;
1635         }
1636         if (internal_cfg->hugepage_dir != NULL &&
1637                         strlen(internal_cfg->hugepage_dir) < 1) {
1638                 RTE_LOG(ERR, EAL, "Invalid length of --" OPT_HUGE_DIR" option\n");
1639                 return -1;
1640         }
1641         if (internal_cfg->user_mbuf_pool_ops_name != NULL &&
1642                         strlen(internal_cfg->user_mbuf_pool_ops_name) < 1) {
1643                 RTE_LOG(ERR, EAL, "Invalid length of --" OPT_MBUF_POOL_OPS_NAME" option\n");
1644                 return -1;
1645         }
1646         if (index(eal_get_hugefile_prefix(), '%') != NULL) {
1647                 RTE_LOG(ERR, EAL, "Invalid char, '%%', in --"OPT_FILE_PREFIX" "
1648                         "option\n");
1649                 return -1;
1650         }
1651         if (mem_parsed && internal_cfg->force_sockets == 1) {
1652                 RTE_LOG(ERR, EAL, "Options -m and --"OPT_SOCKET_MEM" cannot "
1653                         "be specified at the same time\n");
1654                 return -1;
1655         }
1656         if (internal_cfg->no_hugetlbfs && internal_cfg->force_sockets == 1) {
1657                 RTE_LOG(ERR, EAL, "Option --"OPT_SOCKET_MEM" cannot "
1658                         "be specified together with --"OPT_NO_HUGE"\n");
1659                 return -1;
1660         }
1661         if (internal_cfg->no_hugetlbfs && internal_cfg->hugepage_unlink &&
1662                         !internal_cfg->in_memory) {
1663                 RTE_LOG(ERR, EAL, "Option --"OPT_HUGE_UNLINK" cannot "
1664                         "be specified together with --"OPT_NO_HUGE"\n");
1665                 return -1;
1666         }
1667         if (internal_config.force_socket_limits && internal_config.legacy_mem) {
1668                 RTE_LOG(ERR, EAL, "Option --"OPT_SOCKET_LIMIT
1669                         " is only supported in non-legacy memory mode\n");
1670         }
1671         if (internal_cfg->single_file_segments &&
1672                         internal_cfg->hugepage_unlink &&
1673                         !internal_cfg->in_memory) {
1674                 RTE_LOG(ERR, EAL, "Option --"OPT_SINGLE_FILE_SEGMENTS" is "
1675                         "not compatible with --"OPT_HUGE_UNLINK"\n");
1676                 return -1;
1677         }
1678         if (internal_cfg->legacy_mem &&
1679                         internal_cfg->in_memory) {
1680                 RTE_LOG(ERR, EAL, "Option --"OPT_LEGACY_MEM" is not compatible "
1681                                 "with --"OPT_IN_MEMORY"\n");
1682                 return -1;
1683         }
1684         if (internal_cfg->legacy_mem && internal_cfg->match_allocations) {
1685                 RTE_LOG(ERR, EAL, "Option --"OPT_LEGACY_MEM" is not compatible "
1686                                 "with --"OPT_MATCH_ALLOCATIONS"\n");
1687                 return -1;
1688         }
1689         if (internal_cfg->no_hugetlbfs && internal_cfg->match_allocations) {
1690                 RTE_LOG(ERR, EAL, "Option --"OPT_NO_HUGE" is not compatible "
1691                                 "with --"OPT_MATCH_ALLOCATIONS"\n");
1692                 return -1;
1693         }
1694         if (internal_cfg->legacy_mem && internal_cfg->memory == 0) {
1695                 RTE_LOG(NOTICE, EAL, "Static memory layout is selected, "
1696                         "amount of reserved memory can be adjusted with "
1697                         "-m or --"OPT_SOCKET_MEM"\n");
1698         }
1699
1700         return 0;
1701 }
1702
1703 void
1704 eal_common_usage(void)
1705 {
1706         printf("[options]\n\n"
1707                "EAL common options:\n"
1708                "  -c COREMASK         Hexadecimal bitmask of cores to run on\n"
1709                "  -l CORELIST         List of cores to run on\n"
1710                "                      The argument format is <c1>[-c2][,c3[-c4],...]\n"
1711                "                      where c1, c2, etc are core indexes between 0 and %d\n"
1712                "  --"OPT_LCORES" COREMAP    Map lcore set to physical cpu set\n"
1713                "                      The argument format is\n"
1714                "                            '<lcores[@cpus]>[<,lcores[@cpus]>...]'\n"
1715                "                      lcores and cpus list are grouped by '(' and ')'\n"
1716                "                      Within the group, '-' is used for range separator,\n"
1717                "                      ',' is used for single number separator.\n"
1718                "                      '( )' can be omitted for single element group,\n"
1719                "                      '@' can be omitted if cpus and lcores have the same value\n"
1720                "  -s SERVICE COREMASK Hexadecimal bitmask of cores to be used as service cores\n"
1721                "  --"OPT_MASTER_LCORE" ID   Core ID that is used as master\n"
1722                "  --"OPT_MBUF_POOL_OPS_NAME" Pool ops name for mbuf to use\n"
1723                "  -n CHANNELS         Number of memory channels\n"
1724                "  -m MB               Memory to allocate (see also --"OPT_SOCKET_MEM")\n"
1725                "  -r RANKS            Force number of memory ranks (don't detect)\n"
1726                "  -b, --"OPT_PCI_BLACKLIST" Add a PCI device in black list.\n"
1727                "                      Prevent EAL from using this PCI device. The argument\n"
1728                "                      format is <domain:bus:devid.func>.\n"
1729                "  -w, --"OPT_PCI_WHITELIST" Add a PCI device in white list.\n"
1730                "                      Only use the specified PCI devices. The argument format\n"
1731                "                      is <[domain:]bus:devid.func>. This option can be present\n"
1732                "                      several times (once per device).\n"
1733                "                      [NOTE: PCI whitelist cannot be used with -b option]\n"
1734                "  --"OPT_VDEV"              Add a virtual device.\n"
1735                "                      The argument format is <driver><id>[,key=val,...]\n"
1736                "                      (ex: --vdev=net_pcap0,iface=eth2).\n"
1737                "  --"OPT_IOVA_MODE"   Set IOVA mode. 'pa' for IOVA_PA\n"
1738                "                      'va' for IOVA_VA\n"
1739                "  -d LIB.so|DIR       Add a driver or driver directory\n"
1740                "                      (can be used multiple times)\n"
1741                "  --"OPT_VMWARE_TSC_MAP"    Use VMware TSC map instead of native RDTSC\n"
1742                "  --"OPT_PROC_TYPE"         Type of this process (primary|secondary|auto)\n"
1743 #ifndef RTE_EXEC_ENV_WINDOWS
1744                "  --"OPT_SYSLOG"            Set syslog facility\n"
1745 #endif
1746                "  --"OPT_LOG_LEVEL"=<int>   Set global log level\n"
1747                "  --"OPT_LOG_LEVEL"=<type-match>:<int>\n"
1748                "                      Set specific log level\n"
1749 #ifndef RTE_EXEC_ENV_WINDOWS
1750                "  --"OPT_TRACE"=<regex-match>\n"
1751                "                      Enable trace based on regular expression trace name.\n"
1752                "                      By default, the trace is disabled.\n"
1753                "                      User must specify this option to enable trace.\n"
1754                "  --"OPT_TRACE_DIR"=<directory path>\n"
1755                "                      Specify trace directory for trace output.\n"
1756                "                      By default, trace output will created at\n"
1757                "                      $HOME directory and parameter must be\n"
1758                "                      specified once only.\n"
1759                "  --"OPT_TRACE_BUF_SIZE"=<int>\n"
1760                "                      Specify maximum size of allocated memory\n"
1761                "                      for trace output for each thread. Valid\n"
1762                "                      unit can be either 'B|K|M' for 'Bytes',\n"
1763                "                      'KBytes' and 'MBytes' respectively.\n"
1764                "                      Default is 1MB and parameter must be\n"
1765                "                      specified once only.\n"
1766                "  --"OPT_TRACE_MODE"=<o[verwrite] | d[iscard]>\n"
1767                "                      Specify the mode of update of trace\n"
1768                "                      output file. Either update on a file can\n"
1769                "                      be wrapped or discarded when file size\n"
1770                "                      reaches its maximum limit.\n"
1771                "                      Default mode is 'overwrite' and parameter\n"
1772                "                      must be specified once only.\n"
1773 #endif /* !RTE_EXEC_ENV_WINDOWS */
1774                "  -v                  Display version information on startup\n"
1775                "  -h, --help          This help\n"
1776                "  --"OPT_IN_MEMORY"   Operate entirely in memory. This will\n"
1777                "                      disable secondary process support\n"
1778                "  --"OPT_BASE_VIRTADDR"     Base virtual address\n"
1779                "  --"OPT_TELEMETRY"   Enable telemetry support (on by default)\n"
1780                "  --"OPT_NO_TELEMETRY"   Disable telemetry support\n"
1781                "\nEAL options for DEBUG use only:\n"
1782                "  --"OPT_HUGE_UNLINK"       Unlink hugepage files after init\n"
1783                "  --"OPT_NO_HUGE"           Use malloc instead of hugetlbfs\n"
1784                "  --"OPT_NO_PCI"            Disable PCI\n"
1785                "  --"OPT_NO_HPET"           Disable HPET\n"
1786                "  --"OPT_NO_SHCONF"         No shared config (mmap'd files)\n"
1787                "\n", RTE_MAX_LCORE);
1788         rte_option_usage();
1789 }