4 * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5 * Copyright(c) 2014 6WIND S.A.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 #include <sys/types.h>
49 #include <rte_lcore.h>
50 #include <rte_version.h>
51 #include <rte_devargs.h>
52 #include <rte_memcpy.h>
54 #include "eal_internal_cfg.h"
55 #include "eal_options.h"
56 #include "eal_filesystem.h"
58 #define BITS_PER_HEX 4
62 "b:" /* pci-blacklist */
67 "m:" /* memory size */
68 "n:" /* memory channels */
69 "r:" /* memory ranks */
71 "w:" /* pci-whitelist */
75 eal_long_options
[] = {
76 {OPT_BASE_VIRTADDR
, 1, NULL
, OPT_BASE_VIRTADDR_NUM
},
77 {OPT_CREATE_UIO_DEV
, 0, NULL
, OPT_CREATE_UIO_DEV_NUM
},
78 {OPT_FILE_PREFIX
, 1, NULL
, OPT_FILE_PREFIX_NUM
},
79 {OPT_HELP
, 0, NULL
, OPT_HELP_NUM
},
80 {OPT_HUGE_DIR
, 1, NULL
, OPT_HUGE_DIR_NUM
},
81 {OPT_HUGE_UNLINK
, 0, NULL
, OPT_HUGE_UNLINK_NUM
},
82 {OPT_LCORES
, 1, NULL
, OPT_LCORES_NUM
},
83 {OPT_LOG_LEVEL
, 1, NULL
, OPT_LOG_LEVEL_NUM
},
84 {OPT_MASTER_LCORE
, 1, NULL
, OPT_MASTER_LCORE_NUM
},
85 {OPT_NO_HPET
, 0, NULL
, OPT_NO_HPET_NUM
},
86 {OPT_NO_HUGE
, 0, NULL
, OPT_NO_HUGE_NUM
},
87 {OPT_NO_PCI
, 0, NULL
, OPT_NO_PCI_NUM
},
88 {OPT_NO_SHCONF
, 0, NULL
, OPT_NO_SHCONF_NUM
},
89 {OPT_PCI_BLACKLIST
, 1, NULL
, OPT_PCI_BLACKLIST_NUM
},
90 {OPT_PCI_WHITELIST
, 1, NULL
, OPT_PCI_WHITELIST_NUM
},
91 {OPT_PROC_TYPE
, 1, NULL
, OPT_PROC_TYPE_NUM
},
92 {OPT_SOCKET_MEM
, 1, NULL
, OPT_SOCKET_MEM_NUM
},
93 {OPT_SYSLOG
, 1, NULL
, OPT_SYSLOG_NUM
},
94 {OPT_VDEV
, 1, NULL
, OPT_VDEV_NUM
},
95 {OPT_VFIO_INTR
, 1, NULL
, OPT_VFIO_INTR_NUM
},
96 {OPT_VMWARE_TSC_MAP
, 0, NULL
, OPT_VMWARE_TSC_MAP_NUM
},
97 {OPT_XEN_DOM0
, 0, NULL
, OPT_XEN_DOM0_NUM
},
101 TAILQ_HEAD(shared_driver_list
, shared_driver
);
103 /* Definition for shared object drivers. */
104 struct shared_driver
{
105 TAILQ_ENTRY(shared_driver
) next
;
111 /* List of external loadable drivers */
112 static struct shared_driver_list solib_list
=
113 TAILQ_HEAD_INITIALIZER(solib_list
);
115 /* Default path of external loadable drivers */
116 static const char *default_solib_dir
= RTE_EAL_PMD_PATH
;
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 tools/dpdk-pmdinfo.py
123 static const char dpdk_solib_path
[] __attribute__((used
)) =
124 "DPDK_PLUGIN_PATH=" RTE_EAL_PMD_PATH
;
127 static int master_lcore_parsed
;
128 static int mem_parsed
;
131 eal_reset_internal_config(struct internal_config
*internal_cfg
)
135 internal_cfg
->memory
= 0;
136 internal_cfg
->force_nrank
= 0;
137 internal_cfg
->force_nchannel
= 0;
138 internal_cfg
->hugefile_prefix
= HUGEFILE_PREFIX_DEFAULT
;
139 internal_cfg
->hugepage_dir
= NULL
;
140 internal_cfg
->force_sockets
= 0;
141 /* zero out the NUMA config */
142 for (i
= 0; i
< RTE_MAX_NUMA_NODES
; i
++)
143 internal_cfg
->socket_mem
[i
] = 0;
144 /* zero out hugedir descriptors */
145 for (i
= 0; i
< MAX_HUGEPAGE_SIZES
; i
++)
146 internal_cfg
->hugepage_info
[i
].lock_descriptor
= -1;
147 internal_cfg
->base_virtaddr
= 0;
149 internal_cfg
->syslog_facility
= LOG_DAEMON
;
150 /* default value from build option */
151 #if RTE_LOG_LEVEL >= RTE_LOG_DEBUG
152 internal_cfg
->log_level
= RTE_LOG_INFO
;
154 internal_cfg
->log_level
= RTE_LOG_LEVEL
;
157 internal_cfg
->xen_dom0_support
= 0;
159 /* if set to NONE, interrupt mode is determined automatically */
160 internal_cfg
->vfio_intr_mode
= RTE_INTR_MODE_NONE
;
162 #ifdef RTE_LIBEAL_USE_HPET
163 internal_cfg
->no_hpet
= 0;
165 internal_cfg
->no_hpet
= 1;
167 internal_cfg
->vmware_tsc_map
= 0;
168 internal_cfg
->create_uio_dev
= 0;
172 eal_plugin_add(const char *path
)
174 struct shared_driver
*solib
;
176 solib
= malloc(sizeof(*solib
));
178 RTE_LOG(ERR
, EAL
, "malloc(solib) failed\n");
181 memset(solib
, 0, sizeof(*solib
));
182 strncpy(solib
->name
, path
, PATH_MAX
-1);
183 solib
->name
[PATH_MAX
-1] = 0;
184 TAILQ_INSERT_TAIL(&solib_list
, solib
, next
);
190 eal_plugindir_init(const char *path
)
193 struct dirent
*dent
= NULL
;
194 char sopath
[PATH_MAX
];
196 if (path
== NULL
|| *path
== '\0')
201 RTE_LOG(ERR
, EAL
, "failed to open directory %s: %s\n",
202 path
, strerror(errno
));
206 while ((dent
= readdir(d
)) != NULL
) {
209 snprintf(sopath
, PATH_MAX
-1, "%s/%s", path
, dent
->d_name
);
210 sopath
[PATH_MAX
-1] = 0;
212 if (!(stat(sopath
, &sb
) == 0 && S_ISREG(sb
.st_mode
)))
215 if (eal_plugin_add(sopath
) == -1)
220 /* XXX this ignores failures from readdir() itself */
221 return (dent
== NULL
) ? 0 : -1;
225 eal_plugins_init(void)
227 struct shared_driver
*solib
= NULL
;
229 if (*default_solib_dir
!= '\0')
230 eal_plugin_add(default_solib_dir
);
232 TAILQ_FOREACH(solib
, &solib_list
, next
) {
235 if (stat(solib
->name
, &sb
) == 0 && S_ISDIR(sb
.st_mode
)) {
236 if (eal_plugindir_init(solib
->name
) == -1) {
238 "Cannot init plugin directory %s\n",
243 RTE_LOG(DEBUG
, EAL
, "open shared lib %s\n",
245 solib
->lib_handle
= dlopen(solib
->name
, RTLD_NOW
);
246 if (solib
->lib_handle
== NULL
) {
247 RTE_LOG(ERR
, EAL
, "%s\n", dlerror());
257 * Parse the coremask given as argument (hexadecimal string) and fill
258 * the global configuration (core role and core count) with the parsed
261 static int xdigit2val(unsigned char c
)
275 eal_parse_coremask(const char *coremask
)
277 struct rte_config
*cfg
= rte_eal_get_configuration();
283 if (coremask
== NULL
)
285 /* Remove all blank characters ahead and after .
286 * Remove 0x/0X if exists.
288 while (isblank(*coremask
))
290 if (coremask
[0] == '0' && ((coremask
[1] == 'x')
291 || (coremask
[1] == 'X')))
293 i
= strlen(coremask
);
294 while ((i
> 0) && isblank(coremask
[i
- 1]))
299 for (i
= i
- 1; i
>= 0 && idx
< RTE_MAX_LCORE
; i
--) {
301 if (isxdigit(c
) == 0) {
302 /* invalid characters */
306 for (j
= 0; j
< BITS_PER_HEX
&& idx
< RTE_MAX_LCORE
; j
++, idx
++)
308 if ((1 << j
) & val
) {
309 if (!lcore_config
[idx
].detected
) {
310 RTE_LOG(ERR
, EAL
, "lcore %u "
311 "unavailable\n", idx
);
314 cfg
->lcore_role
[idx
] = ROLE_RTE
;
315 lcore_config
[idx
].core_index
= count
;
318 cfg
->lcore_role
[idx
] = ROLE_OFF
;
319 lcore_config
[idx
].core_index
= -1;
324 if (coremask
[i
] != '0')
326 for (; idx
< RTE_MAX_LCORE
; idx
++) {
327 cfg
->lcore_role
[idx
] = ROLE_OFF
;
328 lcore_config
[idx
].core_index
= -1;
332 /* Update the count of enabled logical cores of the EAL configuration */
333 cfg
->lcore_count
= count
;
338 eal_parse_corelist(const char *corelist
)
340 struct rte_config
*cfg
= rte_eal_get_configuration();
346 if (corelist
== NULL
)
349 /* Remove all blank characters ahead and after */
350 while (isblank(*corelist
))
352 i
= strlen(corelist
);
353 while ((i
> 0) && isblank(corelist
[i
- 1]))
357 for (idx
= 0; idx
< RTE_MAX_LCORE
; idx
++) {
358 cfg
->lcore_role
[idx
] = ROLE_OFF
;
359 lcore_config
[idx
].core_index
= -1;
362 /* Get list of cores */
365 while (isblank(*corelist
))
367 if (*corelist
== '\0')
370 idx
= strtoul(corelist
, &end
, 10);
371 if (errno
|| end
== NULL
)
373 while (isblank(*end
))
377 } else if ((*end
== ',') || (*end
== '\0')) {
379 if (min
== RTE_MAX_LCORE
)
381 for (idx
= min
; idx
<= max
; idx
++) {
382 if (cfg
->lcore_role
[idx
] != ROLE_RTE
) {
383 cfg
->lcore_role
[idx
] = ROLE_RTE
;
384 lcore_config
[idx
].core_index
= count
;
392 } while (*end
!= '\0');
397 /* Update the count of enabled logical cores of the EAL configuration */
398 cfg
->lcore_count
= count
;
403 /* Changes the lcore id of the master thread */
405 eal_parse_master_lcore(const char *arg
)
408 struct rte_config
*cfg
= rte_eal_get_configuration();
411 cfg
->master_lcore
= (uint32_t) strtol(arg
, &parsing_end
, 0);
412 if (errno
|| parsing_end
[0] != 0)
414 if (cfg
->master_lcore
>= RTE_MAX_LCORE
)
416 master_lcore_parsed
= 1;
421 * Parse elem, the elem could be single number/range or '(' ')' group
422 * 1) A single number elem, it's just a simple digit. e.g. 9
423 * 2) A single range elem, two digits with a '-' between. e.g. 2-6
424 * 3) A group elem, combines multiple 1) or 2) with '( )'. e.g (0,2-4,6)
425 * Within group elem, '-' used for a range separator;
426 * ',' used for a single number.
429 eal_parse_set(const char *input
, uint16_t set
[], unsigned num
)
432 const char *str
= input
;
436 memset(set
, 0, num
* sizeof(uint16_t));
438 while (isblank(*str
))
441 /* only digit or left bracket is qualify for start point */
442 if ((!isdigit(*str
) && *str
!= '(') || *str
== '\0')
445 /* process single number or single range of number */
448 idx
= strtoul(str
, &end
, 10);
449 if (errno
|| end
== NULL
|| idx
>= num
)
452 while (isblank(*end
))
458 /* process single <number>-<number> */
460 while (isblank(*end
))
466 idx
= strtoul(end
, &end
, 10);
467 if (errno
|| end
== NULL
|| idx
>= num
)
470 while (isblank(*end
))
472 if (*end
!= ',' && *end
!= '\0')
476 if (*end
!= ',' && *end
!= '\0' &&
480 for (idx
= RTE_MIN(min
, max
);
481 idx
<= RTE_MAX(min
, max
); idx
++)
488 /* process set within bracket */
490 while (isblank(*str
))
498 /* go ahead to the first digit */
499 while (isblank(*str
))
504 /* get the digit value */
506 idx
= strtoul(str
, &end
, 10);
507 if (errno
|| end
== NULL
|| idx
>= num
)
510 /* go ahead to separator '-',',' and ')' */
511 while (isblank(*end
))
514 if (min
== RTE_MAX_LCORE
)
516 else /* avoid continuous '-' */
518 } else if ((*end
== ',') || (*end
== ')')) {
520 if (min
== RTE_MAX_LCORE
)
522 for (idx
= RTE_MIN(min
, max
);
523 idx
<= RTE_MAX(min
, max
); idx
++)
531 } while (*end
!= '\0' && *end
!= ')');
534 * to avoid failure that tail blank makes end character check fail
535 * in eal_parse_lcores( )
537 while (isblank(*str
))
543 /* convert from set array to cpuset bitmap */
545 convert_to_cpuset(rte_cpuset_t
*cpusetp
,
546 uint16_t *set
, unsigned num
)
552 for (idx
= 0; idx
< num
; idx
++) {
556 if (!lcore_config
[idx
].detected
) {
557 RTE_LOG(ERR
, EAL
, "core %u "
558 "unavailable\n", idx
);
562 CPU_SET(idx
, cpusetp
);
569 * The format pattern: --lcores='<lcores[@cpus]>[<,lcores[@cpus]>...]'
570 * lcores, cpus could be a single digit/range or a group.
571 * '(' and ')' are necessary if it's a group.
572 * If not supply '@cpus', the value of cpus uses the same as lcores.
573 * e.g. '1,2@(5-7),(3-5)@(0,2),(0,6),7-8' means start 9 EAL thread as below
574 * lcore 0 runs on cpuset 0x41 (cpu 0,6)
575 * lcore 1 runs on cpuset 0x2 (cpu 1)
576 * lcore 2 runs on cpuset 0xe0 (cpu 5,6,7)
577 * lcore 3,4,5 runs on cpuset 0x5 (cpu 0,2)
578 * lcore 6 runs on cpuset 0x41 (cpu 0,6)
579 * lcore 7 runs on cpuset 0x80 (cpu 7)
580 * lcore 8 runs on cpuset 0x100 (cpu 8)
583 eal_parse_lcores(const char *lcores
)
585 struct rte_config
*cfg
= rte_eal_get_configuration();
586 static uint16_t set
[RTE_MAX_LCORE
];
589 const char *lcore_start
= NULL
;
590 const char *end
= NULL
;
599 /* Remove all blank characters ahead and after */
600 while (isblank(*lcores
))
605 /* Reset lcore config */
606 for (idx
= 0; idx
< RTE_MAX_LCORE
; idx
++) {
607 cfg
->lcore_role
[idx
] = ROLE_OFF
;
608 lcore_config
[idx
].core_index
= -1;
609 CPU_ZERO(&lcore_config
[idx
].cpuset
);
612 /* Get list of cores */
614 while (isblank(*lcores
))
621 /* record lcore_set start point */
622 lcore_start
= lcores
;
624 /* go across a complete bracket */
625 if (*lcore_start
== '(') {
626 lcores
+= strcspn(lcores
, ")");
627 if (*lcores
++ == '\0')
631 /* scan the separator '@', ','(next) or '\0'(finish) */
632 lcores
+= strcspn(lcores
, "@,");
634 if (*lcores
== '@') {
635 /* explicit assign cpu_set */
636 offset
= eal_parse_set(lcores
+ 1, set
, RTE_DIM(set
));
640 /* prepare cpu_set and update the end cursor */
641 if (0 > convert_to_cpuset(&cpuset
,
644 end
= lcores
+ 1 + offset
;
645 } else { /* ',' or '\0' */
646 /* haven't given cpu_set, current loop done */
649 /* go back to check <number>-<number> */
650 offset
= strcspn(lcore_start
, "(-");
651 if (offset
< (end
- lcore_start
) &&
652 *(lcore_start
+ offset
) != '(')
656 if (*end
!= ',' && *end
!= '\0')
659 /* parse lcore_set from start point */
660 if (0 > eal_parse_set(lcore_start
, set
, RTE_DIM(set
)))
663 /* without '@', by default using lcore_set as cpu_set */
664 if (*lcores
!= '@' &&
665 0 > convert_to_cpuset(&cpuset
, set
, RTE_DIM(set
)))
668 /* start to update lcore_set */
669 for (idx
= 0; idx
< RTE_MAX_LCORE
; idx
++) {
673 if (cfg
->lcore_role
[idx
] != ROLE_RTE
) {
674 lcore_config
[idx
].core_index
= count
;
675 cfg
->lcore_role
[idx
] = ROLE_RTE
;
681 CPU_SET(idx
, &cpuset
);
683 rte_memcpy(&lcore_config
[idx
].cpuset
, &cpuset
,
684 sizeof(rte_cpuset_t
));
688 } while (*end
!= '\0');
693 cfg
->lcore_count
= count
;
702 eal_parse_syslog(const char *facility
, struct internal_config
*conf
)
709 { "auth", LOG_AUTH
},
710 { "cron", LOG_CRON
},
711 { "daemon", LOG_DAEMON
},
713 { "kern", LOG_KERN
},
715 { "mail", LOG_MAIL
},
716 { "news", LOG_NEWS
},
717 { "syslog", LOG_SYSLOG
},
718 { "user", LOG_USER
},
719 { "uucp", LOG_UUCP
},
720 { "local0", LOG_LOCAL0
},
721 { "local1", LOG_LOCAL1
},
722 { "local2", LOG_LOCAL2
},
723 { "local3", LOG_LOCAL3
},
724 { "local4", LOG_LOCAL4
},
725 { "local5", LOG_LOCAL5
},
726 { "local6", LOG_LOCAL6
},
727 { "local7", LOG_LOCAL7
},
731 for (i
= 0; map
[i
].name
; i
++) {
732 if (!strcmp(facility
, map
[i
].name
)) {
733 conf
->syslog_facility
= map
[i
].value
;
741 eal_parse_log_level(const char *level
, uint32_t *log_level
)
747 tmp
= strtoul(level
, &end
, 0);
749 /* check for errors */
750 if ((errno
!= 0) || (level
[0] == '\0') ||
751 end
== NULL
|| (*end
!= '\0'))
754 /* log_level is a uint32_t */
755 if (tmp
>= UINT32_MAX
)
762 static enum rte_proc_type_t
763 eal_parse_proc_type(const char *arg
)
765 if (strncasecmp(arg
, "primary", sizeof("primary")) == 0)
766 return RTE_PROC_PRIMARY
;
767 if (strncasecmp(arg
, "secondary", sizeof("secondary")) == 0)
768 return RTE_PROC_SECONDARY
;
769 if (strncasecmp(arg
, "auto", sizeof("auto")) == 0)
770 return RTE_PROC_AUTO
;
772 return RTE_PROC_INVALID
;
776 eal_parse_common_option(int opt
, const char *optarg
,
777 struct internal_config
*conf
)
782 if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI
,
789 if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI
,
796 if (eal_parse_coremask(optarg
) < 0) {
797 RTE_LOG(ERR
, EAL
, "invalid coremask\n");
803 if (eal_parse_corelist(optarg
) < 0) {
804 RTE_LOG(ERR
, EAL
, "invalid core list\n");
810 conf
->memory
= atoi(optarg
);
811 conf
->memory
*= 1024ULL;
812 conf
->memory
*= 1024ULL;
815 /* force number of channels */
817 conf
->force_nchannel
= atoi(optarg
);
818 if (conf
->force_nchannel
== 0) {
819 RTE_LOG(ERR
, EAL
, "invalid channel number\n");
823 /* force number of ranks */
825 conf
->force_nrank
= atoi(optarg
);
826 if (conf
->force_nrank
== 0 ||
827 conf
->force_nrank
> 16) {
828 RTE_LOG(ERR
, EAL
, "invalid rank number\n");
832 /* force loading of external driver */
834 if (eal_plugin_add(optarg
) == -1)
838 /* since message is explicitly requested by user, we
839 * write message at highest log level so it can always
841 * even if info or warning messages are disabled */
842 RTE_LOG(CRIT
, EAL
, "RTE Version: '%s'\n", rte_version());
846 case OPT_HUGE_UNLINK_NUM
:
847 conf
->hugepage_unlink
= 1;
850 case OPT_NO_HUGE_NUM
:
851 conf
->no_hugetlbfs
= 1;
858 case OPT_NO_HPET_NUM
:
862 case OPT_VMWARE_TSC_MAP_NUM
:
863 conf
->vmware_tsc_map
= 1;
866 case OPT_NO_SHCONF_NUM
:
870 case OPT_PROC_TYPE_NUM
:
871 conf
->process_type
= eal_parse_proc_type(optarg
);
874 case OPT_MASTER_LCORE_NUM
:
875 if (eal_parse_master_lcore(optarg
) < 0) {
876 RTE_LOG(ERR
, EAL
, "invalid parameter for --"
877 OPT_MASTER_LCORE
"\n");
883 if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL
,
890 if (eal_parse_syslog(optarg
, conf
) < 0) {
891 RTE_LOG(ERR
, EAL
, "invalid parameters for --"
897 case OPT_LOG_LEVEL_NUM
: {
900 if (eal_parse_log_level(optarg
, &log
) < 0) {
902 "invalid parameters for --"
906 conf
->log_level
= log
;
910 if (eal_parse_lcores(optarg
) < 0) {
911 RTE_LOG(ERR
, EAL
, "invalid parameter for --"
917 /* don't know what to do, leave this to caller */
927 eal_adjust_config(struct internal_config
*internal_cfg
)
930 struct rte_config
*cfg
= rte_eal_get_configuration();
932 if (internal_config
.process_type
== RTE_PROC_AUTO
)
933 internal_config
.process_type
= eal_proc_type_detect();
935 /* default master lcore is the first one */
936 if (!master_lcore_parsed
)
937 cfg
->master_lcore
= rte_get_next_lcore(-1, 0, 0);
939 /* if no memory amounts were requested, this will result in 0 and
940 * will be overridden later, right after eal_hugepage_info_init() */
941 for (i
= 0; i
< RTE_MAX_NUMA_NODES
; i
++)
942 internal_cfg
->memory
+= internal_cfg
->socket_mem
[i
];
948 eal_check_common_options(struct internal_config
*internal_cfg
)
950 struct rte_config
*cfg
= rte_eal_get_configuration();
952 if (cfg
->lcore_role
[cfg
->master_lcore
] != ROLE_RTE
) {
953 RTE_LOG(ERR
, EAL
, "Master lcore is not enabled for DPDK\n");
957 if (internal_cfg
->process_type
== RTE_PROC_INVALID
) {
958 RTE_LOG(ERR
, EAL
, "Invalid process type specified\n");
961 if (index(internal_cfg
->hugefile_prefix
, '%') != NULL
) {
962 RTE_LOG(ERR
, EAL
, "Invalid char, '%%', in --"OPT_FILE_PREFIX
" "
966 if (mem_parsed
&& internal_cfg
->force_sockets
== 1) {
967 RTE_LOG(ERR
, EAL
, "Options -m and --"OPT_SOCKET_MEM
" cannot "
968 "be specified at the same time\n");
971 if (internal_cfg
->no_hugetlbfs
&& internal_cfg
->force_sockets
== 1) {
972 RTE_LOG(ERR
, EAL
, "Option --"OPT_SOCKET_MEM
" cannot "
973 "be specified together with --"OPT_NO_HUGE
"\n");
977 if (internal_cfg
->no_hugetlbfs
&& internal_cfg
->hugepage_unlink
) {
978 RTE_LOG(ERR
, EAL
, "Option --"OPT_HUGE_UNLINK
" cannot "
979 "be specified together with --"OPT_NO_HUGE
"\n");
983 if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI
) != 0 &&
984 rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_PCI
) != 0) {
985 RTE_LOG(ERR
, EAL
, "Options blacklist (-b) and whitelist (-w) "
986 "cannot be used at the same time\n");
994 eal_common_usage(void)
996 printf("[options]\n\n"
997 "EAL common options:\n"
998 " -c COREMASK Hexadecimal bitmask of cores to run on\n"
999 " -l CORELIST List of cores to run on\n"
1000 " The argument format is <c1>[-c2][,c3[-c4],...]\n"
1001 " where c1, c2, etc are core indexes between 0 and %d\n"
1002 " --"OPT_LCORES
" COREMAP Map lcore set to physical cpu set\n"
1003 " The argument format is\n"
1004 " '<lcores[@cpus]>[<,lcores[@cpus]>...]'\n"
1005 " lcores and cpus list are grouped by '(' and ')'\n"
1006 " Within the group, '-' is used for range separator,\n"
1007 " ',' is used for single number separator.\n"
1008 " '( )' can be omitted for single element group,\n"
1009 " '@' can be omitted if cpus and lcores have the same value\n"
1010 " --"OPT_MASTER_LCORE
" ID Core ID that is used as master\n"
1011 " -n CHANNELS Number of memory channels\n"
1012 " -m MB Memory to allocate (see also --"OPT_SOCKET_MEM
")\n"
1013 " -r RANKS Force number of memory ranks (don't detect)\n"
1014 " -b, --"OPT_PCI_BLACKLIST
" Add a PCI device in black list.\n"
1015 " Prevent EAL from using this PCI device. The argument\n"
1016 " format is <domain:bus:devid.func>.\n"
1017 " -w, --"OPT_PCI_WHITELIST
" Add a PCI device in white list.\n"
1018 " Only use the specified PCI devices. The argument format\n"
1019 " is <[domain:]bus:devid.func>. This option can be present\n"
1020 " several times (once per device).\n"
1021 " [NOTE: PCI whitelist cannot be used with -b option]\n"
1022 " --"OPT_VDEV
" Add a virtual device.\n"
1023 " The argument format is <driver><id>[,key=val,...]\n"
1024 " (ex: --vdev=net_pcap0,iface=eth2).\n"
1025 " -d LIB.so|DIR Add a driver or driver directory\n"
1026 " (can be used multiple times)\n"
1027 " --"OPT_VMWARE_TSC_MAP
" Use VMware TSC map instead of native RDTSC\n"
1028 " --"OPT_PROC_TYPE
" Type of this process (primary|secondary|auto)\n"
1029 " --"OPT_SYSLOG
" Set syslog facility\n"
1030 " --"OPT_LOG_LEVEL
" Set default log level\n"
1031 " -v Display version information on startup\n"
1032 " -h, --help This help\n"
1033 "\nEAL options for DEBUG use only:\n"
1034 " --"OPT_HUGE_UNLINK
" Unlink hugepage files after init\n"
1035 " --"OPT_NO_HUGE
" Use malloc instead of hugetlbfs\n"
1036 " --"OPT_NO_PCI
" Disable PCI\n"
1037 " --"OPT_NO_HPET
" Disable HPET\n"
1038 " --"OPT_NO_SHCONF
" No shared config (mmap'd files)\n"
1039 "\n", RTE_MAX_LCORE
);