eal: move OS common config objects
[dpdk.git] / lib / librte_eal / freebsd / eal.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2018 Intel Corporation.
3  * Copyright(c) 2014 6WIND S.A.
4  */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include <string.h>
10 #include <stdarg.h>
11 #include <unistd.h>
12 #include <pthread.h>
13 #include <syslog.h>
14 #include <getopt.h>
15 #include <sys/file.h>
16 #include <stddef.h>
17 #include <errno.h>
18 #include <limits.h>
19 #include <sys/mman.h>
20 #include <sys/queue.h>
21 #include <sys/stat.h>
22
23 #include <rte_compat.h>
24 #include <rte_common.h>
25 #include <rte_debug.h>
26 #include <rte_memory.h>
27 #include <rte_launch.h>
28 #include <rte_eal.h>
29 #include <rte_errno.h>
30 #include <rte_per_lcore.h>
31 #include <rte_lcore.h>
32 #include <rte_service_component.h>
33 #include <rte_log.h>
34 #include <rte_random.h>
35 #include <rte_cycles.h>
36 #include <rte_string_fns.h>
37 #include <rte_cpuflags.h>
38 #include <rte_interrupts.h>
39 #include <rte_bus.h>
40 #include <rte_dev.h>
41 #include <rte_devargs.h>
42 #include <rte_version.h>
43 #include <rte_vfio.h>
44 #include <rte_atomic.h>
45 #include <malloc_heap.h>
46 #include <rte_telemetry.h>
47
48 #include "eal_private.h"
49 #include "eal_thread.h"
50 #include "eal_internal_cfg.h"
51 #include "eal_filesystem.h"
52 #include "eal_hugepages.h"
53 #include "eal_options.h"
54 #include "eal_memcfg.h"
55 #include "eal_trace.h"
56
57 #define MEMSIZE_IF_NO_HUGE_PAGE (64ULL * 1024ULL * 1024ULL)
58
59 /* Allow the application to print its usage message too if set */
60 static rte_usage_hook_t rte_application_usage_hook = NULL;
61 /* define fd variable here, because file needs to be kept open for the
62  * duration of the program, as we hold a write lock on it in the primary proc */
63 static int mem_cfg_fd = -1;
64
65 static struct flock wr_lock = {
66                 .l_type = F_WRLCK,
67                 .l_whence = SEEK_SET,
68                 .l_start = offsetof(struct rte_mem_config, memsegs),
69                 .l_len = RTE_SIZEOF_FIELD(struct rte_mem_config, memsegs),
70 };
71
72 /* internal configuration (per-core) */
73 struct lcore_config lcore_config[RTE_MAX_LCORE];
74
75 /* used by rte_rdtsc() */
76 int rte_cycles_vmware_tsc_map;
77
78 static const char *default_runtime_dir = "/var/run";
79
80 int
81 eal_create_runtime_dir(void)
82 {
83         const char *directory = default_runtime_dir;
84         const char *xdg_runtime_dir = getenv("XDG_RUNTIME_DIR");
85         const char *fallback = "/tmp";
86         char run_dir[PATH_MAX];
87         char tmp[PATH_MAX];
88         int ret;
89
90         if (getuid() != 0) {
91                 /* try XDG path first, fall back to /tmp */
92                 if (xdg_runtime_dir != NULL)
93                         directory = xdg_runtime_dir;
94                 else
95                         directory = fallback;
96         }
97         /* create DPDK subdirectory under runtime dir */
98         ret = snprintf(tmp, sizeof(tmp), "%s/dpdk", directory);
99         if (ret < 0 || ret == sizeof(tmp)) {
100                 RTE_LOG(ERR, EAL, "Error creating DPDK runtime path name\n");
101                 return -1;
102         }
103
104         /* create prefix-specific subdirectory under DPDK runtime dir */
105         ret = snprintf(run_dir, sizeof(run_dir), "%s/%s",
106                         tmp, eal_get_hugefile_prefix());
107         if (ret < 0 || ret == sizeof(run_dir)) {
108                 RTE_LOG(ERR, EAL, "Error creating prefix-specific runtime path name\n");
109                 return -1;
110         }
111
112         /* create the path if it doesn't exist. no "mkdir -p" here, so do it
113          * step by step.
114          */
115         ret = mkdir(tmp, 0700);
116         if (ret < 0 && errno != EEXIST) {
117                 RTE_LOG(ERR, EAL, "Error creating '%s': %s\n",
118                         tmp, strerror(errno));
119                 return -1;
120         }
121
122         ret = mkdir(run_dir, 0700);
123         if (ret < 0 && errno != EEXIST) {
124                 RTE_LOG(ERR, EAL, "Error creating '%s': %s\n",
125                         run_dir, strerror(errno));
126                 return -1;
127         }
128
129         if (eal_set_runtime_dir(run_dir, sizeof(run_dir)))
130                 return -1;
131
132         return 0;
133 }
134
135 int
136 eal_clean_runtime_dir(void)
137 {
138         /* FreeBSD doesn't need this implemented for now, because, unlike Linux,
139          * FreeBSD doesn't create per-process files, so no need to clean up.
140          */
141         return 0;
142 }
143
144 /* parse a sysfs (or other) file containing one integer value */
145 int
146 eal_parse_sysfs_value(const char *filename, unsigned long *val)
147 {
148         FILE *f;
149         char buf[BUFSIZ];
150         char *end = NULL;
151
152         if ((f = fopen(filename, "r")) == NULL) {
153                 RTE_LOG(ERR, EAL, "%s(): cannot open sysfs value %s\n",
154                         __func__, filename);
155                 return -1;
156         }
157
158         if (fgets(buf, sizeof(buf), f) == NULL) {
159                 RTE_LOG(ERR, EAL, "%s(): cannot read sysfs value %s\n",
160                         __func__, filename);
161                 fclose(f);
162                 return -1;
163         }
164         *val = strtoul(buf, &end, 0);
165         if ((buf[0] == '\0') || (end == NULL) || (*end != '\n')) {
166                 RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs value %s\n",
167                                 __func__, filename);
168                 fclose(f);
169                 return -1;
170         }
171         fclose(f);
172         return 0;
173 }
174
175
176 /* create memory configuration in shared/mmap memory. Take out
177  * a write lock on the memsegs, so we can auto-detect primary/secondary.
178  * This means we never close the file while running (auto-close on exit).
179  * We also don't lock the whole file, so that in future we can use read-locks
180  * on other parts, e.g. memzones, to detect if there are running secondary
181  * processes. */
182 static int
183 rte_eal_config_create(void)
184 {
185         struct rte_config *config = rte_eal_get_configuration();
186         const struct internal_config *internal_conf =
187                 eal_get_internal_configuration();
188         size_t page_sz = sysconf(_SC_PAGE_SIZE);
189         size_t cfg_len = sizeof(struct rte_mem_config);
190         size_t cfg_len_aligned = RTE_ALIGN(cfg_len, page_sz);
191         void *rte_mem_cfg_addr, *mapped_mem_cfg_addr;
192         int retval;
193
194         const char *pathname = eal_runtime_config_path();
195
196         if (internal_conf->no_shconf)
197                 return 0;
198
199         /* map the config before base address so that we don't waste a page */
200         if (internal_conf->base_virtaddr != 0)
201                 rte_mem_cfg_addr = (void *)
202                         RTE_ALIGN_FLOOR(internal_conf->base_virtaddr -
203                         sizeof(struct rte_mem_config), page_sz);
204         else
205                 rte_mem_cfg_addr = NULL;
206
207         if (mem_cfg_fd < 0){
208                 mem_cfg_fd = open(pathname, O_RDWR | O_CREAT, 0600);
209                 if (mem_cfg_fd < 0) {
210                         RTE_LOG(ERR, EAL, "Cannot open '%s' for rte_mem_config\n",
211                                 pathname);
212                         return -1;
213                 }
214         }
215
216         retval = ftruncate(mem_cfg_fd, cfg_len);
217         if (retval < 0){
218                 close(mem_cfg_fd);
219                 mem_cfg_fd = -1;
220                 RTE_LOG(ERR, EAL, "Cannot resize '%s' for rte_mem_config\n",
221                         pathname);
222                 return -1;
223         }
224
225         retval = fcntl(mem_cfg_fd, F_SETLK, &wr_lock);
226         if (retval < 0){
227                 close(mem_cfg_fd);
228                 mem_cfg_fd = -1;
229                 RTE_LOG(ERR, EAL, "Cannot create lock on '%s'. Is another primary "
230                         "process running?\n", pathname);
231                 return -1;
232         }
233
234         /* reserve space for config */
235         rte_mem_cfg_addr = eal_get_virtual_area(rte_mem_cfg_addr,
236                         &cfg_len_aligned, page_sz, 0, 0);
237         if (rte_mem_cfg_addr == NULL) {
238                 RTE_LOG(ERR, EAL, "Cannot mmap memory for rte_config\n");
239                 close(mem_cfg_fd);
240                 mem_cfg_fd = -1;
241                 return -1;
242         }
243
244         /* remap the actual file into the space we've just reserved */
245         mapped_mem_cfg_addr = mmap(rte_mem_cfg_addr,
246                         cfg_len_aligned, PROT_READ | PROT_WRITE,
247                         MAP_SHARED | MAP_FIXED, mem_cfg_fd, 0);
248         if (mapped_mem_cfg_addr == MAP_FAILED) {
249                 RTE_LOG(ERR, EAL, "Cannot remap memory for rte_config\n");
250                 munmap(rte_mem_cfg_addr, cfg_len);
251                 close(mem_cfg_fd);
252                 mem_cfg_fd = -1;
253                 return -1;
254         }
255
256         memcpy(rte_mem_cfg_addr, config->mem_config, sizeof(struct rte_mem_config));
257         config->mem_config = rte_mem_cfg_addr;
258
259         /* store address of the config in the config itself so that secondary
260          * processes could later map the config into this exact location
261          */
262         config->mem_config->mem_cfg_addr = (uintptr_t) rte_mem_cfg_addr;
263         return 0;
264 }
265
266 /* attach to an existing shared memory config */
267 static int
268 rte_eal_config_attach(void)
269 {
270         void *rte_mem_cfg_addr;
271         const char *pathname = eal_runtime_config_path();
272         struct rte_config *config = rte_eal_get_configuration();
273         const struct internal_config *internal_conf =
274                 eal_get_internal_configuration();
275
276
277         if (internal_conf->no_shconf)
278                 return 0;
279
280         if (mem_cfg_fd < 0){
281                 mem_cfg_fd = open(pathname, O_RDWR);
282                 if (mem_cfg_fd < 0) {
283                         RTE_LOG(ERR, EAL, "Cannot open '%s' for rte_mem_config\n",
284                                 pathname);
285                         return -1;
286                 }
287         }
288
289         rte_mem_cfg_addr = mmap(NULL, sizeof(*config->mem_config),
290                                 PROT_READ, MAP_SHARED, mem_cfg_fd, 0);
291         /* don't close the fd here, it will be closed on reattach */
292         if (rte_mem_cfg_addr == MAP_FAILED) {
293                 close(mem_cfg_fd);
294                 mem_cfg_fd = -1;
295                 RTE_LOG(ERR, EAL, "Cannot mmap memory for rte_config! error %i (%s)\n",
296                         errno, strerror(errno));
297                 return -1;
298         }
299
300         config->mem_config = rte_mem_cfg_addr;
301
302         return 0;
303 }
304
305 /* reattach the shared config at exact memory location primary process has it */
306 static int
307 rte_eal_config_reattach(void)
308 {
309         struct rte_mem_config *mem_config;
310         void *rte_mem_cfg_addr;
311         struct rte_config *config = rte_eal_get_configuration();
312         const struct internal_config *internal_conf =
313                 eal_get_internal_configuration();
314
315         if (internal_conf->no_shconf)
316                 return 0;
317
318         /* save the address primary process has mapped shared config to */
319         rte_mem_cfg_addr =
320                         (void *)(uintptr_t)config->mem_config->mem_cfg_addr;
321
322         /* unmap original config */
323         munmap(config->mem_config, sizeof(struct rte_mem_config));
324
325         /* remap the config at proper address */
326         mem_config = (struct rte_mem_config *) mmap(rte_mem_cfg_addr,
327                         sizeof(*mem_config), PROT_READ | PROT_WRITE, MAP_SHARED,
328                         mem_cfg_fd, 0);
329         close(mem_cfg_fd);
330         mem_cfg_fd = -1;
331
332         if (mem_config == MAP_FAILED || mem_config != rte_mem_cfg_addr) {
333                 if (mem_config != MAP_FAILED) {
334                         /* errno is stale, don't use */
335                         RTE_LOG(ERR, EAL, "Cannot mmap memory for rte_config at [%p], got [%p]"
336                                           " - please use '--" OPT_BASE_VIRTADDR
337                                           "' option\n",
338                                 rte_mem_cfg_addr, mem_config);
339                         munmap(mem_config, sizeof(struct rte_mem_config));
340                         return -1;
341                 }
342                 RTE_LOG(ERR, EAL, "Cannot mmap memory for rte_config! error %i (%s)\n",
343                         errno, strerror(errno));
344                 return -1;
345         }
346
347         config->mem_config = mem_config;
348
349         return 0;
350 }
351
352 /* Detect if we are a primary or a secondary process */
353 enum rte_proc_type_t
354 eal_proc_type_detect(void)
355 {
356         enum rte_proc_type_t ptype = RTE_PROC_PRIMARY;
357         const char *pathname = eal_runtime_config_path();
358         const struct internal_config *internal_conf =
359                 eal_get_internal_configuration();
360
361         /* if there no shared config, there can be no secondary processes */
362         if (!internal_conf->no_shconf) {
363                 /* if we can open the file but not get a write-lock we are a
364                  * secondary process. NOTE: if we get a file handle back, we
365                  * keep that open and don't close it to prevent a race condition
366                  * between multiple opens.
367                  */
368                 if (((mem_cfg_fd = open(pathname, O_RDWR)) >= 0) &&
369                                 (fcntl(mem_cfg_fd, F_SETLK, &wr_lock) < 0))
370                         ptype = RTE_PROC_SECONDARY;
371         }
372
373         RTE_LOG(INFO, EAL, "Auto-detected process type: %s\n",
374                         ptype == RTE_PROC_PRIMARY ? "PRIMARY" : "SECONDARY");
375
376         return ptype;
377 }
378
379 /* Sets up rte_config structure with the pointer to shared memory config.*/
380 static int
381 rte_config_init(void)
382 {
383         struct rte_config *config = rte_eal_get_configuration();
384         const struct internal_config *internal_conf =
385                 eal_get_internal_configuration();
386
387         config->process_type = internal_conf->process_type;
388
389         switch (config->process_type) {
390         case RTE_PROC_PRIMARY:
391                 if (rte_eal_config_create() < 0)
392                         return -1;
393                 eal_mcfg_update_from_internal();
394                 break;
395         case RTE_PROC_SECONDARY:
396                 if (rte_eal_config_attach() < 0)
397                         return -1;
398                 eal_mcfg_wait_complete();
399                 if (eal_mcfg_check_version() < 0) {
400                         RTE_LOG(ERR, EAL, "Primary and secondary process DPDK version mismatch\n");
401                         return -1;
402                 }
403                 if (rte_eal_config_reattach() < 0)
404                         return -1;
405                 eal_mcfg_update_internal();
406                 break;
407         case RTE_PROC_AUTO:
408         case RTE_PROC_INVALID:
409                 RTE_LOG(ERR, EAL, "Invalid process type %d\n",
410                         config->process_type);
411                 return -1;
412         }
413
414         return 0;
415 }
416
417 /* display usage */
418 static void
419 eal_usage(const char *prgname)
420 {
421         printf("\nUsage: %s ", prgname);
422         eal_common_usage();
423         /* Allow the application to print its usage message too if hook is set */
424         if ( rte_application_usage_hook ) {
425                 printf("===== Application Usage =====\n\n");
426                 rte_application_usage_hook(prgname);
427         }
428 }
429
430 /* Set a per-application usage message */
431 rte_usage_hook_t
432 rte_set_application_usage_hook( rte_usage_hook_t usage_func )
433 {
434         rte_usage_hook_t        old_func;
435
436         /* Will be NULL on the first call to denote the last usage routine. */
437         old_func                                        = rte_application_usage_hook;
438         rte_application_usage_hook      = usage_func;
439
440         return old_func;
441 }
442
443 static inline size_t
444 eal_get_hugepage_mem_size(void)
445 {
446         uint64_t size = 0;
447         unsigned i, j;
448         struct internal_config *internal_conf =
449                 eal_get_internal_configuration();
450
451         for (i = 0; i < internal_conf->num_hugepage_sizes; i++) {
452                 struct hugepage_info *hpi = &internal_conf->hugepage_info[i];
453                 if (strnlen(hpi->hugedir, sizeof(hpi->hugedir)) != 0) {
454                         for (j = 0; j < RTE_MAX_NUMA_NODES; j++) {
455                                 size += hpi->hugepage_sz * hpi->num_pages[j];
456                         }
457                 }
458         }
459
460         return (size < SIZE_MAX) ? (size_t)(size) : SIZE_MAX;
461 }
462
463 /* Parse the arguments for --log-level only */
464 static void
465 eal_log_level_parse(int argc, char **argv)
466 {
467         int opt;
468         char **argvopt;
469         int option_index;
470         const int old_optind = optind;
471         const int old_optopt = optopt;
472         const int old_optreset = optreset;
473         char * const old_optarg = optarg;
474         struct internal_config *internal_conf =
475                 eal_get_internal_configuration();
476
477         argvopt = argv;
478         optind = 1;
479         optreset = 1;
480
481         while ((opt = getopt_long(argc, argvopt, eal_short_options,
482                                   eal_long_options, &option_index)) != EOF) {
483
484                 int ret;
485
486                 /* getopt is not happy, stop right now */
487                 if (opt == '?')
488                         break;
489
490                 ret = (opt == OPT_LOG_LEVEL_NUM) ?
491                     eal_parse_common_option(opt, optarg, internal_conf) : 0;
492
493                 /* common parser is not happy */
494                 if (ret < 0)
495                         break;
496         }
497
498         /* restore getopt lib */
499         optind = old_optind;
500         optopt = old_optopt;
501         optreset = old_optreset;
502         optarg = old_optarg;
503 }
504
505 /* Parse the argument given in the command line of the application */
506 static int
507 eal_parse_args(int argc, char **argv)
508 {
509         int opt, ret;
510         char **argvopt;
511         int option_index;
512         char *prgname = argv[0];
513         const int old_optind = optind;
514         const int old_optopt = optopt;
515         const int old_optreset = optreset;
516         char * const old_optarg = optarg;
517         struct internal_config *internal_conf =
518                 eal_get_internal_configuration();
519
520         argvopt = argv;
521         optind = 1;
522         optreset = 1;
523
524         while ((opt = getopt_long(argc, argvopt, eal_short_options,
525                                   eal_long_options, &option_index)) != EOF) {
526
527                 /* getopt didn't recognise the option */
528                 if (opt == '?') {
529                         eal_usage(prgname);
530                         ret = -1;
531                         goto out;
532                 }
533
534                 ret = eal_parse_common_option(opt, optarg, internal_conf);
535                 /* common parser is not happy */
536                 if (ret < 0) {
537                         eal_usage(prgname);
538                         ret = -1;
539                         goto out;
540                 }
541                 /* common parser handled this option */
542                 if (ret == 0)
543                         continue;
544
545                 switch (opt) {
546                 case OPT_MBUF_POOL_OPS_NAME_NUM:
547                 {
548                         char *ops_name = strdup(optarg);
549                         if (ops_name == NULL)
550                                 RTE_LOG(ERR, EAL, "Could not store mbuf pool ops name\n");
551                         else {
552                                 /* free old ops name */
553                                 if (internal_conf->user_mbuf_pool_ops_name !=
554                                                 NULL)
555                                         free(internal_conf->user_mbuf_pool_ops_name);
556
557                                 internal_conf->user_mbuf_pool_ops_name =
558                                                 ops_name;
559                         }
560                         break;
561                 }
562                 case 'h':
563                         eal_usage(prgname);
564                         exit(EXIT_SUCCESS);
565                 default:
566                         if (opt < OPT_LONG_MIN_NUM && isprint(opt)) {
567                                 RTE_LOG(ERR, EAL, "Option %c is not supported "
568                                         "on FreeBSD\n", opt);
569                         } else if (opt >= OPT_LONG_MIN_NUM &&
570                                    opt < OPT_LONG_MAX_NUM) {
571                                 RTE_LOG(ERR, EAL, "Option %s is not supported "
572                                         "on FreeBSD\n",
573                                         eal_long_options[option_index].name);
574                         } else {
575                                 RTE_LOG(ERR, EAL, "Option %d is not supported "
576                                         "on FreeBSD\n", opt);
577                         }
578                         eal_usage(prgname);
579                         ret = -1;
580                         goto out;
581                 }
582         }
583
584         /* create runtime data directory */
585         if (internal_conf->no_shconf == 0 &&
586                         eal_create_runtime_dir() < 0) {
587                 RTE_LOG(ERR, EAL, "Cannot create runtime directory\n");
588                 ret = -1;
589                 goto out;
590         }
591
592         if (eal_adjust_config(internal_conf) != 0) {
593                 ret = -1;
594                 goto out;
595         }
596
597         /* sanity checks */
598         if (eal_check_common_options(internal_conf) != 0) {
599                 eal_usage(prgname);
600                 ret = -1;
601                 goto out;
602         }
603
604         if (optind >= 0)
605                 argv[optind-1] = prgname;
606         ret = optind-1;
607
608 out:
609         /* restore getopt lib */
610         optind = old_optind;
611         optopt = old_optopt;
612         optreset = old_optreset;
613         optarg = old_optarg;
614
615         return ret;
616 }
617
618 static int
619 check_socket(const struct rte_memseg_list *msl, void *arg)
620 {
621         int *socket_id = arg;
622
623         if (msl->external)
624                 return 0;
625
626         if (msl->socket_id == *socket_id && msl->memseg_arr.count != 0)
627                 return 1;
628
629         return 0;
630 }
631
632 static void
633 eal_check_mem_on_local_socket(void)
634 {
635         int socket_id;
636         const struct rte_config *config = rte_eal_get_configuration();
637
638         socket_id = rte_lcore_to_socket_id(config->master_lcore);
639
640         if (rte_memseg_list_walk(check_socket, &socket_id) == 0)
641                 RTE_LOG(WARNING, EAL, "WARNING: Master core has no memory on local socket!\n");
642 }
643
644
645 static int
646 sync_func(__rte_unused void *arg)
647 {
648         return 0;
649 }
650 /* Abstraction for port I/0 privilege */
651 int
652 rte_eal_iopl_init(void)
653 {
654         static int fd = -1;
655
656         if (fd < 0)
657                 fd = open("/dev/io", O_RDWR);
658
659         if (fd < 0)
660                 return -1;
661         /* keep fd open for iopl */
662         return 0;
663 }
664
665 static void rte_eal_init_alert(const char *msg)
666 {
667         fprintf(stderr, "EAL: FATAL: %s\n", msg);
668         RTE_LOG(ERR, EAL, "%s\n", msg);
669 }
670
671 /* Launch threads, called at application init(). */
672 int
673 rte_eal_init(int argc, char **argv)
674 {
675         int i, fctret, ret;
676         pthread_t thread_id;
677         static rte_atomic32_t run_once = RTE_ATOMIC32_INIT(0);
678         char cpuset[RTE_CPU_AFFINITY_STR_LEN];
679         char thread_name[RTE_MAX_THREAD_NAME_LEN];
680         const struct rte_config *config = rte_eal_get_configuration();
681         struct internal_config *internal_conf =
682                 eal_get_internal_configuration();
683
684         /* checks if the machine is adequate */
685         if (!rte_cpu_is_supported()) {
686                 rte_eal_init_alert("unsupported cpu type.");
687                 rte_errno = ENOTSUP;
688                 return -1;
689         }
690
691         if (!rte_atomic32_test_and_set(&run_once)) {
692                 rte_eal_init_alert("already called initialization.");
693                 rte_errno = EALREADY;
694                 return -1;
695         }
696
697         thread_id = pthread_self();
698
699         eal_reset_internal_config(internal_conf);
700
701         /* clone argv to report out later in telemetry */
702         eal_save_args(argc, argv);
703
704         /* set log level as early as possible */
705         eal_log_level_parse(argc, argv);
706
707         if (rte_eal_cpu_init() < 0) {
708                 rte_eal_init_alert("Cannot detect lcores.");
709                 rte_errno = ENOTSUP;
710                 return -1;
711         }
712
713         fctret = eal_parse_args(argc, argv);
714         if (fctret < 0) {
715                 rte_eal_init_alert("Invalid 'command line' arguments.");
716                 rte_errno = EINVAL;
717                 rte_atomic32_clear(&run_once);
718                 return -1;
719         }
720
721         /* FreeBSD always uses legacy memory model */
722         internal_conf->legacy_mem = true;
723
724         if (eal_plugins_init() < 0) {
725                 rte_eal_init_alert("Cannot init plugins");
726                 rte_errno = EINVAL;
727                 rte_atomic32_clear(&run_once);
728                 return -1;
729         }
730
731         if (eal_trace_init() < 0) {
732                 rte_eal_init_alert("Cannot init trace");
733                 rte_errno = EFAULT;
734                 rte_atomic32_clear(&run_once);
735                 return -1;
736         }
737
738         if (eal_option_device_parse()) {
739                 rte_errno = ENODEV;
740                 rte_atomic32_clear(&run_once);
741                 return -1;
742         }
743
744         if (rte_config_init() < 0) {
745                 rte_eal_init_alert("Cannot init config");
746                 return -1;
747         }
748
749         if (rte_eal_intr_init() < 0) {
750                 rte_eal_init_alert("Cannot init interrupt-handling thread");
751                 return -1;
752         }
753
754         if (rte_eal_alarm_init() < 0) {
755                 rte_eal_init_alert("Cannot init alarm");
756                 /* rte_eal_alarm_init sets rte_errno on failure. */
757                 return -1;
758         }
759
760         /* Put mp channel init before bus scan so that we can init the vdev
761          * bus through mp channel in the secondary process before the bus scan.
762          */
763         if (rte_mp_channel_init() < 0 && rte_errno != ENOTSUP) {
764                 rte_eal_init_alert("failed to init mp channel");
765                 if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
766                         rte_errno = EFAULT;
767                         return -1;
768                 }
769         }
770
771         if (rte_bus_scan()) {
772                 rte_eal_init_alert("Cannot scan the buses for devices");
773                 rte_errno = ENODEV;
774                 rte_atomic32_clear(&run_once);
775                 return -1;
776         }
777
778         /* if no EAL option "--iova-mode=<pa|va>", use bus IOVA scheme */
779         if (internal_conf->iova_mode == RTE_IOVA_DC) {
780                 /* autodetect the IOVA mapping mode (default is RTE_IOVA_PA) */
781                 enum rte_iova_mode iova_mode = rte_bus_get_iommu_class();
782
783                 if (iova_mode == RTE_IOVA_DC)
784                         iova_mode = RTE_IOVA_PA;
785                 rte_eal_get_configuration()->iova_mode = iova_mode;
786         } else {
787                 rte_eal_get_configuration()->iova_mode =
788                         internal_conf->iova_mode;
789         }
790
791         RTE_LOG(INFO, EAL, "Selected IOVA mode '%s'\n",
792                 rte_eal_iova_mode() == RTE_IOVA_PA ? "PA" : "VA");
793
794         if (internal_conf->no_hugetlbfs == 0) {
795                 /* rte_config isn't initialized yet */
796                 ret = internal_conf->process_type == RTE_PROC_PRIMARY ?
797                         eal_hugepage_info_init() :
798                         eal_hugepage_info_read();
799                 if (ret < 0) {
800                         rte_eal_init_alert("Cannot get hugepage information.");
801                         rte_errno = EACCES;
802                         rte_atomic32_clear(&run_once);
803                         return -1;
804                 }
805         }
806
807         if (internal_conf->memory == 0 && internal_conf->force_sockets == 0) {
808                 if (internal_conf->no_hugetlbfs)
809                         internal_conf->memory = MEMSIZE_IF_NO_HUGE_PAGE;
810                 else
811                         internal_conf->memory = eal_get_hugepage_mem_size();
812         }
813
814         if (internal_conf->vmware_tsc_map == 1) {
815 #ifdef RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT
816                 rte_cycles_vmware_tsc_map = 1;
817                 RTE_LOG (DEBUG, EAL, "Using VMWARE TSC MAP, "
818                                 "you must have monitor_control.pseudo_perfctr = TRUE\n");
819 #else
820                 RTE_LOG (WARNING, EAL, "Ignoring --vmware-tsc-map because "
821                                 "RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT is not set\n");
822 #endif
823         }
824
825         /* in secondary processes, memory init may allocate additional fbarrays
826          * not present in primary processes, so to avoid any potential issues,
827          * initialize memzones first.
828          */
829         if (rte_eal_memzone_init() < 0) {
830                 rte_eal_init_alert("Cannot init memzone");
831                 rte_errno = ENODEV;
832                 return -1;
833         }
834
835         if (rte_eal_memory_init() < 0) {
836                 rte_eal_init_alert("Cannot init memory");
837                 rte_errno = ENOMEM;
838                 return -1;
839         }
840
841         if (rte_eal_malloc_heap_init() < 0) {
842                 rte_eal_init_alert("Cannot init malloc heap");
843                 rte_errno = ENODEV;
844                 return -1;
845         }
846
847         if (rte_eal_tailqs_init() < 0) {
848                 rte_eal_init_alert("Cannot init tail queues for objects");
849                 rte_errno = EFAULT;
850                 return -1;
851         }
852
853         if (rte_eal_timer_init() < 0) {
854                 rte_eal_init_alert("Cannot init HPET or TSC timers");
855                 rte_errno = ENOTSUP;
856                 return -1;
857         }
858
859         eal_check_mem_on_local_socket();
860
861         eal_thread_init_master(config->master_lcore);
862
863         ret = eal_thread_dump_affinity(cpuset, sizeof(cpuset));
864
865         RTE_LOG(DEBUG, EAL, "Master lcore %u is ready (tid=%p;cpuset=[%s%s])\n",
866                 config->master_lcore, thread_id, cpuset,
867                 ret == 0 ? "" : "...");
868
869         RTE_LCORE_FOREACH_SLAVE(i) {
870
871                 /*
872                  * create communication pipes between master thread
873                  * and children
874                  */
875                 if (pipe(lcore_config[i].pipe_master2slave) < 0)
876                         rte_panic("Cannot create pipe\n");
877                 if (pipe(lcore_config[i].pipe_slave2master) < 0)
878                         rte_panic("Cannot create pipe\n");
879
880                 lcore_config[i].state = WAIT;
881
882                 /* create a thread for each lcore */
883                 ret = pthread_create(&lcore_config[i].thread_id, NULL,
884                                      eal_thread_loop, NULL);
885                 if (ret != 0)
886                         rte_panic("Cannot create thread\n");
887
888                 /* Set thread_name for aid in debugging. */
889                 snprintf(thread_name, sizeof(thread_name),
890                                 "lcore-slave-%d", i);
891                 rte_thread_setname(lcore_config[i].thread_id, thread_name);
892         }
893
894         /*
895          * Launch a dummy function on all slave lcores, so that master lcore
896          * knows they are all ready when this function returns.
897          */
898         rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER);
899         rte_eal_mp_wait_lcore();
900
901         /* initialize services so vdevs register service during bus_probe. */
902         ret = rte_service_init();
903         if (ret) {
904                 rte_eal_init_alert("rte_service_init() failed");
905                 rte_errno = ENOEXEC;
906                 return -1;
907         }
908
909         /* Probe all the buses and devices/drivers on them */
910         if (rte_bus_probe()) {
911                 rte_eal_init_alert("Cannot probe devices");
912                 rte_errno = ENOTSUP;
913                 return -1;
914         }
915
916         /* initialize default service/lcore mappings and start running. Ignore
917          * -ENOTSUP, as it indicates no service coremask passed to EAL.
918          */
919         ret = rte_service_start_with_defaults();
920         if (ret < 0 && ret != -ENOTSUP) {
921                 rte_errno = ENOEXEC;
922                 return -1;
923         }
924
925         /*
926          * Clean up unused files in runtime directory. We do this at the end of
927          * init and not at the beginning because we want to clean stuff up
928          * whether we are primary or secondary process, but we cannot remove
929          * primary process' files because secondary should be able to run even
930          * if primary process is dead.
931          *
932          * In no_shconf mode, no runtime directory is created in the first
933          * place, so no cleanup needed.
934          */
935         if (!internal_conf->no_shconf && eal_clean_runtime_dir() < 0) {
936                 rte_eal_init_alert("Cannot clear runtime directory");
937                 return -1;
938         }
939         if (!internal_conf->no_telemetry) {
940                 const char *error_str = NULL;
941                 if (rte_telemetry_init(rte_eal_get_runtime_dir(),
942                                 &internal_conf->ctrl_cpuset, &error_str)
943                                 != 0) {
944                         rte_eal_init_alert(error_str);
945                         return -1;
946                 }
947                 if (error_str != NULL)
948                         RTE_LOG(NOTICE, EAL, "%s\n", error_str);
949         }
950
951         eal_mcfg_complete();
952
953         return fctret;
954 }
955
956 int
957 rte_eal_cleanup(void)
958 {
959         struct internal_config *internal_conf =
960                 eal_get_internal_configuration();
961         rte_service_finalize();
962         rte_mp_channel_cleanup();
963         rte_trace_save();
964         eal_trace_fini();
965         eal_cleanup_config(internal_conf);
966         return 0;
967 }
968
969 int rte_eal_create_uio_dev(void)
970 {
971         const struct internal_config *internal_conf =
972                 eal_get_internal_configuration();
973         return internal_conf->create_uio_dev;
974 }
975
976 enum rte_intr_mode
977 rte_eal_vfio_intr_mode(void)
978 {
979         return RTE_INTR_MODE_NONE;
980 }
981
982 int rte_vfio_setup_device(__rte_unused const char *sysfs_base,
983                       __rte_unused const char *dev_addr,
984                       __rte_unused int *vfio_dev_fd,
985                       __rte_unused struct vfio_device_info *device_info)
986 {
987         return -1;
988 }
989
990 int rte_vfio_release_device(__rte_unused const char *sysfs_base,
991                         __rte_unused const char *dev_addr,
992                         __rte_unused int fd)
993 {
994         return -1;
995 }
996
997 int rte_vfio_enable(__rte_unused const char *modname)
998 {
999         return -1;
1000 }
1001
1002 int rte_vfio_is_enabled(__rte_unused const char *modname)
1003 {
1004         return 0;
1005 }
1006
1007 int rte_vfio_noiommu_is_enabled(void)
1008 {
1009         return 0;
1010 }
1011
1012 int rte_vfio_clear_group(__rte_unused int vfio_group_fd)
1013 {
1014         return 0;
1015 }
1016
1017 int
1018 rte_vfio_get_group_num(__rte_unused const char *sysfs_base,
1019                        __rte_unused const char *dev_addr,
1020                        __rte_unused int *iommu_group_num)
1021 {
1022         return -1;
1023 }
1024
1025 int
1026 rte_vfio_get_container_fd(void)
1027 {
1028         return -1;
1029 }
1030
1031 int
1032 rte_vfio_get_group_fd(__rte_unused int iommu_group_num)
1033 {
1034         return -1;
1035 }
1036
1037 int
1038 rte_vfio_container_create(void)
1039 {
1040         return -1;
1041 }
1042
1043 int
1044 rte_vfio_container_destroy(__rte_unused int container_fd)
1045 {
1046         return -1;
1047 }
1048
1049 int
1050 rte_vfio_container_group_bind(__rte_unused int container_fd,
1051                 __rte_unused int iommu_group_num)
1052 {
1053         return -1;
1054 }
1055
1056 int
1057 rte_vfio_container_group_unbind(__rte_unused int container_fd,
1058                 __rte_unused int iommu_group_num)
1059 {
1060         return -1;
1061 }
1062
1063 int
1064 rte_vfio_container_dma_map(__rte_unused int container_fd,
1065                         __rte_unused uint64_t vaddr,
1066                         __rte_unused uint64_t iova,
1067                         __rte_unused uint64_t len)
1068 {
1069         return -1;
1070 }
1071
1072 int
1073 rte_vfio_container_dma_unmap(__rte_unused int container_fd,
1074                         __rte_unused uint64_t vaddr,
1075                         __rte_unused uint64_t iova,
1076                         __rte_unused uint64_t len)
1077 {
1078         return -1;
1079 }