eal: do not panic on interrupt thread init
[dpdk.git] / lib / librte_eal / bsdapp / eal / eal.c
index 1b6f705..0c157b4 100644 (file)
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   Copyright(c) 2014 6WIND S.A.
  *   All rights reserved.
  *
@@ -56,6 +56,7 @@
 #include <rte_launch.h>
 #include <rte_eal.h>
 #include <rte_eal_memconfig.h>
+#include <rte_errno.h>
 #include <rte_per_lcore.h>
 #include <rte_lcore.h>
 #include <rte_log.h>
@@ -64,6 +65,7 @@
 #include <rte_string_fns.h>
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
+#include <rte_bus.h>
 #include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
@@ -312,8 +314,14 @@ eal_log_level_parse(int argc, char **argv)
        int opt;
        char **argvopt;
        int option_index;
+       const int old_optind = optind;
+       const int old_optopt = optopt;
+       const int old_optreset = optreset;
+       char * const old_optarg = optarg;
 
        argvopt = argv;
+       optind = 1;
+       optreset = 1;
 
        eal_reset_internal_config(&internal_config);
 
@@ -334,7 +342,11 @@ eal_log_level_parse(int argc, char **argv)
                        break;
        }
 
-       optind = 0; /* reset getopt lib */
+       /* restore getopt lib */
+       optind = old_optind;
+       optopt = old_optopt;
+       optreset = old_optreset;
+       optarg = old_optarg;
 }
 
 /* Parse the argument given in the command line of the application */
@@ -345,25 +357,31 @@ eal_parse_args(int argc, char **argv)
        char **argvopt;
        int option_index;
        char *prgname = argv[0];
+       const int old_optind = optind;
+       const int old_optopt = optopt;
+       const int old_optreset = optreset;
+       char * const old_optarg = optarg;
 
        argvopt = argv;
+       optind = 1;
+       optreset = 1;
 
        while ((opt = getopt_long(argc, argvopt, eal_short_options,
                                  eal_long_options, &option_index)) != EOF) {
 
-               int ret;
-
                /* getopt is not happy, stop right now */
                if (opt == '?') {
                        eal_usage(prgname);
-                       return -1;
+                       ret = -1;
+                       goto out;
                }
 
                ret = eal_parse_common_option(opt, optarg, &internal_config);
                /* common parser is not happy */
                if (ret < 0) {
                        eal_usage(prgname);
-                       return -1;
+                       ret = -1;
+                       goto out;
                }
                /* common parser handled this option */
                if (ret == 0)
@@ -387,23 +405,34 @@ eal_parse_args(int argc, char **argv)
                                        "on FreeBSD\n", opt);
                        }
                        eal_usage(prgname);
-                       return -1;
+                       ret = -1;
+                       goto out;
                }
        }
 
-       if (eal_adjust_config(&internal_config) != 0)
-               return -1;
+       if (eal_adjust_config(&internal_config) != 0) {
+               ret = -1;
+               goto out;
+       }
 
        /* sanity checks */
        if (eal_check_common_options(&internal_config) != 0) {
                eal_usage(prgname);
-               return -1;
+               ret = -1;
+               goto out;
        }
 
        if (optind >= 0)
                argv[optind-1] = prgname;
        ret = optind-1;
-       optind = 0; /* reset getopt lib */
+
+out:
+       /* restore getopt lib */
+       optind = old_optind;
+       optopt = old_optopt;
+       optreset = old_optreset;
+       optarg = old_optarg;
+
        return ret;
 }
 
@@ -459,6 +488,12 @@ rte_eal_iopl_init(void)
        return 0;
 }
 
+static void rte_eal_init_alert(const char *msg)
+{
+       fprintf(stderr, "EAL: FATAL: %s\n", msg);
+       RTE_LOG(ERR, EAL, "%s\n", msg);
+}
+
 /* Launch threads, called at application init(). */
 int
 rte_eal_init(int argc, char **argv)
@@ -467,31 +502,50 @@ rte_eal_init(int argc, char **argv)
        pthread_t thread_id;
        static rte_atomic32_t run_once = RTE_ATOMIC32_INIT(0);
        char cpuset[RTE_CPU_AFFINITY_STR_LEN];
+       char thread_name[RTE_MAX_THREAD_NAME_LEN];
+
+       /* checks if the machine is adequate */
+       if (!rte_cpu_is_supported()) {
+               rte_eal_init_alert("unsupported cpu type.");
+               rte_errno = ENOTSUP;
+               return -1;
+       }
 
-       if (!rte_atomic32_test_and_set(&run_once))
+       if (!rte_atomic32_test_and_set(&run_once)) {
+               rte_eal_init_alert("already called initialization.");
+               rte_errno = EALREADY;
                return -1;
+       }
 
        thread_id = pthread_self();
 
-       if (rte_eal_log_early_init() < 0)
-               rte_panic("Cannot init early logs\n");
-
        eal_log_level_parse(argc, argv);
 
        /* set log level as early as possible */
        rte_set_log_level(internal_config.log_level);
 
