199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * Copyright(c) 2019 Intel Corporation 399a2dd95SBruce Richardson */ 499a2dd95SBruce Richardson 599a2dd95SBruce Richardson #include <stdarg.h> 699a2dd95SBruce Richardson 799a2dd95SBruce Richardson #include <fcntl.h> 899a2dd95SBruce Richardson #include <io.h> 999a2dd95SBruce Richardson #include <share.h> 1099a2dd95SBruce Richardson #include <sys/stat.h> 1199a2dd95SBruce Richardson 1299a2dd95SBruce Richardson #include <rte_debug.h> 13770ebc06SDavid Marchand #include <rte_bus.h> 1499a2dd95SBruce Richardson #include <rte_eal.h> 152e2f0272SDavid Marchand #include <rte_eal_memconfig.h> 1699a2dd95SBruce Richardson #include <eal_memcfg.h> 1799a2dd95SBruce Richardson #include <rte_errno.h> 1899a2dd95SBruce Richardson #include <rte_lcore.h> 195bce9bedSMattias Rönnblom #include "eal_lcore_var.h" 2099a2dd95SBruce Richardson #include <eal_thread.h> 2199a2dd95SBruce Richardson #include <eal_internal_cfg.h> 2299a2dd95SBruce Richardson #include <eal_filesystem.h> 2399a2dd95SBruce Richardson #include <eal_options.h> 2499a2dd95SBruce Richardson #include <eal_private.h> 2599a2dd95SBruce Richardson #include <rte_service_component.h> 2699a2dd95SBruce Richardson #include <rte_vfio.h> 2799a2dd95SBruce Richardson 2840edb9c0SDavid Marchand #include "eal_firmware.h" 2999a2dd95SBruce Richardson #include "eal_hugepages.h" 3099a2dd95SBruce Richardson #include "eal_trace.h" 3199a2dd95SBruce Richardson #include "eal_windows.h" 3209ce4131SBruce Richardson #include "log_internal.h" 3399a2dd95SBruce Richardson 3499a2dd95SBruce Richardson #define MEMSIZE_IF_NO_HUGE_PAGE (64ULL * 1024ULL * 1024ULL) 3599a2dd95SBruce Richardson 3699a2dd95SBruce Richardson /* define fd variable here, because file needs to be kept open for the 3799a2dd95SBruce Richardson * duration of the program, as we hold a write lock on it in the primary proc 3899a2dd95SBruce Richardson */ 3999a2dd95SBruce Richardson static int mem_cfg_fd = -1; 4099a2dd95SBruce Richardson 4199a2dd95SBruce Richardson /* internal configuration (per-core) */ 4299a2dd95SBruce Richardson struct lcore_config lcore_config[RTE_MAX_LCORE]; 4399a2dd95SBruce Richardson 4499a2dd95SBruce Richardson /* Detect if we are a primary or a secondary process */ 4599a2dd95SBruce Richardson enum rte_proc_type_t 4699a2dd95SBruce Richardson eal_proc_type_detect(void) 4799a2dd95SBruce Richardson { 4899a2dd95SBruce Richardson enum rte_proc_type_t ptype = RTE_PROC_PRIMARY; 4999a2dd95SBruce Richardson const char *pathname = eal_runtime_config_path(); 5099a2dd95SBruce Richardson const struct rte_config *config = rte_eal_get_configuration(); 5199a2dd95SBruce Richardson 5299a2dd95SBruce Richardson /* if we can open the file but not get a write-lock we are a secondary 5399a2dd95SBruce Richardson * process. NOTE: if we get a file handle back, we keep that open 5499a2dd95SBruce Richardson * and don't close it to prevent a race condition between multiple opens 5599a2dd95SBruce Richardson */ 5699a2dd95SBruce Richardson errno_t err = _sopen_s(&mem_cfg_fd, pathname, 5799a2dd95SBruce Richardson _O_RDWR, _SH_DENYNO, _S_IREAD | _S_IWRITE); 5899a2dd95SBruce Richardson if (err == 0) { 5999a2dd95SBruce Richardson OVERLAPPED soverlapped = { 0 }; 6099a2dd95SBruce Richardson soverlapped.Offset = sizeof(*config->mem_config); 6199a2dd95SBruce Richardson soverlapped.OffsetHigh = 0; 6299a2dd95SBruce Richardson 6399a2dd95SBruce Richardson HANDLE hwinfilehandle = (HANDLE)_get_osfhandle(mem_cfg_fd); 6499a2dd95SBruce Richardson 6599a2dd95SBruce Richardson if (!LockFileEx(hwinfilehandle, 6699a2dd95SBruce Richardson LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0, 6799a2dd95SBruce Richardson sizeof(*config->mem_config), 0, &soverlapped)) 6899a2dd95SBruce Richardson ptype = RTE_PROC_SECONDARY; 6999a2dd95SBruce Richardson } 7099a2dd95SBruce Richardson 71ae67895bSDavid Marchand EAL_LOG(INFO, "Auto-detected process type: %s", 7299a2dd95SBruce Richardson ptype == RTE_PROC_PRIMARY ? "PRIMARY" : "SECONDARY"); 7399a2dd95SBruce Richardson 7499a2dd95SBruce Richardson return ptype; 7599a2dd95SBruce Richardson } 7699a2dd95SBruce Richardson 7799a2dd95SBruce Richardson bool 7899a2dd95SBruce Richardson rte_mp_disable(void) 7999a2dd95SBruce Richardson { 8099a2dd95SBruce Richardson return true; 8199a2dd95SBruce Richardson } 8299a2dd95SBruce Richardson 8399a2dd95SBruce Richardson /* display usage */ 8499a2dd95SBruce Richardson static void 8599a2dd95SBruce Richardson eal_usage(const char *prgname) 8699a2dd95SBruce Richardson { 8799a2dd95SBruce Richardson rte_usage_hook_t hook = eal_get_application_usage_hook(); 8899a2dd95SBruce Richardson 8999a2dd95SBruce Richardson printf("\nUsage: %s ", prgname); 9099a2dd95SBruce Richardson eal_common_usage(); 9199a2dd95SBruce Richardson /* Allow the application to print its usage message too 9299a2dd95SBruce Richardson * if hook is set 9399a2dd95SBruce Richardson */ 9499a2dd95SBruce Richardson if (hook) { 9599a2dd95SBruce Richardson printf("===== Application Usage =====\n\n"); 9699a2dd95SBruce Richardson (hook)(prgname); 9799a2dd95SBruce Richardson } 9899a2dd95SBruce Richardson } 9999a2dd95SBruce Richardson 10099a2dd95SBruce Richardson /* Parse the argument given in the command line of the application */ 10199a2dd95SBruce Richardson static int 10299a2dd95SBruce Richardson eal_parse_args(int argc, char **argv) 10399a2dd95SBruce Richardson { 10499a2dd95SBruce Richardson int opt, ret; 10599a2dd95SBruce Richardson char **argvopt; 10699a2dd95SBruce Richardson int option_index; 10799a2dd95SBruce Richardson char *prgname = argv[0]; 10899a2dd95SBruce Richardson struct internal_config *internal_conf = 10999a2dd95SBruce Richardson eal_get_internal_configuration(); 11099a2dd95SBruce Richardson 11199a2dd95SBruce Richardson argvopt = argv; 11299a2dd95SBruce Richardson 11399a2dd95SBruce Richardson while ((opt = getopt_long(argc, argvopt, eal_short_options, 11499a2dd95SBruce Richardson eal_long_options, &option_index)) != EOF) { 11599a2dd95SBruce Richardson 11699a2dd95SBruce Richardson int ret; 11799a2dd95SBruce Richardson 11899a2dd95SBruce Richardson /* getopt is not happy, stop right now */ 11999a2dd95SBruce Richardson if (opt == '?') { 12099a2dd95SBruce Richardson eal_usage(prgname); 12199a2dd95SBruce Richardson return -1; 12299a2dd95SBruce Richardson } 12399a2dd95SBruce Richardson 1249a4276f9SDavid Marchand /* eal_parse_log_options() already handled this option */ 1259a4276f9SDavid Marchand if (eal_option_is_log(opt)) 12699a2dd95SBruce Richardson continue; 12799a2dd95SBruce Richardson 12899a2dd95SBruce Richardson ret = eal_parse_common_option(opt, optarg, internal_conf); 12999a2dd95SBruce Richardson /* common parser is not happy */ 13099a2dd95SBruce Richardson if (ret < 0) { 13199a2dd95SBruce Richardson eal_usage(prgname); 13299a2dd95SBruce Richardson return -1; 13399a2dd95SBruce Richardson } 13499a2dd95SBruce Richardson /* common parser handled this option */ 13599a2dd95SBruce Richardson if (ret == 0) 13699a2dd95SBruce Richardson continue; 13799a2dd95SBruce Richardson 13899a2dd95SBruce Richardson switch (opt) { 139df60837cSThomas Monjalon case OPT_HELP_NUM: 14099a2dd95SBruce Richardson eal_usage(prgname); 14199a2dd95SBruce Richardson exit(EXIT_SUCCESS); 14299a2dd95SBruce Richardson default: 14399a2dd95SBruce Richardson if (opt < OPT_LONG_MIN_NUM && isprint(opt)) { 144ae67895bSDavid Marchand EAL_LOG(ERR, "Option %c is not supported " 145ae67895bSDavid Marchand "on Windows", opt); 14699a2dd95SBruce Richardson } else if (opt >= OPT_LONG_MIN_NUM && 14799a2dd95SBruce Richardson opt < OPT_LONG_MAX_NUM) { 148ae67895bSDavid Marchand EAL_LOG(ERR, "Option %s is not supported " 149ae67895bSDavid Marchand "on Windows", 15099a2dd95SBruce Richardson eal_long_options[option_index].name); 15199a2dd95SBruce Richardson } else { 152ae67895bSDavid Marchand EAL_LOG(ERR, "Option %d is not supported " 153ae67895bSDavid Marchand "on Windows", opt); 15499a2dd95SBruce Richardson } 15599a2dd95SBruce Richardson eal_usage(prgname); 15699a2dd95SBruce Richardson return -1; 15799a2dd95SBruce Richardson } 15899a2dd95SBruce Richardson } 15999a2dd95SBruce Richardson 16099a2dd95SBruce Richardson if (eal_adjust_config(internal_conf) != 0) 16199a2dd95SBruce Richardson return -1; 16299a2dd95SBruce Richardson 16399a2dd95SBruce Richardson /* sanity checks */ 16499a2dd95SBruce Richardson if (eal_check_common_options(internal_conf) != 0) { 16599a2dd95SBruce Richardson eal_usage(prgname); 16699a2dd95SBruce Richardson return -1; 16799a2dd95SBruce Richardson } 16899a2dd95SBruce Richardson 16999a2dd95SBruce Richardson if (optind >= 0) 17099a2dd95SBruce Richardson argv[optind - 1] = prgname; 17199a2dd95SBruce Richardson ret = optind - 1; 17299a2dd95SBruce Richardson optind = 0; /* reset getopt lib */ 17399a2dd95SBruce Richardson return ret; 17499a2dd95SBruce Richardson } 17599a2dd95SBruce Richardson 17699a2dd95SBruce Richardson static int 17799a2dd95SBruce Richardson sync_func(void *arg __rte_unused) 17899a2dd95SBruce Richardson { 17999a2dd95SBruce Richardson return 0; 18099a2dd95SBruce Richardson } 18199a2dd95SBruce Richardson 18299a2dd95SBruce Richardson static void 18399a2dd95SBruce Richardson rte_eal_init_alert(const char *msg) 18499a2dd95SBruce Richardson { 18572bf6da8SStephen Hemminger EAL_LOG(ALERT, "%s", msg); 18699a2dd95SBruce Richardson } 18799a2dd95SBruce Richardson 18899a2dd95SBruce Richardson /* Stubs to enable EAL trace point compilation 18999a2dd95SBruce Richardson * until eal_common_trace.c can be compiled. 19099a2dd95SBruce Richardson */ 19199a2dd95SBruce Richardson 19299a2dd95SBruce Richardson RTE_DEFINE_PER_LCORE(volatile int, trace_point_sz); 19399a2dd95SBruce Richardson RTE_DEFINE_PER_LCORE(void *, trace_mem); 19499a2dd95SBruce Richardson 19599a2dd95SBruce Richardson void 19699a2dd95SBruce Richardson __rte_trace_mem_per_thread_alloc(void) 19799a2dd95SBruce Richardson { 19899a2dd95SBruce Richardson } 19999a2dd95SBruce Richardson 20099a2dd95SBruce Richardson void 20199a2dd95SBruce Richardson trace_mem_per_thread_free(void) 20299a2dd95SBruce Richardson { 20399a2dd95SBruce Richardson } 20499a2dd95SBruce Richardson 20599a2dd95SBruce Richardson void 20699a2dd95SBruce Richardson __rte_trace_point_emit_field(size_t sz, const char *field, 20799a2dd95SBruce Richardson const char *type) 20899a2dd95SBruce Richardson { 20999a2dd95SBruce Richardson RTE_SET_USED(sz); 21099a2dd95SBruce Richardson RTE_SET_USED(field); 21199a2dd95SBruce Richardson RTE_SET_USED(type); 21299a2dd95SBruce Richardson } 21399a2dd95SBruce Richardson 21499a2dd95SBruce Richardson int 21599a2dd95SBruce Richardson __rte_trace_point_register(rte_trace_point_t *trace, const char *name, 21699a2dd95SBruce Richardson void (*register_fn)(void)) 21799a2dd95SBruce Richardson { 21899a2dd95SBruce Richardson RTE_SET_USED(trace); 21999a2dd95SBruce Richardson RTE_SET_USED(name); 22099a2dd95SBruce Richardson RTE_SET_USED(register_fn); 22199a2dd95SBruce Richardson return -ENOTSUP; 22299a2dd95SBruce Richardson } 22399a2dd95SBruce Richardson 22499a2dd95SBruce Richardson int 22599a2dd95SBruce Richardson rte_eal_cleanup(void) 22699a2dd95SBruce Richardson { 22799a2dd95SBruce Richardson struct internal_config *internal_conf = 22899a2dd95SBruce Richardson eal_get_internal_configuration(); 229cfdaa678SDmitry Kozlyuk 230cfdaa678SDmitry Kozlyuk eal_intr_thread_cancel(); 23123ce9e0aSDmitry Kozlyuk eal_mem_virt2iova_cleanup(); 2321cab1a40SKevin Laatz eal_bus_cleanup(); 23399a2dd95SBruce Richardson /* after this point, any DPDK pointers will become dangling */ 23499a2dd95SBruce Richardson rte_eal_memory_detach(); 23599a2dd95SBruce Richardson eal_cleanup_config(internal_conf); 2365bce9bedSMattias Rönnblom eal_lcore_var_cleanup(); 23799a2dd95SBruce Richardson return 0; 23899a2dd95SBruce Richardson } 23999a2dd95SBruce Richardson 24099a2dd95SBruce Richardson /* Launch threads, called at application init(). */ 24199a2dd95SBruce Richardson int 24299a2dd95SBruce Richardson rte_eal_init(int argc, char **argv) 24399a2dd95SBruce Richardson { 24499a2dd95SBruce Richardson int i, fctret, bscan; 24599a2dd95SBruce Richardson const struct rte_config *config = rte_eal_get_configuration(); 24699a2dd95SBruce Richardson struct internal_config *internal_conf = 24799a2dd95SBruce Richardson eal_get_internal_configuration(); 2480c8fc83aSDmitry Kozlyuk bool has_phys_addr; 2490c8fc83aSDmitry Kozlyuk enum rte_iova_mode iova_mode; 25099a2dd95SBruce Richardson int ret; 2518001c0ddSTyler Retzlaff char cpuset[RTE_CPU_AFFINITY_STR_LEN]; 25293d8a7edSThomas Monjalon char thread_name[RTE_THREAD_NAME_SIZE]; 25399a2dd95SBruce Richardson 254*2773d39fSStephen Hemminger /* setup log as early as possible */ 255*2773d39fSStephen Hemminger if (eal_parse_log_options(argc, argv) < 0) { 256*2773d39fSStephen Hemminger rte_eal_init_alert("invalid log arguments."); 257*2773d39fSStephen Hemminger rte_errno = EINVAL; 258*2773d39fSStephen Hemminger return -1; 259*2773d39fSStephen Hemminger } 26099a2dd95SBruce Richardson 261*2773d39fSStephen Hemminger eal_log_init(NULL); 26299a2dd95SBruce Richardson 26399a2dd95SBruce Richardson if (eal_create_cpu_map() < 0) { 26499a2dd95SBruce Richardson rte_eal_init_alert("Cannot discover CPU and NUMA."); 26599a2dd95SBruce Richardson /* rte_errno is set */ 26699a2dd95SBruce Richardson return -1; 26799a2dd95SBruce Richardson } 26899a2dd95SBruce Richardson 269e168b189SDavid Christensen /* verify if DPDK supported on architecture MMU */ 270e168b189SDavid Christensen if (!eal_mmu_supported()) { 271e168b189SDavid Christensen rte_eal_init_alert("Unsupported MMU type."); 272e168b189SDavid Christensen rte_errno = ENOTSUP; 273e168b189SDavid Christensen return -1; 274e168b189SDavid Christensen } 275e168b189SDavid Christensen 27699a2dd95SBruce Richardson if (rte_eal_cpu_init() < 0) { 27799a2dd95SBruce Richardson rte_eal_init_alert("Cannot detect lcores."); 27899a2dd95SBruce Richardson rte_errno = ENOTSUP; 27999a2dd95SBruce Richardson return -1; 28099a2dd95SBruce Richardson } 28199a2dd95SBruce Richardson 28299a2dd95SBruce Richardson fctret = eal_parse_args(argc, argv); 28399a2dd95SBruce Richardson if (fctret < 0) 28499a2dd95SBruce Richardson exit(1); 28599a2dd95SBruce Richardson 28699a2dd95SBruce Richardson if (eal_option_device_parse()) { 28799a2dd95SBruce Richardson rte_errno = ENODEV; 28899a2dd95SBruce Richardson return -1; 28999a2dd95SBruce Richardson } 29099a2dd95SBruce Richardson 29199a2dd95SBruce Richardson /* Prevent creation of shared memory files. */ 29299a2dd95SBruce Richardson if (internal_conf->in_memory == 0) { 293ae67895bSDavid Marchand EAL_LOG(WARNING, "Multi-process support is requested, " 294ae67895bSDavid Marchand "but not available."); 29599a2dd95SBruce Richardson internal_conf->in_memory = 1; 29699a2dd95SBruce Richardson internal_conf->no_shconf = 1; 29799a2dd95SBruce Richardson } 29899a2dd95SBruce Richardson 29999a2dd95SBruce Richardson if (!internal_conf->no_hugetlbfs && (eal_hugepage_info_init() < 0)) { 30099a2dd95SBruce Richardson rte_eal_init_alert("Cannot get hugepage information"); 30199a2dd95SBruce Richardson rte_errno = EACCES; 30299a2dd95SBruce Richardson return -1; 30399a2dd95SBruce Richardson } 30499a2dd95SBruce Richardson 30599a2dd95SBruce Richardson if (internal_conf->memory == 0 && !internal_conf->force_sockets) { 30699a2dd95SBruce Richardson if (internal_conf->no_hugetlbfs) 30799a2dd95SBruce Richardson internal_conf->memory = MEMSIZE_IF_NO_HUGE_PAGE; 30899a2dd95SBruce Richardson } 30999a2dd95SBruce Richardson 3100c8fc83aSDmitry Kozlyuk if (rte_eal_intr_init() < 0) { 3110c8fc83aSDmitry Kozlyuk rte_eal_init_alert("Cannot init interrupt-handling thread"); 3120c8fc83aSDmitry Kozlyuk return -1; 3130c8fc83aSDmitry Kozlyuk } 3140c8fc83aSDmitry Kozlyuk 3150c8fc83aSDmitry Kozlyuk if (rte_eal_timer_init() < 0) { 3160c8fc83aSDmitry Kozlyuk rte_eal_init_alert("Cannot init TSC timer"); 3170c8fc83aSDmitry Kozlyuk rte_errno = EFAULT; 3180c8fc83aSDmitry Kozlyuk return -1; 3190c8fc83aSDmitry Kozlyuk } 3200c8fc83aSDmitry Kozlyuk 3210c8fc83aSDmitry Kozlyuk bscan = rte_bus_scan(); 3220c8fc83aSDmitry Kozlyuk if (bscan < 0) { 3230c8fc83aSDmitry Kozlyuk rte_eal_init_alert("Cannot scan the buses"); 3240c8fc83aSDmitry Kozlyuk rte_errno = ENODEV; 3250c8fc83aSDmitry Kozlyuk return -1; 3260c8fc83aSDmitry Kozlyuk } 3270c8fc83aSDmitry Kozlyuk 32899a2dd95SBruce Richardson if (eal_mem_win32api_init() < 0) { 32999a2dd95SBruce Richardson rte_eal_init_alert("Cannot access Win32 memory management"); 33099a2dd95SBruce Richardson rte_errno = ENOTSUP; 33199a2dd95SBruce Richardson return -1; 33299a2dd95SBruce Richardson } 33399a2dd95SBruce Richardson 3340c8fc83aSDmitry Kozlyuk has_phys_addr = true; 33599a2dd95SBruce Richardson if (eal_mem_virt2iova_init() < 0) { 33699a2dd95SBruce Richardson /* Non-fatal error if physical addresses are not required. */ 337ae67895bSDavid Marchand EAL_LOG(DEBUG, "Cannot access virt2phys driver, " 338ae67895bSDavid Marchand "PA will not be available"); 3390c8fc83aSDmitry Kozlyuk has_phys_addr = false; 34099a2dd95SBruce Richardson } 34199a2dd95SBruce Richardson 3420c8fc83aSDmitry Kozlyuk iova_mode = internal_conf->iova_mode; 3430c8fc83aSDmitry Kozlyuk if (iova_mode == RTE_IOVA_DC) { 344ae67895bSDavid Marchand EAL_LOG(DEBUG, "Specific IOVA mode is not requested, autodetecting"); 3450c8fc83aSDmitry Kozlyuk if (has_phys_addr) { 346ae67895bSDavid Marchand EAL_LOG(DEBUG, "Selecting IOVA mode according to bus requests"); 3470c8fc83aSDmitry Kozlyuk iova_mode = rte_bus_get_iommu_class(); 348a37335bcSViacheslav Ovsiienko if (iova_mode == RTE_IOVA_DC) { 349a37335bcSViacheslav Ovsiienko if (!RTE_IOVA_IN_MBUF) { 350a37335bcSViacheslav Ovsiienko iova_mode = RTE_IOVA_VA; 351ae67895bSDavid Marchand EAL_LOG(DEBUG, "IOVA as VA mode is forced by build option."); 352a37335bcSViacheslav Ovsiienko } else { 3530c8fc83aSDmitry Kozlyuk iova_mode = RTE_IOVA_PA; 354a37335bcSViacheslav Ovsiienko } 355a37335bcSViacheslav Ovsiienko } 3560c8fc83aSDmitry Kozlyuk } else { 3570c8fc83aSDmitry Kozlyuk iova_mode = RTE_IOVA_VA; 3580c8fc83aSDmitry Kozlyuk } 3590c8fc83aSDmitry Kozlyuk } 360a37335bcSViacheslav Ovsiienko 361a37335bcSViacheslav Ovsiienko if (iova_mode == RTE_IOVA_PA && !has_phys_addr) { 362a37335bcSViacheslav Ovsiienko rte_eal_init_alert("Cannot use IOVA as 'PA' since physical addresses are not available"); 363a37335bcSViacheslav Ovsiienko rte_errno = EINVAL; 364a37335bcSViacheslav Ovsiienko return -1; 365a37335bcSViacheslav Ovsiienko } 366a37335bcSViacheslav Ovsiienko 367a37335bcSViacheslav Ovsiienko if (iova_mode == RTE_IOVA_PA && !RTE_IOVA_IN_MBUF) { 368a37335bcSViacheslav Ovsiienko rte_eal_init_alert("Cannot use IOVA as 'PA' as it is disabled during build"); 369a37335bcSViacheslav Ovsiienko rte_errno = EINVAL; 370a37335bcSViacheslav Ovsiienko return -1; 371a37335bcSViacheslav Ovsiienko } 372a37335bcSViacheslav Ovsiienko 373ae67895bSDavid Marchand EAL_LOG(DEBUG, "Selected IOVA mode '%s'", 3740c8fc83aSDmitry Kozlyuk iova_mode == RTE_IOVA_PA ? "PA" : "VA"); 3750c8fc83aSDmitry Kozlyuk rte_eal_get_configuration()->iova_mode = iova_mode; 3760c8fc83aSDmitry Kozlyuk 37799a2dd95SBruce Richardson if (rte_eal_memzone_init() < 0) { 37899a2dd95SBruce Richardson rte_eal_init_alert("Cannot init memzone"); 37999a2dd95SBruce Richardson rte_errno = ENODEV; 38099a2dd95SBruce Richardson return -1; 38199a2dd95SBruce Richardson } 38299a2dd95SBruce Richardson 3832e2f0272SDavid Marchand rte_mcfg_mem_read_lock(); 3842e2f0272SDavid Marchand 38599a2dd95SBruce Richardson if (rte_eal_memory_init() < 0) { 3862e2f0272SDavid Marchand rte_mcfg_mem_read_unlock(); 38799a2dd95SBruce Richardson rte_eal_init_alert("Cannot init memory"); 38899a2dd95SBruce Richardson rte_errno = ENOMEM; 38999a2dd95SBruce Richardson return -1; 39099a2dd95SBruce Richardson } 39199a2dd95SBruce Richardson 39299a2dd95SBruce Richardson if (rte_eal_malloc_heap_init() < 0) { 3932e2f0272SDavid Marchand rte_mcfg_mem_read_unlock(); 3942e2f0272SDavid Marchand rte_eal_init_alert("Cannot init malloc heap"); 3952e2f0272SDavid Marchand rte_errno = ENODEV; 3962e2f0272SDavid Marchand return -1; 3972e2f0272SDavid Marchand } 3982e2f0272SDavid Marchand 3992e2f0272SDavid Marchand rte_mcfg_mem_read_unlock(); 4002e2f0272SDavid Marchand 4012e2f0272SDavid Marchand if (rte_eal_malloc_heap_populate() < 0) { 40299a2dd95SBruce Richardson rte_eal_init_alert("Cannot init malloc heap"); 40399a2dd95SBruce Richardson rte_errno = ENODEV; 40499a2dd95SBruce Richardson return -1; 40599a2dd95SBruce Richardson } 40699a2dd95SBruce Richardson 40799a2dd95SBruce Richardson if (rte_eal_tailqs_init() < 0) { 40899a2dd95SBruce Richardson rte_eal_init_alert("Cannot init tail queues for objects"); 40999a2dd95SBruce Richardson rte_errno = EFAULT; 41099a2dd95SBruce Richardson return -1; 41199a2dd95SBruce Richardson } 41299a2dd95SBruce Richardson 4138b0a1b8cSTyler Retzlaff if (rte_thread_set_affinity_by_id(rte_thread_self(), 4148001c0ddSTyler Retzlaff &lcore_config[config->main_lcore].cpuset) != 0) { 4158001c0ddSTyler Retzlaff rte_eal_init_alert("Cannot set affinity"); 4168001c0ddSTyler Retzlaff rte_errno = EINVAL; 4178001c0ddSTyler Retzlaff return -1; 4188001c0ddSTyler Retzlaff } 41999a2dd95SBruce Richardson __rte_thread_init(config->main_lcore, 42099a2dd95SBruce Richardson &lcore_config[config->main_lcore].cpuset); 42199a2dd95SBruce Richardson 4228001c0ddSTyler Retzlaff ret = eal_thread_dump_current_affinity(cpuset, sizeof(cpuset)); 423ae67895bSDavid Marchand EAL_LOG(DEBUG, "Main lcore %u is ready (tid=%zx;cpuset=[%s%s])", 424db77fe7dSTyler Retzlaff config->main_lcore, rte_thread_self().opaque_id, cpuset, 4258001c0ddSTyler Retzlaff ret == 0 ? "" : "..."); 4268001c0ddSTyler Retzlaff 42799a2dd95SBruce Richardson RTE_LCORE_FOREACH_WORKER(i) { 42899a2dd95SBruce Richardson 42999a2dd95SBruce Richardson /* 43099a2dd95SBruce Richardson * create communication pipes between main thread 43199a2dd95SBruce Richardson * and children 43299a2dd95SBruce Richardson */ 43399a2dd95SBruce Richardson if (_pipe(lcore_config[i].pipe_main2worker, 43499a2dd95SBruce Richardson sizeof(char), _O_BINARY) < 0) 43599a2dd95SBruce Richardson rte_panic("Cannot create pipe\n"); 43699a2dd95SBruce Richardson if (_pipe(lcore_config[i].pipe_worker2main, 43799a2dd95SBruce Richardson sizeof(char), _O_BINARY) < 0) 43899a2dd95SBruce Richardson rte_panic("Cannot create pipe\n"); 43999a2dd95SBruce Richardson 44099a2dd95SBruce Richardson lcore_config[i].state = WAIT; 44199a2dd95SBruce Richardson 44299a2dd95SBruce Richardson /* create a thread for each lcore */ 4438b0a1b8cSTyler Retzlaff if (rte_thread_create(&lcore_config[i].thread_id, NULL, 4448b0a1b8cSTyler Retzlaff eal_thread_loop, (void *)(uintptr_t)i) != 0) 44599a2dd95SBruce Richardson rte_panic("Cannot create thread\n"); 446c1c8db59STyler Retzlaff 447c1c8db59STyler Retzlaff /* Set thread name for aid in debugging. */ 448c1c8db59STyler Retzlaff snprintf(thread_name, sizeof(thread_name), 44962774b78SThomas Monjalon "dpdk-worker%d", i); 450c1c8db59STyler Retzlaff rte_thread_set_name(lcore_config[i].thread_id, thread_name); 451c1c8db59STyler Retzlaff 4528b0a1b8cSTyler Retzlaff ret = rte_thread_set_affinity_by_id(lcore_config[i].thread_id, 4538b0a1b8cSTyler Retzlaff &lcore_config[i].cpuset); 454416c1befSPallavi Kadam if (ret != 0) 455ae67895bSDavid Marchand EAL_LOG(DEBUG, "Cannot set affinity"); 45699a2dd95SBruce Richardson } 45799a2dd95SBruce Richardson 45899a2dd95SBruce Richardson /* Initialize services so drivers can register services during probe. */ 45999a2dd95SBruce Richardson ret = rte_service_init(); 46099a2dd95SBruce Richardson if (ret) { 46199a2dd95SBruce Richardson rte_eal_init_alert("rte_service_init() failed"); 46299a2dd95SBruce Richardson rte_errno = -ret; 46399a2dd95SBruce Richardson return -1; 46499a2dd95SBruce Richardson } 46599a2dd95SBruce Richardson 46699a2dd95SBruce Richardson if (rte_bus_probe()) { 46799a2dd95SBruce Richardson rte_eal_init_alert("Cannot probe devices"); 46899a2dd95SBruce Richardson rte_errno = ENOTSUP; 46999a2dd95SBruce Richardson return -1; 47099a2dd95SBruce Richardson } 47199a2dd95SBruce Richardson 47299a2dd95SBruce Richardson /* 47399a2dd95SBruce Richardson * Launch a dummy function on all worker lcores, so that main lcore 47499a2dd95SBruce Richardson * knows they are all ready when this function returns. 47599a2dd95SBruce Richardson */ 47699a2dd95SBruce Richardson rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MAIN); 47799a2dd95SBruce Richardson rte_eal_mp_wait_lcore(); 47840032e5eSTyler Retzlaff 47940032e5eSTyler Retzlaff eal_mcfg_complete(); 48040032e5eSTyler Retzlaff 48199a2dd95SBruce Richardson return fctret; 48299a2dd95SBruce Richardson } 48399a2dd95SBruce Richardson 48499a2dd95SBruce Richardson /* Don't use MinGW asprintf() to have identical code with all toolchains. */ 48599a2dd95SBruce Richardson int 48699a2dd95SBruce Richardson eal_asprintf(char **buffer, const char *format, ...) 48799a2dd95SBruce Richardson { 48899a2dd95SBruce Richardson int size, ret; 48999a2dd95SBruce Richardson va_list arg; 49099a2dd95SBruce Richardson 49199a2dd95SBruce Richardson va_start(arg, format); 49299a2dd95SBruce Richardson size = vsnprintf(NULL, 0, format, arg); 49399a2dd95SBruce Richardson va_end(arg); 49499a2dd95SBruce Richardson if (size < 0) 49599a2dd95SBruce Richardson return -1; 49699a2dd95SBruce Richardson size++; 49799a2dd95SBruce Richardson 49899a2dd95SBruce Richardson *buffer = malloc(size); 49999a2dd95SBruce Richardson if (*buffer == NULL) 50099a2dd95SBruce Richardson return -1; 50199a2dd95SBruce Richardson 50299a2dd95SBruce Richardson va_start(arg, format); 50399a2dd95SBruce Richardson ret = vsnprintf(*buffer, size, format, arg); 50499a2dd95SBruce Richardson va_end(arg); 50599a2dd95SBruce Richardson if (ret != size - 1) { 50699a2dd95SBruce Richardson free(*buffer); 50799a2dd95SBruce Richardson return -1; 50899a2dd95SBruce Richardson } 50999a2dd95SBruce Richardson return ret; 51099a2dd95SBruce Richardson } 51199a2dd95SBruce Richardson 51299a2dd95SBruce Richardson int 51399a2dd95SBruce Richardson rte_vfio_container_dma_map(__rte_unused int container_fd, 51499a2dd95SBruce Richardson __rte_unused uint64_t vaddr, 51599a2dd95SBruce Richardson __rte_unused uint64_t iova, 51699a2dd95SBruce Richardson __rte_unused uint64_t len) 51799a2dd95SBruce Richardson { 5184fd15c6aSAnatoly Burakov rte_errno = ENOTSUP; 51999a2dd95SBruce Richardson return -1; 52099a2dd95SBruce Richardson } 52199a2dd95SBruce Richardson 52299a2dd95SBruce Richardson int 52399a2dd95SBruce Richardson rte_vfio_container_dma_unmap(__rte_unused int container_fd, 52499a2dd95SBruce Richardson __rte_unused uint64_t vaddr, 52599a2dd95SBruce Richardson __rte_unused uint64_t iova, 52699a2dd95SBruce Richardson __rte_unused uint64_t len) 52799a2dd95SBruce Richardson { 5284fd15c6aSAnatoly Burakov rte_errno = ENOTSUP; 52999a2dd95SBruce Richardson return -1; 53099a2dd95SBruce Richardson } 53140edb9c0SDavid Marchand 53240edb9c0SDavid Marchand int 53340edb9c0SDavid Marchand rte_firmware_read(__rte_unused const char *name, 53440edb9c0SDavid Marchand __rte_unused void **buf, 53540edb9c0SDavid Marchand __rte_unused size_t *bufsz) 53640edb9c0SDavid Marchand { 53740edb9c0SDavid Marchand return -1; 53840edb9c0SDavid Marchand } 539