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

Generated by: LCOV version 1.14