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