-       if (rte_eal_cpu_init() < 0)
-               rte_panic("Cannot detect lcores\n");
+       if (rte_eal_cpu_init() < 0) {
+               rte_eal_init_alert("Cannot detect lcores.");
+               rte_errno = ENOTSUP;
+               return -1;
+       }
 
        fctret = eal_parse_args(argc, argv);
-       if (fctret < 0)
-               exit(1);
+       if (fctret < 0) {
+               rte_eal_init_alert("Invalid 'command line' arguments.");
+               rte_errno = EINVAL;
+               rte_atomic32_clear(&run_once);
+               return -1;
+       }
 
        if (internal_config.no_hugetlbfs == 0 &&
                        internal_config.process_type != RTE_PROC_SECONDARY &&
-                       eal_hugepage_info_init() < 0)
-               rte_panic("Cannot get hugepage information\n");
+                       eal_hugepage_info_init() < 0) {
+               rte_eal_init_alert("Cannot get hugepage information.");
+               rte_errno = EACCES;
+               rte_atomic32_clear(&run_once);
+               return -1;
+       }
 
        if (internal_config.memory == 0 && internal_config.force_sockets == 0) {
                if (internal_config.no_hugetlbfs)
@@ -515,33 +569,48 @@ rte_eal_init(int argc, char **argv)
 
        rte_config_init();
 
-       if (rte_eal_memory_init() < 0)
-               rte_panic("Cannot init memory\n");
-
-       if (rte_eal_memzone_init() < 0)
-               rte_panic("Cannot init memzone\n");
+       if (rte_eal_memory_init() < 0) {
+               rte_eal_init_alert("Cannot init memory\n");
+               rte_errno = ENOMEM;
+               return -1;
+       }
 
-       if (rte_eal_tailqs_init() < 0)
-               rte_panic("Cannot init tail queues for objects\n");
+       if (rte_eal_memzone_init() < 0) {
+               rte_eal_init_alert("Cannot init memzone\n");
+               rte_errno = ENODEV;
+               return -1;
+       }
 
-/*     if (rte_eal_log_init(argv[0], internal_config.syslog_facility) < 0)
-               rte_panic("Cannot init logs\n");*/
+       if (rte_eal_tailqs_init() < 0) {
+               rte_eal_init_alert("Cannot init tail queues for objects\n");
+               rte_errno = EFAULT;
+               return -1;
+       }
 
-       if (rte_eal_alarm_init() < 0)
-               rte_panic("Cannot init interrupt-handling thread\n");
+       if (rte_eal_alarm_init() < 0) {
+               rte_eal_init_alert("Cannot init interrupt-handling thread\n");
+               /* rte_eal_alarm_init sets rte_errno on failure. */
+               return -1;
+       }
 
-       if (rte_eal_intr_init() < 0)
-               rte_panic("Cannot init interrupt-handling thread\n");
+       if (rte_eal_intr_init() < 0) {
+               rte_eal_init_alert("Cannot init interrupt-handling thread\n");
+               return -1;
+       }
 
-       if (rte_eal_timer_init() < 0)
-               rte_panic("Cannot init HPET or TSC timers\n");
+       if (rte_eal_timer_init() < 0) {
+               rte_eal_init_alert("Cannot init HPET or TSC timers\n");
+               rte_errno = ENOTSUP;
+               return -1;
+       }
 
        if (rte_eal_pci_init() < 0)
                rte_panic("Cannot init PCI\n");
 
        eal_check_mem_on_local_socket();
 
-       rte_eal_mcfg_complete();
+       if (eal_plugins_init() < 0)
+               rte_panic("Cannot init plugins\n");
 
        eal_thread_init_master(rte_config.master_lcore);
 
@@ -551,8 +620,8 @@ rte_eal_init(int argc, char **argv)
                rte_config.master_lcore, thread_id, cpuset,
                ret == 0 ? "" : "...");
 
-       if (rte_eal_dev_init() < 0)
-               rte_panic("Cannot init pmd devices\n");
+       if (rte_bus_scan())
+               rte_panic("Cannot scan the buses for devices\n");
 
        RTE_LCORE_FOREACH_SLAVE(i) {
 
@@ -572,6 +641,11 @@ rte_eal_init(int argc, char **argv)
                                     eal_thread_loop, NULL);
                if (ret != 0)
                        rte_panic("Cannot create thread\n");
+
+               /* Set thread_name for aid in debugging. */
+               snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN,
+                               "lcore-slave-%d", i);
+               rte_thread_setname(lcore_config[i].thread_id, thread_name);
        }
 
        /*
@@ -581,10 +655,19 @@ rte_eal_init(int argc, char **argv)
        rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER);
        rte_eal_mp_wait_lcore();
 
+       /* Probe all the buses and devices/drivers on them */
+       if (rte_bus_probe())
+               rte_panic("Cannot probe devices\n");
+
        /* Probe & Initialize PCI devices */
        if (rte_eal_pci_probe())
                rte_panic("Cannot probe PCI\n");
 
+       if (rte_eal_dev_init() < 0)
+               rte_panic("Cannot init pmd devices\n");
+
+       rte_eal_mcfg_complete();
+
        return fctret;
 }