LCOV - code coverage report
Current view: top level - lib/eal/linux - eal.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 382 597 64.0 %
Date: 2025-07-01 21:32:37 Functions: 24 28 85.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 195 314 62.1 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2010-2018 Intel Corporation.
       3                 :            :  * Copyright(c) 2012-2014 6WIND S.A.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include <ctype.h>
       7                 :            : #include <stdio.h>
       8                 :            : #include <stdlib.h>
       9                 :            : #include <stdint.h>
      10                 :            : #include <string.h>
      11                 :            : #include <unistd.h>
      12                 :            : #include <pthread.h>
      13                 :            : #include <getopt.h>
      14                 :            : #include <sys/file.h>
      15                 :            : #include <dirent.h>
      16                 :            : #include <fcntl.h>
      17                 :            : #include <fnmatch.h>
      18                 :            : #include <stddef.h>
      19                 :            : #include <errno.h>
      20                 :            : #include <limits.h>
      21                 :            : #include <sys/mman.h>
      22                 :            : #include <sys/stat.h>
      23                 :            : #if defined(RTE_ARCH_X86)
      24                 :            : #include <sys/io.h>
      25                 :            : #endif
      26                 :            : #include <linux/version.h>
      27                 :            : 
      28                 :            : #include <rte_common.h>
      29                 :            : #include <rte_debug.h>
      30                 :            : #include <rte_memory.h>
      31                 :            : #include <rte_launch.h>
      32                 :            : #include <rte_eal.h>
      33                 :            : #include <rte_eal_memconfig.h>
      34                 :            : #include <rte_eal_paging.h>
      35                 :            : #include <rte_errno.h>
      36                 :            : #include <rte_lcore.h>
      37                 :            : #include <rte_service_component.h>
      38                 :            : #include <rte_log.h>
      39                 :            : #include <rte_string_fns.h>
      40                 :            : #include <rte_cpuflags.h>
      41                 :            : #include <rte_bus.h>
      42                 :            : #include <rte_version.h>
      43                 :            : #include <malloc_heap.h>
      44                 :            : #include <rte_vfio.h>
      45                 :            : 
      46                 :            : #include <telemetry_internal.h>
      47                 :            : #include <eal_export.h>
      48                 :            : #include "eal_private.h"
      49                 :            : #include "eal_thread.h"
      50                 :            : #include "eal_lcore_var.h"
      51                 :            : #include "eal_internal_cfg.h"
      52                 :            : #include "eal_filesystem.h"
      53                 :            : #include "eal_hugepages.h"
      54                 :            : #include "eal_memcfg.h"
      55                 :            : #include "eal_trace.h"
      56                 :            : #include "eal_options.h"
      57                 :            : #include "eal_vfio.h"
      58                 :            : #include "hotplug_mp.h"
      59                 :            : #include "log_internal.h"
      60                 :            : 
      61                 :            : #define MEMSIZE_IF_NO_HUGE_PAGE (64ULL * 1024ULL * 1024ULL)
      62                 :            : 
      63                 :            : #define SOCKET_MEM_STRLEN (RTE_MAX_NUMA_NODES * 10)
      64                 :            : 
      65                 :            : #define KERNEL_IOMMU_GROUPS_PATH "/sys/kernel/iommu_groups"
      66                 :            : 
      67                 :            : /* define fd variable here, because file needs to be kept open for the
      68                 :            :  * duration of the program, as we hold a write lock on it in the primary proc */
      69                 :            : static int mem_cfg_fd = -1;
      70                 :            : 
      71                 :            : static struct flock wr_lock = {
      72                 :            :                 .l_type = F_WRLCK,
      73                 :            :                 .l_whence = SEEK_SET,
      74                 :            :                 .l_start = offsetof(struct rte_mem_config, memsegs),
      75                 :            :                 .l_len = RTE_SIZEOF_FIELD(struct rte_mem_config, memsegs),
      76                 :            : };
      77                 :            : 
      78                 :            : /* internal configuration (per-core) */
      79                 :            : struct lcore_config lcore_config[RTE_MAX_LCORE];
      80                 :            : 
      81                 :            : /* used by rte_rdtsc() */
      82                 :            : RTE_EXPORT_SYMBOL(rte_cycles_vmware_tsc_map)
      83                 :            : int rte_cycles_vmware_tsc_map;
      84                 :            : 
      85                 :            : 
      86                 :            : int
      87                 :        175 : eal_clean_runtime_dir(void)
      88                 :            : {
      89                 :        175 :         const char *runtime_dir = rte_eal_get_runtime_dir();
      90                 :            :         DIR *dir;
      91                 :            :         struct dirent *dirent;
      92                 :            :         int dir_fd, fd, lck_result;
      93                 :            :         static const char * const filters[] = {
      94                 :            :                 "fbarray_*",
      95                 :            :                 "mp_socket_*"
      96                 :            :         };
      97                 :            : 
      98                 :            :         /* open directory */
      99                 :        175 :         dir = opendir(runtime_dir);
     100         [ -  + ]:        175 :         if (!dir) {
     101                 :          0 :                 EAL_LOG(ERR, "Unable to open runtime directory %s",
     102                 :            :                                 runtime_dir);
     103                 :          0 :                 goto error;
     104                 :            :         }
     105                 :        175 :         dir_fd = dirfd(dir);
     106                 :            : 
     107                 :            :         /* lock the directory before doing anything, to avoid races */
     108         [ -  + ]:        175 :         if (flock(dir_fd, LOCK_EX) < 0) {
     109                 :          0 :                 EAL_LOG(ERR, "Unable to lock runtime directory %s",
     110                 :            :                         runtime_dir);
     111                 :          0 :                 goto error;
     112                 :            :         }
     113                 :            : 
     114                 :        175 :         dirent = readdir(dir);
     115         [ -  + ]:        175 :         if (!dirent) {
     116                 :          0 :                 EAL_LOG(ERR, "Unable to read runtime directory %s",
     117                 :            :                                 runtime_dir);
     118                 :          0 :                 goto error;
     119                 :            :         }
     120                 :            : 
     121         [ +  + ]:       2349 :         while (dirent != NULL) {
     122                 :            :                 unsigned int f_idx;
     123                 :            :                 bool skip = true;
     124                 :            : 
     125                 :            :                 /* skip files that don't match the patterns */
     126         [ +  + ]:       4043 :                 for (f_idx = 0; f_idx < RTE_DIM(filters); f_idx++) {
     127                 :       3121 :                         const char *filter = filters[f_idx];
     128                 :            : 
     129         [ +  + ]:       3121 :                         if (fnmatch(filter, dirent->d_name, 0) == 0) {
     130                 :            :                                 skip = false;
     131                 :            :                                 break;
     132                 :            :                         }
     133                 :            :                 }
     134         [ +  + ]:       2174 :                 if (skip) {
     135                 :        922 :                         dirent = readdir(dir);
     136                 :        922 :                         continue;
     137                 :            :                 }
     138                 :            : 
     139                 :            :                 /* try and lock the file */
     140                 :       1252 :                 fd = openat(dir_fd, dirent->d_name, O_RDONLY);
     141                 :            : 
     142                 :            :                 /* skip to next file */
     143         [ +  + ]:       1252 :                 if (fd == -1) {
     144                 :         25 :                         dirent = readdir(dir);
     145                 :         25 :                         continue;
     146                 :            :                 }
     147                 :            : 
     148                 :            :                 /* non-blocking lock */
     149                 :       1227 :                 lck_result = flock(fd, LOCK_EX | LOCK_NB);
     150                 :            : 
     151                 :            :                 /* if lock succeeds, remove the file */
     152         [ +  + ]:       1227 :                 if (lck_result != -1)
     153                 :        145 :                         unlinkat(dir_fd, dirent->d_name, 0);
     154                 :       1227 :                 close(fd);
     155                 :       1227 :                 dirent = readdir(dir);
     156                 :            :         }
     157                 :            : 
     158                 :            :         /* closedir closes dir_fd and drops the lock */
     159                 :        175 :         closedir(dir);
     160                 :        175 :         return 0;
     161                 :            : 
     162                 :          0 : error:
     163         [ #  # ]:          0 :         if (dir)
     164                 :          0 :                 closedir(dir);
     165                 :            : 
     166                 :          0 :         EAL_LOG(ERR, "Error while clearing runtime dir: %s",
     167                 :            :                 strerror(errno));
     168                 :            : 
     169                 :          0 :         return -1;
     170                 :            : }
     171                 :            : 
     172                 :            : 
     173                 :            : /* create memory configuration in shared/mmap memory. Take out
     174                 :            :  * a write lock on the memsegs, so we can auto-detect primary/secondary.
     175                 :            :  * This means we never close the file while running (auto-close on exit).
     176                 :            :  * We also don't lock the whole file, so that in future we can use read-locks
     177                 :            :  * on other parts, e.g. memzones, to detect if there are running secondary
     178                 :            :  * processes. */
     179                 :            : static int
     180                 :        160 : rte_eal_config_create(void)
     181                 :            : {
     182                 :        160 :         struct rte_config *config = rte_eal_get_configuration();
     183                 :        160 :         size_t page_sz = rte_mem_page_size();
     184                 :            :         size_t cfg_len = sizeof(*config->mem_config);
     185                 :        160 :         size_t cfg_len_aligned = RTE_ALIGN(cfg_len, page_sz);
     186                 :            :         void *rte_mem_cfg_addr, *mapped_mem_cfg_addr;
     187                 :            :         int retval;
     188                 :            :         const struct internal_config *internal_conf =
     189                 :        160 :                 eal_get_internal_configuration();
     190                 :            : 
     191                 :        160 :         const char *pathname = eal_runtime_config_path();
     192                 :            : 
     193         [ +  + ]:        160 :         if (internal_conf->no_shconf)
     194                 :            :                 return 0;
     195                 :            : 
     196                 :            :         /* map the config before hugepage address so that we don't waste a page */
     197         [ +  + ]:        153 :         if (internal_conf->base_virtaddr != 0)
     198                 :          1 :                 rte_mem_cfg_addr = (void *)
     199                 :          1 :                         RTE_ALIGN_FLOOR(internal_conf->base_virtaddr -
     200                 :            :                         sizeof(struct rte_mem_config), page_sz);
     201                 :            :         else
     202                 :            :                 rte_mem_cfg_addr = NULL;
     203                 :            : 
     204         [ +  - ]:        153 :         if (mem_cfg_fd < 0){
     205                 :        153 :                 mem_cfg_fd = open(pathname, O_RDWR | O_CREAT, 0600);
     206         [ -  + ]:        153 :                 if (mem_cfg_fd < 0) {
     207                 :          0 :                         EAL_LOG(ERR, "Cannot open '%s' for rte_mem_config",
     208                 :            :                                 pathname);
     209                 :          0 :                         return -1;
     210                 :            :                 }
     211                 :            :         }
     212                 :            : 
     213                 :        153 :         retval = ftruncate(mem_cfg_fd, cfg_len);
     214         [ -  + ]:        153 :         if (retval < 0){
     215                 :          0 :                 close(mem_cfg_fd);
     216                 :          0 :                 mem_cfg_fd = -1;
     217                 :          0 :                 EAL_LOG(ERR, "Cannot resize '%s' for rte_mem_config",
     218                 :            :                         pathname);
     219                 :          0 :                 return -1;
     220                 :            :         }
     221                 :            : 
     222                 :        153 :         retval = fcntl(mem_cfg_fd, F_SETLK, &wr_lock);
     223         [ -  + ]:        153 :         if (retval < 0){
     224                 :          0 :                 close(mem_cfg_fd);
     225                 :          0 :                 mem_cfg_fd = -1;
     226                 :          0 :                 EAL_LOG(ERR, "Cannot create lock on '%s'. Is another primary "
     227                 :            :                         "process running?", pathname);
     228                 :          0 :                 return -1;
     229                 :            :         }
     230                 :            : 
     231                 :            :         /* reserve space for config */
     232                 :        153 :         rte_mem_cfg_addr = eal_get_virtual_area(rte_mem_cfg_addr,
     233                 :            :                         &cfg_len_aligned, page_sz, 0, 0);
     234         [ -  + ]:        153 :         if (rte_mem_cfg_addr == NULL) {
     235                 :          0 :                 EAL_LOG(ERR, "Cannot mmap memory for rte_config");
     236                 :          0 :                 close(mem_cfg_fd);
     237                 :          0 :                 mem_cfg_fd = -1;
     238                 :          0 :                 return -1;
     239                 :            :         }
     240                 :            : 
     241                 :            :         /* remap the actual file into the space we've just reserved */
     242                 :        153 :         mapped_mem_cfg_addr = mmap(rte_mem_cfg_addr,
     243                 :            :                         cfg_len_aligned, PROT_READ | PROT_WRITE,
     244                 :            :                         MAP_SHARED | MAP_FIXED, mem_cfg_fd, 0);
     245         [ -  + ]:        153 :         if (mapped_mem_cfg_addr == MAP_FAILED) {
     246                 :          0 :                 munmap(rte_mem_cfg_addr, cfg_len);
     247                 :          0 :                 close(mem_cfg_fd);
     248                 :          0 :                 mem_cfg_fd = -1;
     249                 :          0 :                 EAL_LOG(ERR, "Cannot remap memory for rte_config");
     250                 :          0 :                 return -1;
     251                 :            :         }
     252                 :            : 
     253                 :        153 :         memcpy(rte_mem_cfg_addr, config->mem_config, sizeof(struct rte_mem_config));
     254                 :        153 :         config->mem_config = rte_mem_cfg_addr;
     255                 :            : 
     256                 :            :         /* store address of the config in the config itself so that secondary
     257                 :            :          * processes could later map the config into this exact location
     258                 :            :          */
     259                 :        153 :         config->mem_config->mem_cfg_addr = (uintptr_t) rte_mem_cfg_addr;
     260                 :        153 :         config->mem_config->dma_maskbits = 0;
     261                 :            : 
     262                 :        153 :         return 0;
     263                 :            : }
     264                 :            : 
     265                 :            : /* attach to an existing shared memory config */
     266                 :            : static int
     267                 :         28 : rte_eal_config_attach(void)
     268                 :            : {
     269                 :         28 :         struct rte_config *config = rte_eal_get_configuration();
     270                 :            :         struct rte_mem_config *mem_config;
     271                 :            :         const struct internal_config *internal_conf =
     272                 :         28 :                 eal_get_internal_configuration();
     273                 :            : 
     274                 :         28 :         const char *pathname = eal_runtime_config_path();
     275                 :            : 
     276         [ +  - ]:         28 :         if (internal_conf->no_shconf)
     277                 :            :                 return 0;
     278                 :            : 
     279         [ +  + ]:         28 :         if (mem_cfg_fd < 0){
     280                 :         27 :                 mem_cfg_fd = open(pathname, O_RDWR);
     281         [ +  + ]:         27 :                 if (mem_cfg_fd < 0) {
     282                 :          1 :                         EAL_LOG(ERR, "Cannot open '%s' for rte_mem_config",
     283                 :            :                                 pathname);
     284                 :          1 :                         return -1;
     285                 :            :                 }
     286                 :            :         }
     287                 :            : 
     288                 :            :         /* map it as read-only first */
     289                 :         27 :         mem_config = (struct rte_mem_config *) mmap(NULL, sizeof(*mem_config),
     290                 :            :                         PROT_READ, MAP_SHARED, mem_cfg_fd, 0);
     291         [ -  + ]:         27 :         if (mem_config == MAP_FAILED) {
     292                 :          0 :                 close(mem_cfg_fd);
     293                 :          0 :                 mem_cfg_fd = -1;
     294                 :          0 :                 EAL_LOG(ERR, "Cannot mmap memory for rte_config! error %i (%s)",
     295                 :            :                         errno, strerror(errno));
     296                 :          0 :                 return -1;
     297                 :            :         }
     298                 :            : 
     299                 :         27 :         config->mem_config = mem_config;
     300                 :            : 
     301                 :         27 :         return 0;
     302                 :            : }
     303                 :            : 
     304                 :            : /* reattach the shared config at exact memory location primary process has it */
     305                 :            : static int
     306                 :         27 : rte_eal_config_reattach(void)
     307                 :            : {
     308                 :         27 :         struct rte_config *config = rte_eal_get_configuration();
     309                 :            :         struct rte_mem_config *mem_config;
     310                 :            :         void *rte_mem_cfg_addr;
     311                 :            :         const struct internal_config *internal_conf =
     312                 :         27 :                 eal_get_internal_configuration();
     313                 :            : 
     314         [ +  - ]:         27 :         if (internal_conf->no_shconf)
     315                 :            :                 return 0;
     316                 :            : 
     317                 :            :         /* save the address primary process has mapped shared config to */
     318                 :         27 :         rte_mem_cfg_addr =
     319                 :         27 :                 (void *) (uintptr_t) config->mem_config->mem_cfg_addr;
     320                 :            : 
     321                 :            :         /* unmap original config */
     322                 :         27 :         munmap(config->mem_config, sizeof(struct rte_mem_config));
     323                 :            : 
     324                 :            :         /* remap the config at proper address */
     325                 :         27 :         mem_config = (struct rte_mem_config *) mmap(rte_mem_cfg_addr,
     326                 :            :                         sizeof(*mem_config), PROT_READ | PROT_WRITE, MAP_SHARED,
     327                 :            :                         mem_cfg_fd, 0);
     328                 :            : 
     329                 :         27 :         close(mem_cfg_fd);
     330                 :         27 :         mem_cfg_fd = -1;
     331                 :            : 
     332         [ -  + ]:         27 :         if (mem_config == MAP_FAILED || mem_config != rte_mem_cfg_addr) {
     333         [ #  # ]:          0 :                 if (mem_config != MAP_FAILED) {
     334                 :            :                         /* errno is stale, don't use */
     335                 :          0 :                         EAL_LOG(ERR, "Cannot mmap memory for rte_config at [%p], got [%p]"
     336                 :            :                                 " - please use '--" OPT_BASE_VIRTADDR
     337                 :            :                                 "' option", rte_mem_cfg_addr, mem_config);
     338                 :          0 :                         munmap(mem_config, sizeof(struct rte_mem_config));
     339                 :          0 :                         return -1;
     340                 :            :                 }
     341                 :          0 :                 EAL_LOG(ERR, "Cannot mmap memory for rte_config! error %i (%s)",
     342                 :            :                         errno, strerror(errno));
     343                 :          0 :                 return -1;
     344                 :            :         }
     345                 :            : 
     346                 :         27 :         config->mem_config = mem_config;
     347                 :            : 
     348                 :         27 :         return 0;
     349                 :            : }
     350                 :            : 
     351                 :            : /* Detect if we are a primary or a secondary process */
     352                 :            : enum rte_proc_type_t
     353                 :          3 : eal_proc_type_detect(void)
     354                 :            : {
     355                 :            :         enum rte_proc_type_t ptype = RTE_PROC_PRIMARY;
     356                 :          3 :         const char *pathname = eal_runtime_config_path();
     357                 :            :         const struct internal_config *internal_conf =
     358                 :          3 :                 eal_get_internal_configuration();
     359                 :            : 
     360                 :            :         /* if there no shared config, there can be no secondary processes */
     361         [ +  + ]:          3 :         if (!internal_conf->no_shconf) {
     362                 :            :                 /* if we can open the file but not get a write-lock we are a
     363                 :            :                  * secondary process. NOTE: if we get a file handle back, we
     364                 :            :                  * keep that open and don't close it to prevent a race condition
     365                 :            :                  * between multiple opens.
     366                 :            :                  */
     367   [ +  +  +  - ]:          3 :                 if (((mem_cfg_fd = open(pathname, O_RDWR)) >= 0) &&
     368                 :          1 :                                 (fcntl(mem_cfg_fd, F_SETLK, &wr_lock) < 0))
     369                 :            :                         ptype = RTE_PROC_SECONDARY;
     370                 :            :         }
     371                 :            : 
     372                 :          3 :         EAL_LOG(INFO, "Auto-detected process type: %s",
     373                 :            :                         ptype == RTE_PROC_PRIMARY ? "PRIMARY" : "SECONDARY");
     374                 :            : 
     375                 :          3 :         return ptype;
     376                 :            : }
     377                 :            : 
     378                 :            : /* Sets up rte_config structure with the pointer to shared memory config.*/
     379                 :            : static int
     380                 :        188 : rte_config_init(void)
     381                 :            : {
     382                 :        188 :         struct rte_config *config = rte_eal_get_configuration();
     383                 :            :         const struct internal_config *internal_conf =
     384                 :        188 :                 eal_get_internal_configuration();
     385                 :            : 
     386                 :        188 :         config->process_type = internal_conf->process_type;
     387                 :            : 
     388   [ +  +  -  - ]:        188 :         switch (config->process_type) {
     389                 :        160 :         case RTE_PROC_PRIMARY:
     390         [ +  - ]:        160 :                 if (rte_eal_config_create() < 0)
     391                 :            :                         return -1;
     392                 :        160 :                 eal_mcfg_update_from_internal();
     393                 :        160 :                 break;
     394                 :         28 :         case RTE_PROC_SECONDARY:
     395         [ +  + ]:         28 :                 if (rte_eal_config_attach() < 0)
     396                 :            :                         return -1;
     397                 :         27 :                 eal_mcfg_wait_complete();
     398         [ -  + ]:         27 :                 if (eal_mcfg_check_version() < 0) {
     399                 :          0 :                         EAL_LOG(ERR, "Primary and secondary process DPDK version mismatch");
     400                 :          0 :                         return -1;
     401                 :            :                 }
     402         [ +  - ]:         27 :                 if (rte_eal_config_reattach() < 0)
     403                 :            :                         return -1;
     404         [ -  + ]:         27 :                 if (!__rte_mp_enable()) {
     405                 :          0 :                         EAL_LOG(ERR, "Primary process refused secondary attachment");
     406                 :          0 :                         return -1;
     407                 :            :                 }
     408                 :         27 :                 eal_mcfg_update_internal();
     409                 :         27 :                 break;
     410                 :          0 :         case RTE_PROC_AUTO:
     411                 :            :         case RTE_PROC_INVALID:
     412                 :          0 :                 EAL_LOG(ERR, "Invalid process type %d",
     413                 :            :                         config->process_type);
     414                 :          0 :                 return -1;
     415                 :            :         }
     416                 :            : 
     417                 :            :         return 0;
     418                 :            : }
     419                 :            : 
     420                 :            : /* Unlocks hugepage directories that were locked by eal_hugepage_info_init */
     421                 :            : static void
     422                 :        182 : eal_hugedirs_unlock(void)
     423                 :            : {
     424                 :            :         int i;
     425                 :            :         struct internal_config *internal_conf =
     426                 :        182 :                 eal_get_internal_configuration();
     427                 :            : 
     428         [ +  + ]:        728 :         for (i = 0; i < MAX_HUGEPAGE_SIZES; i++)
     429                 :            :         {
     430                 :            :                 /* skip uninitialized */
     431         [ +  + ]:        546 :                 if (internal_conf->hugepage_info[i].lock_descriptor < 0)
     432                 :        490 :                         continue;
     433                 :            :                 /* unlock hugepage file */
     434                 :         56 :                 flock(internal_conf->hugepage_info[i].lock_descriptor, LOCK_UN);
     435                 :         56 :                 close(internal_conf->hugepage_info[i].lock_descriptor);
     436                 :            :                 /* reset the field */
     437                 :         56 :                 internal_conf->hugepage_info[i].lock_descriptor = -1;
     438                 :            :         }
     439                 :        182 : }
     440                 :            : 
     441                 :            : /* display usage */
     442                 :            : static void
     443                 :         50 : eal_usage(const char *prgname)
     444                 :            : {
     445                 :         50 :         rte_usage_hook_t hook = eal_get_application_usage_hook();
     446                 :            : 
     447                 :            :         printf("\nUsage: %s ", prgname);
     448                 :         50 :         eal_common_usage();
     449                 :            :         printf("EAL Linux options:\n"
     450                 :            :                "  --"OPT_NUMA_MEM"        Memory to allocate on NUMA nodes (comma separated values)\n"
     451                 :            :                "  --"OPT_NUMA_LIMIT"      Limit memory allocation on NUMA nodes (comma separated values)\n"
     452                 :            :                "  --"OPT_HUGE_DIR"          Directory where hugetlbfs is mounted\n"
     453                 :            :                "  --"OPT_FILE_PREFIX"       Prefix for hugepage filenames\n"
     454                 :            :                "  --"OPT_CREATE_UIO_DEV"    Create /dev/uioX (usually done by hotplug)\n"
     455                 :            :                "  --"OPT_VFIO_INTR"         Interrupt mode for VFIO (legacy|msi|msix)\n"
     456                 :            :                "  --"OPT_VFIO_VF_TOKEN"     VF token (UUID) shared between SR-IOV PF and VFs\n"
     457                 :            :                "  --"OPT_LEGACY_MEM"        Legacy memory mode (no dynamic allocation, contiguous segments)\n"
     458                 :            :                "  --"OPT_SINGLE_FILE_SEGMENTS" Put all hugepage memory in single files\n"
     459                 :            :                "  --"OPT_MATCH_ALLOCATIONS" Free hugepages exactly as allocated\n"
     460                 :            :                "  --"OPT_HUGE_WORKER_STACK"[=size]\n"
     461                 :            :                "                      Allocate worker thread stacks from hugepage memory.\n"
     462                 :            :                "                      Size is in units of kbytes and defaults to system\n"
     463                 :            :                "                      thread stack size if not specified.\n"
     464                 :            :                "\n");
     465                 :            :         /* Allow the application to print its usage message too if hook is set */
     466         [ -  + ]:         50 :         if (hook) {
     467                 :            :                 printf("===== Application Usage =====\n\n");
     468                 :          0 :                 (hook)(prgname);
     469                 :            :         }
     470                 :         50 : }
     471                 :            : 
     472                 :            : static int
     473                 :         10 : eal_parse_socket_arg(char *strval, volatile uint64_t *socket_arg)
     474                 :            : {
     475                 :            :         char * arg[RTE_MAX_NUMA_NODES];
     476                 :            :         char *end;
     477                 :            :         int arg_num, i, len;
     478                 :            : 
     479                 :         10 :         len = strnlen(strval, SOCKET_MEM_STRLEN);
     480         [ -  + ]:         10 :         if (len == SOCKET_MEM_STRLEN) {
     481                 :          0 :                 EAL_LOG(ERR, "--socket-mem is too long");
     482                 :          0 :                 return -1;
     483                 :            :         }
     484                 :            : 
     485                 :            :         /* all other error cases will be caught later */
     486         [ +  + ]:         10 :         if (!isdigit(strval[len-1]))
     487                 :            :                 return -1;
     488                 :            : 
     489                 :            :         /* split the optarg into separate socket values */
     490                 :          7 :         arg_num = rte_strsplit(strval, len,
     491                 :            :                         arg, RTE_MAX_NUMA_NODES, ',');
     492                 :            : 
     493                 :            :         /* if split failed, or 0 arguments */
     494         [ +  - ]:          7 :         if (arg_num <= 0)
     495                 :            :                 return -1;
     496                 :            : 
     497                 :            :         /* parse each defined socket option */
     498                 :          7 :         errno = 0;
     499         [ +  + ]:         19 :         for (i = 0; i < arg_num; i++) {
     500                 :            :                 uint64_t val;
     501                 :         13 :                 end = NULL;
     502                 :         13 :                 val = strtoull(arg[i], &end, 10);
     503                 :            : 
     504                 :            :                 /* check for invalid input */
     505         [ +  - ]:         13 :                 if ((errno != 0)  ||
     506   [ +  -  +  -  :         13 :                                 (arg[i][0] == '\0') || (end == NULL) || (*end != '\0'))
                   +  + ]
     507                 :            :                         return -1;
     508                 :         12 :                 val <<= 20;
     509                 :         12 :                 socket_arg[i] = val;
     510                 :            :         }
     511                 :            : 
     512                 :            :         return 0;
     513                 :            : }
     514                 :            : 
     515                 :            : static int
     516                 :          4 : eal_parse_vfio_intr(const char *mode)
     517                 :            : {
     518                 :            :         struct internal_config *internal_conf =
     519                 :          4 :                 eal_get_internal_configuration();
     520                 :            :         unsigned i;
     521                 :            :         static struct {
     522                 :            :                 const char *name;
     523                 :            :                 enum rte_intr_mode value;
     524                 :            :         } map[] = {
     525                 :            :                 { "legacy", RTE_INTR_MODE_LEGACY },
     526                 :            :                 { "msi", RTE_INTR_MODE_MSI },
     527                 :            :                 { "msix", RTE_INTR_MODE_MSIX },
     528                 :            :         };
     529                 :            : 
     530         [ +  + ]:         10 :         for (i = 0; i < RTE_DIM(map); i++) {
     531         [ +  + ]:          9 :                 if (!strcmp(mode, map[i].name)) {
     532                 :          3 :                         internal_conf->vfio_intr_mode = map[i].value;
     533                 :          3 :                         return 0;
     534                 :            :                 }
     535                 :            :         }
     536                 :            :         return -1;
     537                 :            : }
     538                 :            : 
     539                 :            : static int
     540                 :          0 : eal_parse_vfio_vf_token(const char *vf_token)
     541                 :            : {
     542                 :          0 :         struct internal_config *cfg = eal_get_internal_configuration();
     543                 :            :         rte_uuid_t uuid;
     544                 :            : 
     545         [ #  # ]:          0 :         if (!rte_uuid_parse(vf_token, uuid)) {
     546                 :          0 :                 rte_uuid_copy(cfg->vfio_vf_token, uuid);
     547                 :          0 :                 return 0;
     548                 :            :         }
     549                 :            : 
     550                 :            :         return -1;
     551                 :            : }
     552                 :            : 
     553                 :            : static int
     554                 :          4 : eal_parse_huge_worker_stack(const char *arg)
     555                 :            : {
     556                 :          4 :         struct internal_config *cfg = eal_get_internal_configuration();
     557                 :            : 
     558   [ +  +  -  + ]:          6 :         if (arg == NULL || arg[0] == '\0') {
     559                 :            :                 pthread_attr_t attr;
     560                 :            :                 int ret;
     561                 :            : 
     562         [ -  + ]:          2 :                 if (pthread_attr_init(&attr) != 0) {
     563                 :          0 :                         EAL_LOG(ERR, "Could not retrieve default stack size");
     564                 :          0 :                         return -1;
     565                 :            :                 }
     566                 :          2 :                 ret = pthread_attr_getstacksize(&attr, &cfg->huge_worker_stack_size);
     567                 :          2 :                 pthread_attr_destroy(&attr);
     568         [ -  + ]:          2 :                 if (ret != 0) {
     569                 :          0 :                         EAL_LOG(ERR, "Could not retrieve default stack size");
     570                 :          0 :                         return -1;
     571                 :            :                 }
     572                 :            :         } else {
     573                 :            :                 unsigned long stack_size;
     574                 :            :                 char *end;
     575                 :            : 
     576                 :          2 :                 errno = 0;
     577                 :          2 :                 stack_size = strtoul(arg, &end, 10);
     578   [ +  -  +  -  :          2 :                 if (errno || end == NULL || stack_size == 0 ||
                   -  + ]
     579                 :            :                                 stack_size >= (size_t)-1 / 1024)
     580                 :          0 :                         return -1;
     581                 :            : 
     582                 :          2 :                 cfg->huge_worker_stack_size = stack_size * 1024;
     583                 :            :         }
     584                 :            : 
     585                 :          4 :         EAL_LOG(DEBUG, "Each worker thread will use %zu kB of DPDK memory as stack",
     586                 :            :                 cfg->huge_worker_stack_size / 1024);
     587                 :          4 :         return 0;
     588                 :            : }
     589                 :            : 
     590                 :            : /* Parse the argument given in the command line of the application */
     591                 :            : static int
     592                 :        251 : eal_parse_args(int argc, char **argv)
     593                 :            : {
     594                 :            :         int opt, ret;
     595                 :            :         char **argvopt;
     596                 :            :         int option_index;
     597                 :        251 :         char *prgname = argv[0];
     598                 :        251 :         const int old_optind = optind;
     599                 :        251 :         const int old_optopt = optopt;
     600                 :        251 :         char * const old_optarg = optarg;
     601                 :            :         struct internal_config *internal_conf =
     602                 :        251 :                 eal_get_internal_configuration();
     603                 :            : 
     604                 :            :         argvopt = argv;
     605                 :        251 :         optind = 1;
     606                 :            : 
     607                 :        766 :         while ((opt = getopt_long(argc, argvopt, eal_short_options,
     608         [ +  + ]:        766 :                                   eal_long_options, &option_index)) != EOF) {
     609                 :            : 
     610                 :            :                 /* getopt didn't recognise the option */
     611         [ +  + ]:        558 :                 if (opt == '?') {
     612                 :          7 :                         eal_usage(prgname);
     613                 :            :                         ret = -1;
     614                 :          7 :                         goto out;
     615                 :            :                 }
     616                 :            : 
     617                 :            :                 /* eal_parse_log_options() already handled this option */
     618         [ +  + ]:        551 :                 if (eal_option_is_log(opt))
     619                 :          6 :                         continue;
     620                 :            : 
     621                 :        545 :                 ret = eal_parse_common_option(opt, optarg, internal_conf);
     622                 :            :                 /* common parser is not happy */
     623         [ +  + ]:        545 :                 if (ret < 0) {
     624                 :         31 :                         eal_usage(prgname);
     625                 :            :                         ret = -1;
     626                 :         31 :                         goto out;
     627                 :            :                 }
     628                 :            :                 /* common parser handled this option */
     629         [ +  + ]:        514 :                 if (ret == 0)
     630                 :        368 :                         continue;
     631                 :            : 
     632   [ -  +  +  +  :        146 :                 switch (opt) {
          -  +  -  +  -  
                -  +  - ]
     633                 :          0 :                 case OPT_HELP_NUM:
     634                 :          0 :                         eal_usage(prgname);
     635                 :          0 :                         exit(EXIT_SUCCESS);
     636                 :            : 
     637                 :          5 :                 case OPT_HUGE_DIR_NUM:
     638                 :            :                 {
     639                 :          5 :                         char *hdir = strdup(optarg);
     640         [ -  + ]:          5 :                         if (hdir == NULL)
     641                 :          0 :                                 EAL_LOG(ERR, "Could not store hugepage directory");
     642                 :            :                         else {
     643                 :            :                                 /* free old hugepage dir */
     644                 :          5 :                                 free(internal_conf->hugepage_dir);
     645                 :          5 :                                 internal_conf->hugepage_dir = hdir;
     646                 :            :                         }
     647                 :            :                         break;
     648                 :            :                 }
     649                 :        122 :                 case OPT_FILE_PREFIX_NUM:
     650                 :            :                 {
     651                 :        122 :                         char *prefix = strdup(optarg);
     652         [ -  + ]:        122 :                         if (prefix == NULL)
     653                 :          0 :                                 EAL_LOG(ERR, "Could not store file prefix");
     654                 :            :                         else {
     655                 :            :                                 /* free old prefix */
     656                 :        122 :                                 free(internal_conf->hugefile_prefix);
     657                 :        122 :                                 internal_conf->hugefile_prefix = prefix;
     658                 :            :                         }
     659                 :            :                         break;
     660                 :            :                 }
     661                 :         10 :                 case OPT_NUMA_MEM_NUM:
     662         [ +  + ]:         10 :                         if (eal_parse_socket_arg(optarg,
     663                 :         10 :                                         internal_conf->numa_mem) < 0) {
     664                 :          4 :                                 EAL_LOG(ERR, "invalid parameters for --"
     665                 :            :                                                 OPT_NUMA_MEM
     666                 :            :                                                 " (aka --"
     667                 :            :                                                 OPT_SOCKET_MEM
     668                 :            :                                                 ")");
     669                 :          4 :                                 eal_usage(prgname);
     670                 :            :                                 ret = -1;
     671                 :          4 :                                 goto out;
     672                 :            :                         }
     673                 :          6 :                         internal_conf->force_numa = 1;
     674                 :          6 :                         break;
     675                 :            : 
     676                 :          0 :                 case OPT_NUMA_LIMIT_NUM:
     677         [ #  # ]:          0 :                         if (eal_parse_socket_arg(optarg,
     678                 :          0 :                                         internal_conf->numa_limit) < 0) {
     679                 :          0 :                                 EAL_LOG(ERR, "invalid parameters for --"
     680                 :            :                                                 OPT_NUMA_LIMIT
     681                 :            :                                                 " (aka --"
     682                 :            :                                                 OPT_SOCKET_LIMIT
     683                 :            :                                                 ")");
     684                 :          0 :                                 eal_usage(prgname);
     685                 :            :                                 ret = -1;
     686                 :          0 :                                 goto out;
     687                 :            :                         }
     688                 :          0 :                         internal_conf->force_numa_limits = 1;
     689                 :          0 :                         break;
     690                 :            : 
     691                 :          4 :                 case OPT_VFIO_INTR_NUM:
     692         [ +  + ]:          4 :                         if (eal_parse_vfio_intr(optarg) < 0) {
     693                 :          1 :                                 EAL_LOG(ERR, "invalid parameters for --"
     694                 :            :                                                 OPT_VFIO_INTR);
     695                 :          1 :                                 eal_usage(prgname);
     696                 :            :                                 ret = -1;
     697                 :          1 :                                 goto out;
     698                 :            :                         }
     699                 :            :                         break;
     700                 :            : 
     701                 :          0 :                 case OPT_VFIO_VF_TOKEN_NUM:
     702         [ #  # ]:          0 :                         if (eal_parse_vfio_vf_token(optarg) < 0) {
     703                 :          0 :                                 EAL_LOG(ERR, "invalid parameters for --"
     704                 :            :                                                 OPT_VFIO_VF_TOKEN);
     705                 :          0 :                                 eal_usage(prgname);
     706                 :            :                                 ret = -1;
     707                 :          0 :                                 goto out;
     708                 :            :                         }
     709                 :            :                         break;
     710                 :            : 
     711                 :          1 :                 case OPT_CREATE_UIO_DEV_NUM:
     712                 :          1 :                         internal_conf->create_uio_dev = 1;
     713                 :          1 :                         break;
     714                 :            : 
     715                 :          0 :                 case OPT_MBUF_POOL_OPS_NAME_NUM:
     716                 :            :                 {
     717                 :          0 :                         char *ops_name = strdup(optarg);
     718         [ #  # ]:          0 :                         if (ops_name == NULL)
     719                 :          0 :                                 EAL_LOG(ERR, "Could not store mbuf pool ops name");
     720                 :            :                         else {
     721                 :            :                                 /* free old ops name */
     722                 :          0 :                                 free(internal_conf->user_mbuf_pool_ops_name);
     723                 :            : 
     724                 :          0 :                                 internal_conf->user_mbuf_pool_ops_name =
     725                 :            :                                                 ops_name;
     726                 :            :                         }
     727                 :            :                         break;
     728                 :            :                 }
     729                 :          0 :                 case OPT_MATCH_ALLOCATIONS_NUM:
     730                 :          0 :                         internal_conf->match_allocations = 1;
     731                 :          0 :                         break;
     732                 :            : 
     733                 :          4 :                 case OPT_HUGE_WORKER_STACK_NUM:
     734         [ -  + ]:          4 :                         if (eal_parse_huge_worker_stack(optarg) < 0) {
     735                 :          0 :                                 EAL_LOG(ERR, "invalid parameter for --"
     736                 :            :                                         OPT_HUGE_WORKER_STACK);
     737                 :          0 :                                 eal_usage(prgname);
     738                 :            :                                 ret = -1;
     739                 :          0 :                                 goto out;
     740                 :            :                         }
     741                 :            :                         break;
     742                 :            : 
     743                 :          0 :                 default:
     744   [ #  #  #  # ]:          0 :                         if (opt < OPT_LONG_MIN_NUM && isprint(opt)) {
     745                 :          0 :                                 EAL_LOG(ERR, "Option %c is not supported "
     746                 :            :                                         "on Linux", opt);
     747         [ #  # ]:          0 :                         } else if (opt >= OPT_LONG_MIN_NUM &&
     748                 :            :                                    opt < OPT_LONG_MAX_NUM) {
     749                 :          0 :                                 EAL_LOG(ERR, "Option %s is not supported "
     750                 :            :                                         "on Linux",
     751                 :            :                                         eal_long_options[option_index].name);
     752                 :            :                         } else {
     753                 :          0 :                                 EAL_LOG(ERR, "Option %d is not supported "
     754                 :            :                                         "on Linux", opt);
     755                 :            :                         }
     756                 :          0 :                         eal_usage(prgname);
     757                 :            :                         ret = -1;
     758                 :          0 :                         goto out;
     759                 :            :                 }
     760                 :            :         }
     761                 :            : 
     762                 :            :         /* create runtime data directory. In no_shconf mode, skip any errors */
     763         [ -  + ]:        208 :         if (eal_create_runtime_dir() < 0) {
     764         [ #  # ]:          0 :                 if (internal_conf->no_shconf == 0) {
     765                 :          0 :                         EAL_LOG(ERR, "Cannot create runtime directory");
     766                 :            :                         ret = -1;
     767                 :          0 :                         goto out;
     768                 :            :                 } else
     769                 :          0 :                         EAL_LOG(WARNING, "No DPDK runtime directory created");
     770                 :            :         }
     771                 :            : 
     772         [ -  + ]:        208 :         if (eal_adjust_config(internal_conf) != 0) {
     773                 :            :                 ret = -1;
     774                 :          0 :                 goto out;
     775                 :            :         }
     776                 :            : 
     777                 :            :         /* sanity checks */
     778         [ +  + ]:        208 :         if (eal_check_common_options(internal_conf) != 0) {
     779                 :          7 :                 eal_usage(prgname);
     780                 :            :                 ret = -1;
     781                 :          7 :                 goto out;
     782                 :            :         }
     783                 :            : 
     784         [ +  - ]:        201 :         if (optind >= 0)
     785                 :        201 :                 argv[optind-1] = prgname;
     786                 :        201 :         ret = optind-1;
     787                 :            : 
     788                 :        251 : out:
     789                 :            :         /* restore getopt lib */
     790                 :        251 :         optind = old_optind;
     791                 :        251 :         optopt = old_optopt;
     792                 :        251 :         optarg = old_optarg;
     793                 :            : 
     794                 :        251 :         return ret;
     795                 :            : }
     796                 :            : 
     797                 :            : static int
     798                 :        182 : check_socket(const struct rte_memseg_list *msl, void *arg)
     799                 :            : {
     800                 :            :         int *socket_id = arg;
     801                 :            : 
     802         [ +  - ]:        182 :         if (msl->external)
     803                 :            :                 return 0;
     804                 :            : 
     805                 :        182 :         return *socket_id == msl->socket_id;
     806                 :            : }
     807                 :            : 
     808                 :            : static void
     809                 :        182 : eal_check_mem_on_local_socket(void)
     810                 :            : {
     811                 :            :         int socket_id;
     812                 :        182 :         const struct rte_config *config = rte_eal_get_configuration();
     813                 :            : 
     814                 :        182 :         socket_id = rte_lcore_to_socket_id(config->main_lcore);
     815                 :            : 
     816         [ -  + ]:        182 :         if (rte_memseg_list_walk(check_socket, &socket_id) == 0)
     817                 :          0 :                 EAL_LOG(WARNING, "WARNING: Main core has no memory on local socket!");
     818                 :        182 : }
     819                 :            : 
     820                 :            : static int
     821                 :        130 : sync_func(__rte_unused void *arg)
     822                 :            : {
     823                 :        130 :         return 0;
     824                 :            : }
     825                 :            : 
     826                 :            : /*
     827                 :            :  * Request iopl privilege for all RPL, returns 0 on success
     828                 :            :  * iopl() call is mostly for the i386 architecture. For other architectures,
     829                 :            :  * return -1 to indicate IO privilege can't be changed in this way.
     830                 :            :  */
     831                 :            : RTE_EXPORT_SYMBOL(rte_eal_iopl_init)
     832                 :            : int
     833                 :        254 : rte_eal_iopl_init(void)
     834                 :            : {
     835                 :            : #if defined(RTE_ARCH_X86)
     836         [ -  + ]:        254 :         if (iopl(3) != 0)
     837                 :          0 :                 return -1;
     838                 :            : #endif
     839                 :            :         return 0;
     840                 :            : }
     841                 :            : 
     842                 :         61 : static void rte_eal_init_alert(const char *msg)
     843                 :            : {
     844                 :         61 :         EAL_LOG(ALERT, "%s", msg);
     845                 :         61 : }
     846                 :            : 
     847                 :            : /*
     848                 :            :  * On Linux 3.6+, even if VFIO is not loaded, whenever IOMMU is enabled in the
     849                 :            :  * BIOS and in the kernel, /sys/kernel/iommu_groups path will contain kernel
     850                 :            :  * IOMMU groups. If IOMMU is not enabled, that path would be empty.
     851                 :            :  * Therefore, checking if the path is empty will tell us if IOMMU is enabled.
     852                 :            :  */
     853                 :            : static bool
     854                 :         86 : is_iommu_enabled(void)
     855                 :            : {
     856                 :         86 :         DIR *dir = opendir(KERNEL_IOMMU_GROUPS_PATH);
     857                 :            :         struct dirent *d;
     858                 :            :         int n = 0;
     859                 :            : 
     860                 :            :         /* if directory doesn't exist, assume IOMMU is not enabled */
     861         [ +  - ]:         86 :         if (dir == NULL)
     862                 :            :                 return false;
     863                 :            : 
     864         [ +  + ]:        258 :         while ((d = readdir(dir)) != NULL) {
     865                 :            :                 /* skip dot and dot-dot */
     866         [ +  - ]:        172 :                 if (++n > 2)
     867                 :            :                         break;
     868                 :            :         }
     869                 :         86 :         closedir(dir);
     870                 :            : 
     871                 :         86 :         return n > 2;
     872                 :            : }
     873                 :            : 
     874                 :            : static __rte_noreturn void *
     875                 :        130 : eal_worker_thread_loop(void *arg)
     876                 :            : {
     877                 :        130 :         eal_thread_loop(arg);
     878                 :            : }
     879                 :            : 
     880                 :            : static int
     881                 :        130 : eal_worker_thread_create(unsigned int lcore_id)
     882                 :            : {
     883                 :            :         pthread_attr_t *attrp = NULL;
     884                 :            :         void *stack_ptr = NULL;
     885                 :            :         pthread_attr_t attr;
     886                 :            :         size_t stack_size;
     887                 :            :         int ret = -1;
     888                 :            : 
     889                 :        130 :         stack_size = eal_get_internal_configuration()->huge_worker_stack_size;
     890         [ -  + ]:        130 :         if (stack_size != 0) {
     891                 :            :                 /* Allocate NUMA aware stack memory and set pthread attributes */
     892                 :          0 :                 stack_ptr = rte_zmalloc_socket("lcore_stack", stack_size,
     893                 :          0 :                         RTE_CACHE_LINE_SIZE, rte_lcore_to_socket_id(lcore_id));
     894         [ #  # ]:          0 :                 if (stack_ptr == NULL) {
     895                 :          0 :                         rte_eal_init_alert("Cannot allocate worker lcore stack memory");
     896                 :          0 :                         rte_errno = ENOMEM;
     897                 :          0 :                         goto out;
     898                 :            :                 }
     899                 :            : 
     900         [ #  # ]:          0 :                 if (pthread_attr_init(&attr) != 0) {
     901                 :          0 :                         rte_eal_init_alert("Cannot init pthread attributes");
     902                 :          0 :                         rte_errno = EFAULT;
     903                 :          0 :                         goto out;
     904                 :            :                 }
     905                 :            :                 attrp = &attr;
     906                 :            : 
     907         [ #  # ]:          0 :                 if (pthread_attr_setstack(attrp, stack_ptr, stack_size) != 0) {
     908                 :          0 :                         rte_eal_init_alert("Cannot set pthread stack attributes");
     909                 :          0 :                         rte_errno = EFAULT;
     910                 :          0 :                         goto out;
     911                 :            :                 }
     912                 :            :         }
     913                 :            : 
     914         [ -  + ]:        130 :         if (pthread_create((pthread_t *)&lcore_config[lcore_id].thread_id.opaque_id,
     915                 :        130 :                         attrp, eal_worker_thread_loop, (void *)(uintptr_t)lcore_id) == 0)
     916                 :            :                 ret = 0;
     917                 :            : 
     918                 :          0 : out:
     919         [ -  + ]:        130 :         if (ret != 0)
     920                 :          0 :                 rte_free(stack_ptr);
     921         [ -  + ]:        130 :         if (attrp != NULL)
     922                 :          0 :                 pthread_attr_destroy(attrp);
     923                 :        130 :         return ret;
     924                 :            : }
     925                 :            : 
     926                 :            : /* Launch threads, called at application init(). */
     927                 :            : RTE_EXPORT_SYMBOL(rte_eal_init)
     928                 :            : int
     929                 :        256 : rte_eal_init(int argc, char **argv)
     930                 :            : {
     931                 :            :         int i, fctret, ret;
     932                 :            :         static RTE_ATOMIC(uint32_t) run_once;
     933                 :            :         uint32_t has_run = 0;
     934                 :            :         char cpuset[RTE_CPU_AFFINITY_STR_LEN];
     935                 :            :         char thread_name[RTE_THREAD_NAME_SIZE];
     936                 :            :         bool phys_addrs;
     937                 :        256 :         const struct rte_config *config = rte_eal_get_configuration();
     938                 :            :         struct internal_config *internal_conf =
     939                 :        255 :                 eal_get_internal_configuration();
     940                 :            : 
     941                 :            :         /* setup log as early as possible */
     942         [ +  + ]:        255 :         if (eal_parse_log_options(argc, argv) < 0) {
     943                 :          3 :                 rte_eal_init_alert("invalid log arguments.");
     944                 :          3 :                 rte_errno = EINVAL;
     945                 :          3 :                 return -1;
     946                 :            :         }
     947                 :            : 
     948                 :        252 :         eal_log_init(program_invocation_short_name);
     949                 :            : 
     950                 :            :         /* checks if the machine is adequate */
     951         [ -  + ]:        253 :         if (!rte_cpu_is_supported()) {
     952                 :          0 :                 rte_eal_init_alert("unsupported cpu type.");
     953                 :          0 :                 rte_errno = ENOTSUP;
     954                 :          0 :                 return -1;
     955                 :            :         }
     956                 :            : 
     957                 :            :         /* verify if DPDK supported on architecture MMU */
     958         [ -  + ]:        252 :         if (!eal_mmu_supported()) {
     959                 :          0 :                 rte_eal_init_alert("unsupported MMU type.");
     960                 :          0 :                 rte_errno = ENOTSUP;
     961                 :          0 :                 return -1;
     962                 :            :         }
     963                 :            : 
     964         [ +  + ]:        253 :         if (!rte_atomic_compare_exchange_strong_explicit(&run_once, &has_run, 1,
     965                 :            :                                         rte_memory_order_relaxed, rte_memory_order_relaxed)) {
     966                 :          1 :                 rte_eal_init_alert("already called initialization.");
     967                 :          2 :                 rte_errno = EALREADY;
     968                 :          2 :                 return -1;
     969                 :            :         }
     970                 :            : 
     971                 :        252 :         eal_reset_internal_config(internal_conf);
     972                 :            : 
     973                 :            :         /* clone argv to report out later in telemetry */
     974                 :        251 :         eal_save_args(argc, argv);
     975                 :            : 
     976         [ -  + ]:        251 :         if (rte_eal_cpu_init() < 0) {
     977                 :          0 :                 rte_eal_init_alert("Cannot detect lcores.");
     978                 :          0 :                 rte_errno = ENOTSUP;
     979                 :          0 :                 return -1;
     980                 :            :         }
     981                 :            : 
     982                 :        251 :         fctret = eal_parse_args(argc, argv);
     983         [ +  + ]:        251 :         if (fctret < 0) {
     984                 :         50 :                 rte_eal_init_alert("Invalid 'command line' arguments.");
     985                 :         50 :                 rte_errno = EINVAL;
     986                 :         50 :                 rte_atomic_store_explicit(&run_once, 0, rte_memory_order_relaxed);
     987                 :         50 :                 return -1;
     988                 :            :         }
     989                 :            : 
     990         [ -  + ]:        201 :         if (eal_plugins_init() < 0) {
     991                 :          0 :                 rte_eal_init_alert("Cannot init plugins");
     992                 :          0 :                 rte_errno = EINVAL;
     993                 :          0 :                 rte_atomic_store_explicit(&run_once, 0, rte_memory_order_relaxed);
     994                 :          0 :                 return -1;
     995                 :            :         }
     996                 :            : 
     997         [ -  + ]:        201 :         if (eal_trace_init() < 0) {
     998                 :          0 :                 rte_eal_init_alert("Cannot init trace");
     999                 :          0 :                 rte_errno = EFAULT;
    1000                 :          0 :                 return -1;
    1001                 :            :         }
    1002                 :            : 
    1003         [ +  + ]:        201 :         if (eal_option_device_parse()) {
    1004                 :         13 :                 rte_errno = ENODEV;
    1005                 :         13 :                 rte_atomic_store_explicit(&run_once, 0, rte_memory_order_relaxed);
    1006                 :         13 :                 return -1;
    1007                 :            :         }
    1008                 :            : 
    1009         [ +  + ]:        188 :         if (rte_config_init() < 0) {
    1010                 :          1 :                 rte_eal_init_alert("Cannot init config");
    1011                 :          1 :                 return -1;
    1012                 :            :         }
    1013                 :            : 
    1014         [ -  + ]:        187 :         if (rte_eal_intr_init() < 0) {
    1015                 :          0 :                 rte_eal_init_alert("Cannot init interrupt-handling thread");
    1016                 :          0 :                 return -1;
    1017                 :            :         }
    1018                 :            : 
    1019         [ -  + ]:        187 :         if (rte_eal_alarm_init() < 0) {
    1020                 :          0 :                 rte_eal_init_alert("Cannot init alarm");
    1021                 :            :                 /* rte_eal_alarm_init sets rte_errno on failure. */
    1022                 :          0 :                 return -1;
    1023                 :            :         }
    1024                 :            : 
    1025                 :            :         /* Put mp channel init before bus scan so that we can init the vdev
    1026                 :            :          * bus through mp channel in the secondary process before the bus scan.
    1027                 :            :          */
    1028   [ +  +  -  + ]:        187 :         if (rte_mp_channel_init() < 0 && rte_errno != ENOTSUP) {
    1029                 :          0 :                 rte_eal_init_alert("failed to init mp channel");
    1030         [ #  # ]:          0 :                 if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
    1031                 :          0 :                         rte_errno = EFAULT;
    1032                 :          0 :                         return -1;
    1033                 :            :                 }
    1034                 :            :         }
    1035                 :            : 
    1036         [ -  + ]:        187 :         if (rte_bus_scan()) {
    1037                 :          0 :                 rte_eal_init_alert("Cannot scan the buses for devices");
    1038                 :          0 :                 rte_errno = ENODEV;
    1039                 :          0 :                 rte_atomic_store_explicit(&run_once, 0, rte_memory_order_relaxed);
    1040                 :          0 :                 return -1;
    1041                 :            :         }
    1042                 :            : 
    1043                 :        187 :         phys_addrs = rte_eal_using_phys_addrs() != 0;
    1044                 :            : 
    1045                 :            :         /* if no EAL option "--iova-mode=<pa|va>", use bus IOVA scheme */
    1046         [ +  - ]:        187 :         if (internal_conf->iova_mode == RTE_IOVA_DC) {
    1047                 :            :                 /* autodetect the IOVA mapping mode */
    1048                 :        187 :                 enum rte_iova_mode iova_mode = rte_bus_get_iommu_class();
    1049                 :            : 
    1050         [ +  + ]:        187 :                 if (iova_mode == RTE_IOVA_DC) {
    1051                 :        186 :                         EAL_LOG(DEBUG, "Buses did not request a specific IOVA mode.");
    1052                 :            : 
    1053                 :            :                         if (!RTE_IOVA_IN_MBUF) {
    1054                 :            :                                 iova_mode = RTE_IOVA_VA;
    1055                 :            :                                 EAL_LOG(DEBUG, "IOVA as VA mode is forced by build option.");
    1056         [ +  + ]:        186 :                         } else if (!phys_addrs) {
    1057                 :            :                                 /* if we have no access to physical addresses,
    1058                 :            :                                  * pick IOVA as VA mode.
    1059                 :            :                                  */
    1060                 :            :                                 iova_mode = RTE_IOVA_VA;
    1061                 :        100 :                                 EAL_LOG(DEBUG, "Physical addresses are unavailable, selecting IOVA as VA mode.");
    1062         [ -  + ]:         86 :                         } else if (is_iommu_enabled()) {
    1063                 :            :                                 /* we have an IOMMU, pick IOVA as VA mode */
    1064                 :            :                                 iova_mode = RTE_IOVA_VA;
    1065                 :          0 :                                 EAL_LOG(DEBUG, "IOMMU is available, selecting IOVA as VA mode.");
    1066                 :            :                         } else {
    1067                 :            :                                 /* physical addresses available, and no IOMMU
    1068                 :            :                                  * found, so pick IOVA as PA.
    1069                 :            :                                  */
    1070                 :            :                                 iova_mode = RTE_IOVA_PA;
    1071                 :         86 :                                 EAL_LOG(DEBUG, "IOMMU is not available, selecting IOVA as PA mode.");
    1072                 :            :                         }
    1073                 :            :                 }
    1074                 :        187 :                 rte_eal_get_configuration()->iova_mode = iova_mode;
    1075                 :            :         } else {
    1076                 :          0 :                 rte_eal_get_configuration()->iova_mode =
    1077                 :          0 :                         internal_conf->iova_mode;
    1078                 :            :         }
    1079                 :            : 
    1080   [ +  +  -  + ]:        187 :         if (rte_eal_iova_mode() == RTE_IOVA_PA && !phys_addrs) {
    1081                 :          0 :                 rte_eal_init_alert("Cannot use IOVA as 'PA' since physical addresses are not available");
    1082                 :          0 :                 rte_errno = EINVAL;
    1083                 :          0 :                 return -1;
    1084                 :            :         }
    1085                 :            : 
    1086                 :        187 :         if (rte_eal_iova_mode() == RTE_IOVA_PA && !RTE_IOVA_IN_MBUF) {
    1087                 :            :                 rte_eal_init_alert("Cannot use IOVA as 'PA' as it is disabled during build");
    1088                 :            :                 rte_errno = EINVAL;
    1089                 :            :                 return -1;
    1090                 :            :         }
    1091                 :            : 
    1092         [ +  + ]:        288 :         EAL_LOG(INFO, "Selected IOVA mode '%s'",
    1093                 :            :                 rte_eal_iova_mode() == RTE_IOVA_PA ? "PA" : "VA");
    1094                 :            : 
    1095         [ +  + ]:        187 :         if (internal_conf->no_hugetlbfs == 0) {
    1096                 :            :                 /* rte_config isn't initialized yet */
    1097                 :         86 :                 ret = internal_conf->process_type == RTE_PROC_PRIMARY ?
    1098         [ +  + ]:         86 :                                 eal_hugepage_info_init() :
    1099                 :         27 :                                 eal_hugepage_info_read();
    1100         [ +  + ]:         86 :                 if (ret < 0) {
    1101                 :          2 :                         rte_eal_init_alert("Cannot get hugepage information.");
    1102                 :          2 :                         rte_errno = EACCES;
    1103                 :          2 :                         rte_atomic_store_explicit(&run_once, 0, rte_memory_order_relaxed);
    1104                 :          2 :                         return -1;
    1105                 :            :                 }
    1106                 :            :         }
    1107                 :            : 
    1108   [ +  +  +  + ]:        185 :         if (internal_conf->memory == 0 && internal_conf->force_numa == 0) {
    1109         [ +  + ]:         74 :                 if (internal_conf->no_hugetlbfs)
    1110                 :          7 :                         internal_conf->memory = MEMSIZE_IF_NO_HUGE_PAGE;
    1111                 :            :         }
    1112                 :            : 
    1113         [ -  + ]:        185 :         if (internal_conf->vmware_tsc_map == 1) {
    1114                 :            : #ifdef RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT
    1115                 :            :                 rte_cycles_vmware_tsc_map = 1;
    1116                 :            :                 EAL_LOG(DEBUG, "Using VMWARE TSC MAP, "
    1117                 :            :                                 "you must have monitor_control.pseudo_perfctr = TRUE");
    1118                 :            : #else
    1119                 :          0 :                 EAL_LOG(WARNING, "Ignoring --vmware-tsc-map because "
    1120                 :            :                                 "RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT is not set");
    1121                 :            : #endif
    1122                 :            :         }
    1123                 :            : 
    1124                 :            : #ifdef VFIO_PRESENT
    1125         [ -  + ]:        185 :         if (rte_vfio_enable("vfio")) {
    1126                 :          0 :                 rte_eal_init_alert("Cannot init VFIO");
    1127                 :          0 :                 rte_errno = EAGAIN;
    1128                 :          0 :                 rte_atomic_store_explicit(&run_once, 0, rte_memory_order_relaxed);
    1129                 :          0 :                 return -1;
    1130                 :            :         }
    1131                 :            : #endif
    1132                 :            :         /* in secondary processes, memory init may allocate additional fbarrays
    1133                 :            :          * not present in primary processes, so to avoid any potential issues,
    1134                 :            :          * initialize memzones first.
    1135                 :            :          */
    1136         [ -  + ]:        185 :         if (rte_eal_memzone_init() < 0) {
    1137                 :          0 :                 rte_eal_init_alert("Cannot init memzone");
    1138                 :          0 :                 rte_errno = ENODEV;
    1139                 :          0 :                 return -1;
    1140                 :            :         }
    1141                 :            : 
    1142                 :        185 :         rte_mcfg_mem_read_lock();
    1143                 :            : 
    1144         [ +  + ]:        185 :         if (rte_eal_memory_init() < 0) {
    1145                 :          3 :                 rte_mcfg_mem_read_unlock();
    1146                 :          3 :                 rte_eal_init_alert("Cannot init memory");
    1147                 :          3 :                 rte_errno = ENOMEM;
    1148                 :          3 :                 return -1;
    1149                 :            :         }
    1150                 :            : 
    1151                 :            :         /* the directories are locked during eal_hugepage_info_init */
    1152                 :        182 :         eal_hugedirs_unlock();
    1153                 :            : 
    1154         [ -  + ]:        182 :         if (rte_eal_malloc_heap_init() < 0) {
    1155                 :          0 :                 rte_mcfg_mem_read_unlock();
    1156                 :          0 :                 rte_eal_init_alert("Cannot init malloc heap");
    1157                 :          0 :                 rte_errno = ENODEV;
    1158                 :          0 :                 return -1;
    1159                 :            :         }
    1160                 :            : 
    1161                 :        182 :         rte_mcfg_mem_read_unlock();
    1162                 :            : 
    1163         [ -  + ]:        182 :         if (rte_eal_malloc_heap_populate() < 0) {
    1164                 :          0 :                 rte_eal_init_alert("Cannot init malloc heap");
    1165                 :          0 :                 rte_errno = ENODEV;
    1166                 :          0 :                 return -1;
    1167                 :            :         }
    1168                 :            : 
    1169                 :            :         /* register multi-process action callbacks for hotplug after memory init */
    1170         [ -  + ]:        182 :         if (eal_mp_dev_hotplug_init() < 0) {
    1171                 :          0 :                 rte_eal_init_alert("failed to register mp callback for hotplug");
    1172                 :          0 :                 return -1;
    1173                 :            :         }
    1174                 :            : 
    1175         [ -  + ]:        182 :         if (rte_eal_tailqs_init() < 0) {
    1176                 :          0 :                 rte_eal_init_alert("Cannot init tail queues for objects");
    1177                 :          0 :                 rte_errno = EFAULT;
    1178                 :          0 :                 return -1;
    1179                 :            :         }
    1180                 :            : 
    1181         [ -  + ]:        182 :         if (rte_eal_timer_init() < 0) {
    1182                 :          0 :                 rte_eal_init_alert("Cannot init HPET or TSC timers");
    1183                 :          0 :                 rte_errno = ENOTSUP;
    1184                 :          0 :                 return -1;
    1185                 :            :         }
    1186                 :            : 
    1187                 :        182 :         eal_rand_init();
    1188                 :            : 
    1189                 :        182 :         eal_check_mem_on_local_socket();
    1190                 :            : 
    1191         [ -  + ]:        182 :         if (rte_thread_set_affinity_by_id(rte_thread_self(),
    1192                 :        182 :                         &lcore_config[config->main_lcore].cpuset) != 0) {
    1193                 :          0 :                 rte_eal_init_alert("Cannot set affinity");
    1194                 :          0 :                 rte_errno = EINVAL;
    1195                 :          0 :                 return -1;
    1196                 :            :         }
    1197                 :        182 :         __rte_thread_init(config->main_lcore,
    1198                 :        182 :                 &lcore_config[config->main_lcore].cpuset);
    1199                 :            : 
    1200                 :        182 :         ret = eal_thread_dump_current_affinity(cpuset, sizeof(cpuset));
    1201         [ -  + ]:        182 :         EAL_LOG(DEBUG, "Main lcore %u is ready (tid=%zx;cpuset=[%s%s])",
    1202                 :            :                 config->main_lcore, (uintptr_t)pthread_self(), cpuset,
    1203                 :            :                 ret == 0 ? "" : "...");
    1204                 :            : 
    1205         [ +  + ]:        312 :         RTE_LCORE_FOREACH_WORKER(i) {
    1206                 :            : 
    1207                 :            :                 /*
    1208                 :            :                  * create communication pipes between main thread
    1209                 :            :                  * and children
    1210                 :            :                  */
    1211         [ -  + ]:        130 :                 if (pipe(lcore_config[i].pipe_main2worker) < 0)
    1212                 :          0 :                         rte_panic("Cannot create pipe\n");
    1213         [ -  + ]:        130 :                 if (pipe(lcore_config[i].pipe_worker2main) < 0)
    1214                 :          0 :                         rte_panic("Cannot create pipe\n");
    1215                 :            : 
    1216                 :        130 :                 lcore_config[i].state = WAIT;
    1217                 :            : 
    1218                 :            :                 /* create a thread for each lcore */
    1219                 :        130 :                 ret = eal_worker_thread_create(i);
    1220         [ -  + ]:        130 :                 if (ret != 0)
    1221                 :          0 :                         rte_panic("Cannot create thread\n");
    1222                 :            : 
    1223                 :            :                 /* Set thread_name for aid in debugging. */
    1224                 :            :                 snprintf(thread_name, sizeof(thread_name),
    1225                 :            :                         "dpdk-worker%d", i);
    1226                 :        130 :                 rte_thread_set_name(lcore_config[i].thread_id, thread_name);
    1227                 :            : 
    1228                 :        130 :                 ret = rte_thread_set_affinity_by_id(lcore_config[i].thread_id,
    1229                 :        130 :                         &lcore_config[i].cpuset);
    1230         [ -  + ]:        130 :                 if (ret != 0)
    1231                 :          0 :                         rte_panic("Cannot set affinity\n");
    1232                 :            :         }
    1233                 :            : 
    1234                 :            :         /*
    1235                 :            :          * Launch a dummy function on all worker lcores, so that main lcore
    1236                 :            :          * knows they are all ready when this function returns.
    1237                 :            :          */
    1238                 :        182 :         rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MAIN);
    1239                 :        182 :         rte_eal_mp_wait_lcore();
    1240                 :            : 
    1241                 :            :         /* initialize services so vdevs register service during bus_probe. */
    1242                 :        182 :         ret = rte_service_init();
    1243         [ -  + ]:        182 :         if (ret) {
    1244                 :          0 :                 rte_eal_init_alert("rte_service_init() failed");
    1245                 :          0 :                 rte_errno = -ret;
    1246                 :          0 :                 return -1;
    1247                 :            :         }
    1248                 :            : 
    1249                 :            :         /* Probe all the buses and devices/drivers on them */
    1250         [ -  + ]:        182 :         if (rte_bus_probe()) {
    1251                 :          0 :                 rte_eal_init_alert("Cannot probe devices");
    1252                 :          0 :                 rte_errno = ENOTSUP;
    1253                 :          0 :                 return -1;
    1254                 :            :         }
    1255                 :            : 
    1256                 :            :         /* initialize default service/lcore mappings and start running. Ignore
    1257                 :            :          * -ENOTSUP, as it indicates no service coremask passed to EAL.
    1258                 :            :          */
    1259                 :        182 :         ret = rte_service_start_with_defaults();
    1260         [ -  + ]:        182 :         if (ret < 0 && ret != -ENOTSUP) {
    1261                 :          0 :                 rte_errno = -ret;
    1262                 :          0 :                 return -1;
    1263                 :            :         }
    1264                 :            : 
    1265                 :            :         /*
    1266                 :            :          * Clean up unused files in runtime directory. We do this at the end of
    1267                 :            :          * init and not at the beginning because we want to clean stuff up
    1268                 :            :          * whether we are primary or secondary process, but we cannot remove
    1269                 :            :          * primary process' files because secondary should be able to run even
    1270                 :            :          * if primary process is dead.
    1271                 :            :          *
    1272                 :            :          * In no_shconf mode, no runtime directory is created in the first
    1273                 :            :          * place, so no cleanup needed.
    1274                 :            :          */
    1275   [ +  +  -  + ]:        182 :         if (!internal_conf->no_shconf && eal_clean_runtime_dir() < 0) {
    1276                 :          0 :                 rte_eal_init_alert("Cannot clear runtime directory");
    1277                 :          0 :                 return -1;
    1278                 :            :         }
    1279   [ +  +  +  - ]:        182 :         if (rte_eal_process_type() == RTE_PROC_PRIMARY && !internal_conf->no_telemetry) {
    1280         [ +  - ]:        157 :                 if (rte_telemetry_init(rte_eal_get_runtime_dir(),
    1281                 :            :                                 rte_version(),
    1282                 :            :                                 &internal_conf->ctrl_cpuset) != 0)
    1283                 :            :                         return -1;
    1284                 :            :         }
    1285                 :            : 
    1286                 :        182 :         eal_mcfg_complete();
    1287                 :            : 
    1288                 :        182 :         return fctret;
    1289                 :            : }
    1290                 :            : 
    1291                 :            : static int
    1292                 :   48358552 : mark_freeable(const struct rte_memseg_list *msl, const struct rte_memseg *ms,
    1293                 :            :                 void *arg __rte_unused)
    1294                 :            : {
    1295                 :            :         /* ms is const, so find this memseg */
    1296                 :            :         struct rte_memseg *found;
    1297                 :            : 
    1298         [ +  - ]:   48358552 :         if (msl->external)
    1299                 :            :                 return 0;
    1300                 :            : 
    1301                 :   48358552 :         found = rte_mem_virt2memseg(ms->addr, msl);
    1302                 :            : 
    1303                 :   48358552 :         found->flags &= ~RTE_MEMSEG_FLAG_DO_NOT_FREE;
    1304                 :            : 
    1305                 :   48358552 :         return 0;
    1306                 :            : }
    1307                 :            : 
    1308                 :            : RTE_EXPORT_SYMBOL(rte_eal_cleanup)
    1309                 :            : int
    1310                 :        254 : rte_eal_cleanup(void)
    1311                 :            : {
    1312                 :            :         static RTE_ATOMIC(uint32_t) run_once;
    1313                 :            :         uint32_t has_run = 0;
    1314                 :            : 
    1315         [ -  + ]:        254 :         if (!rte_atomic_compare_exchange_strong_explicit(&run_once, &has_run, 1,
    1316                 :            :                                         rte_memory_order_relaxed, rte_memory_order_relaxed)) {
    1317                 :          0 :                 EAL_LOG(WARNING, "Already called cleanup");
    1318                 :          0 :                 rte_errno = EALREADY;
    1319                 :          0 :                 return -1;
    1320                 :            :         }
    1321                 :            : 
    1322                 :            :         /* if we're in a primary process, we need to mark hugepages as freeable
    1323                 :            :          * so that finalization can release them back to the system.
    1324                 :            :          */
    1325                 :            :         struct internal_config *internal_conf =
    1326                 :        254 :                 eal_get_internal_configuration();
    1327                 :            : 
    1328         [ +  + ]:        254 :         if (rte_eal_process_type() == RTE_PROC_PRIMARY &&
    1329         [ +  + ]:        226 :                         internal_conf->hugepage_file.unlink_existing)
    1330                 :        222 :                 rte_memseg_walk(mark_freeable, NULL);
    1331                 :            : 
    1332                 :        254 :         rte_service_finalize();
    1333                 :            : #ifdef VFIO_PRESENT
    1334                 :        254 :         vfio_mp_sync_cleanup();
    1335                 :            : #endif
    1336                 :        254 :         rte_mp_channel_cleanup();
    1337                 :        254 :         eal_bus_cleanup();
    1338                 :        254 :         rte_eal_alarm_cleanup();
    1339                 :        254 :         rte_trace_save();
    1340                 :        254 :         eal_trace_fini();
    1341                 :        254 :         eal_mp_dev_hotplug_cleanup();
    1342                 :            :         /* after this point, any DPDK pointers will become dangling */
    1343                 :        254 :         rte_eal_memory_detach();
    1344                 :        254 :         rte_eal_malloc_heap_cleanup();
    1345                 :        254 :         eal_cleanup_config(internal_conf);
    1346                 :        254 :         eal_lcore_var_cleanup();
    1347                 :        254 :         rte_eal_log_cleanup();
    1348                 :        254 :         return 0;
    1349                 :            : }
    1350                 :            : 
    1351                 :            : RTE_EXPORT_SYMBOL(rte_eal_create_uio_dev)
    1352                 :          0 : int rte_eal_create_uio_dev(void)
    1353                 :            : {
    1354                 :            :         const struct internal_config *internal_conf =
    1355                 :          0 :                 eal_get_internal_configuration();
    1356                 :            : 
    1357                 :          0 :         return internal_conf->create_uio_dev;
    1358                 :            : }
    1359                 :            : 
    1360                 :            : RTE_EXPORT_SYMBOL(rte_eal_vfio_intr_mode)
    1361                 :            : enum rte_intr_mode
    1362                 :          0 : rte_eal_vfio_intr_mode(void)
    1363                 :            : {
    1364                 :            :         const struct internal_config *internal_conf =
    1365                 :          0 :                 eal_get_internal_configuration();
    1366                 :            : 
    1367                 :          0 :         return internal_conf->vfio_intr_mode;
    1368                 :            : }
    1369                 :            : 
    1370                 :            : RTE_EXPORT_SYMBOL(rte_eal_vfio_get_vf_token)
    1371                 :            : void
    1372                 :          0 : rte_eal_vfio_get_vf_token(rte_uuid_t vf_token)
    1373                 :            : {
    1374                 :          0 :         struct internal_config *cfg = eal_get_internal_configuration();
    1375                 :            : 
    1376                 :          0 :         rte_uuid_copy(vf_token, cfg->vfio_vf_token);
    1377                 :          0 : }
    1378                 :            : 
    1379                 :            : int
    1380                 :        185 : rte_eal_check_module(const char *module_name)
    1381                 :            : {
    1382                 :            :         char sysfs_mod_name[PATH_MAX];
    1383                 :            :         struct stat st;
    1384                 :            :         int n;
    1385                 :            : 
    1386         [ +  - ]:        185 :         if (NULL == module_name)
    1387                 :            :                 return -1;
    1388                 :            : 
    1389                 :            :         /* Check if there is sysfs mounted */
    1390         [ -  + ]:        185 :         if (stat("/sys/module", &st) != 0) {
    1391                 :          0 :                 EAL_LOG(DEBUG, "sysfs is not mounted! error %i (%s)",
    1392                 :            :                         errno, strerror(errno));
    1393                 :          0 :                 return -1;
    1394                 :            :         }
    1395                 :            : 
    1396                 :            :         /* A module might be built-in, therefore try sysfs */
    1397                 :            :         n = snprintf(sysfs_mod_name, PATH_MAX, "/sys/module/%s", module_name);
    1398         [ -  + ]:        185 :         if (n < 0 || n > PATH_MAX) {
    1399                 :          0 :                 EAL_LOG(DEBUG, "Could not format module path");
    1400                 :          0 :                 return -1;
    1401                 :            :         }
    1402                 :            : 
    1403         [ -  + ]:        185 :         if (stat(sysfs_mod_name, &st) != 0) {
    1404                 :          0 :                 EAL_LOG(DEBUG, "Module %s not found! error %i (%s)",
    1405                 :            :                         sysfs_mod_name, errno, strerror(errno));
    1406                 :          0 :                 return 0;
    1407                 :            :         }
    1408                 :            : 
    1409                 :            :         /* Module has been found */
    1410                 :            :         return 1;
    1411                 :            : }

Generated by: LCOV version 1.14