1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2017 Cavium, Inc 3 */ 4 5 #include <stdio.h> 6 #include <unistd.h> 7 #include <signal.h> 8 9 #include <rte_debug.h> 10 #include <rte_eal.h> 11 #include <rte_eventdev.h> 12 13 #include "evt_options.h" 14 #include "evt_test.h" 15 16 struct evt_options opt; 17 struct evt_test *test; 18 19 static void 20 signal_handler(int signum) 21 { 22 int i; 23 static uint8_t once; 24 25 if ((signum == SIGINT || signum == SIGTERM) && !once) { 26 once = true; 27 printf("\nSignal %d received, preparing to exit...\n", 28 signum); 29 30 if (test != NULL) { 31 /* request all lcores to exit from the main loop */ 32 *(int *)test->test_priv = true; 33 rte_wmb(); 34 35 if (test->ops.ethdev_destroy) 36 test->ops.ethdev_destroy(test, &opt); 37 38 rte_eal_mp_wait_lcore(); 39 40 if (test->ops.test_result) 41 test->ops.test_result(test, &opt); 42 43 if (opt.prod_type == EVT_PROD_TYPE_ETH_RX_ADPTR) { 44 RTE_ETH_FOREACH_DEV(i) 45 rte_eth_dev_close(i); 46 } 47 48 if (test->ops.eventdev_destroy) 49 test->ops.eventdev_destroy(test, &opt); 50 51 if (test->ops.mempool_destroy) 52 test->ops.mempool_destroy(test, &opt); 53 54 if (test->ops.test_destroy) 55 test->ops.test_destroy(test, &opt); 56 } 57 58 /* exit with the expected status */ 59 signal(signum, SIG_DFL); 60 kill(getpid(), signum); 61 } 62 } 63 64 static inline void 65 evt_options_dump_all(struct evt_test *test, struct evt_options *opts) 66 { 67 evt_options_dump(opts); 68 if (test->ops.opt_dump) 69 test->ops.opt_dump(opts); 70 } 71 72 int 73 main(int argc, char **argv) 74 { 75 uint8_t evdevs; 76 int ret; 77 78 signal(SIGINT, signal_handler); 79 signal(SIGTERM, signal_handler); 80 81 ret = rte_eal_init(argc, argv); 82 if (ret < 0) 83 rte_panic("invalid EAL arguments\n"); 84 argc -= ret; 85 argv += ret; 86 87 evdevs = rte_event_dev_count(); 88 if (!evdevs) 89 rte_panic("no eventdev devices found\n"); 90 91 /* Populate the default values of the options */ 92 evt_options_default(&opt); 93 94 /* Parse the command line arguments */ 95 ret = evt_options_parse(&opt, argc, argv); 96 if (ret) { 97 evt_err("parsing one or more user options failed"); 98 goto error; 99 } 100 101 /* Get struct evt_test *test from name */ 102 test = evt_test_get(opt.test_name); 103 if (test == NULL) { 104 evt_err("failed to find requested test: %s", opt.test_name); 105 goto error; 106 } 107 108 if (test->ops.test_result == NULL) { 109 evt_err("%s: ops.test_result not found", opt.test_name); 110 goto error; 111 } 112 113 /* Verify the command line options */ 114 if (opt.dev_id >= rte_event_dev_count()) { 115 evt_err("invalid event device %d", opt.dev_id); 116 goto error; 117 } 118 if (test->ops.opt_check) { 119 if (test->ops.opt_check(&opt)) { 120 evt_err("invalid command line argument"); 121 evt_options_dump_all(test, &opt); 122 goto error; 123 } 124 } 125 126 /* Check the eventdev capability before proceeding */ 127 if (test->ops.cap_check) { 128 if (test->ops.cap_check(&opt) == false) { 129 evt_info("unsupported test: %s", opt.test_name); 130 evt_options_dump_all(test, &opt); 131 ret = EVT_TEST_UNSUPPORTED; 132 goto nocap; 133 } 134 } 135 136 /* Dump the options */ 137 if (opt.verbose_level) 138 evt_options_dump_all(test, &opt); 139 140 /* Test specific setup */ 141 if (test->ops.test_setup) { 142 if (test->ops.test_setup(test, &opt)) { 143 evt_err("failed to setup test: %s", opt.test_name); 144 goto error; 145 146 } 147 } 148 149 /* Test specific mempool setup */ 150 if (test->ops.mempool_setup) { 151 if (test->ops.mempool_setup(test, &opt)) { 152 evt_err("%s: mempool setup failed", opt.test_name); 153 goto test_destroy; 154 } 155 } 156 157 /* Test specific ethdev setup */ 158 if (test->ops.ethdev_setup) { 159 if (test->ops.ethdev_setup(test, &opt)) { 160 evt_err("%s: ethdev setup failed", opt.test_name); 161 goto mempool_destroy; 162 } 163 } 164 165 /* Test specific eventdev setup */ 166 if (test->ops.eventdev_setup) { 167 if (test->ops.eventdev_setup(test, &opt)) { 168 evt_err("%s: eventdev setup failed", opt.test_name); 169 goto ethdev_destroy; 170 } 171 } 172 173 /* Launch lcores */ 174 if (test->ops.launch_lcores) { 175 if (test->ops.launch_lcores(test, &opt)) { 176 evt_err("%s: failed to launch lcores", opt.test_name); 177 goto eventdev_destroy; 178 } 179 } 180 181 rte_eal_mp_wait_lcore(); 182 183 /* Print the test result */ 184 ret = test->ops.test_result(test, &opt); 185 nocap: 186 if (ret == EVT_TEST_SUCCESS) { 187 printf("Result: "CLGRN"%s"CLNRM"\n", "Success"); 188 } else if (ret == EVT_TEST_FAILED) { 189 printf("Result: "CLRED"%s"CLNRM"\n", "Failed"); 190 return EXIT_FAILURE; 191 } else if (ret == EVT_TEST_UNSUPPORTED) { 192 printf("Result: "CLYEL"%s"CLNRM"\n", "Unsupported"); 193 } 194 195 return 0; 196 eventdev_destroy: 197 if (test->ops.eventdev_destroy) 198 test->ops.eventdev_destroy(test, &opt); 199 200 ethdev_destroy: 201 if (test->ops.ethdev_destroy) 202 test->ops.ethdev_destroy(test, &opt); 203 204 mempool_destroy: 205 if (test->ops.mempool_destroy) 206 test->ops.mempool_destroy(test, &opt); 207 208 test_destroy: 209 if (test->ops.test_destroy) 210 test->ops.test_destroy(test, &opt); 211 error: 212 return EXIT_FAILURE; 213 } 214