1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation 3 */ 4 5 #include <stdio.h> 6 7 #include "test.h" 8 9 #include <stdint.h> 10 #include <stdlib.h> 11 #include <stdarg.h> 12 #include <inttypes.h> 13 #include <sys/queue.h> 14 #include <errno.h> 15 #include <string.h> 16 #include <unistd.h> 17 #include <sys/wait.h> 18 #include <libgen.h> 19 #include <dirent.h> 20 #include <limits.h> 21 22 #include <rte_common.h> 23 #include <rte_memory.h> 24 #include <rte_memzone.h> 25 #include <rte_eal.h> 26 #include <rte_launch.h> 27 #include <rte_per_lcore.h> 28 #include <rte_lcore.h> 29 #include <rte_errno.h> 30 #include <rte_branch_prediction.h> 31 #include <rte_atomic.h> 32 #include <rte_ring.h> 33 #include <rte_debug.h> 34 #include <rte_log.h> 35 #include <rte_mempool.h> 36 37 #ifdef RTE_LIB_HASH 38 #include <rte_hash.h> 39 #include <rte_fbk_hash.h> 40 #endif /* RTE_LIB_HASH */ 41 42 #ifdef RTE_LIB_LPM 43 #include <rte_lpm.h> 44 #endif /* RTE_LIB_LPM */ 45 46 #include <rte_string_fns.h> 47 48 #include "process.h" 49 50 #define launch_proc(ARGV) process_dup(ARGV, RTE_DIM(ARGV), __func__) 51 52 /* 53 * This function is called in the primary i.e. main test, to spawn off secondary 54 * processes to run actual mp tests. Uses fork() and exec pair 55 */ 56 static int 57 run_secondary_instances(void) 58 { 59 int ret = 0; 60 char coremask[10]; 61 62 #ifdef RTE_EXEC_ENV_LINUX 63 char tmp[PATH_MAX] = {0}; 64 char prefix[PATH_MAX] = {0}; 65 66 get_current_prefix(tmp, sizeof(tmp)); 67 68 snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); 69 #else 70 const char *prefix = ""; 71 #endif 72 73 /* good case, using secondary */ 74 const char *argv1[] = { 75 prgname, "-c", coremask, "--proc-type=secondary", 76 prefix 77 }; 78 /* good case, using auto */ 79 const char *argv2[] = { 80 prgname, "-c", coremask, "--proc-type=auto", 81 prefix 82 }; 83 /* bad case, using invalid type */ 84 const char *argv3[] = { 85 prgname, "-c", coremask, "--proc-type=ERROR", 86 prefix 87 }; 88 #ifdef RTE_EXEC_ENV_LINUX 89 /* bad case, using invalid file prefix */ 90 const char *argv4[] = { 91 prgname, "-c", coremask, "--proc-type=secondary", 92 "--file-prefix=ERROR" 93 }; 94 #endif 95 96 snprintf(coremask, sizeof(coremask), "%x", \ 97 (1 << rte_get_main_lcore())); 98 99 ret |= launch_proc(argv1); 100 printf("### Testing rte_mp_disable() reject:\n"); 101 if (rte_mp_disable()) { 102 printf("Error: rte_mp_disable() has been accepted\n"); 103 ret |= -1; 104 } else { 105 printf("# Checked rte_mp_disable() is refused\n"); 106 } 107 ret |= launch_proc(argv2); 108 109 ret |= !(launch_proc(argv3)); 110 #ifdef RTE_EXEC_ENV_LINUX 111 ret |= !(launch_proc(argv4)); 112 #endif 113 114 return ret; 115 } 116 117 /* 118 * This function is run in the secondary instance to test that creation of 119 * objects fails in a secondary 120 */ 121 static int 122 run_object_creation_tests(void) 123 { 124 const unsigned flags = 0; 125 const unsigned size = 1024; 126 const unsigned elt_size = 64; 127 const unsigned cache_size = 64; 128 const unsigned priv_data_size = 32; 129 130 printf("### Testing object creation - expect lots of mz reserve errors!\n"); 131 132 rte_errno = 0; 133 if ((rte_memzone_reserve("test_mz", size, rte_socket_id(), 134 flags) == NULL) && 135 (rte_memzone_lookup("test_mz") == NULL)) { 136 printf("Error: unexpected return value from rte_memzone_reserve\n"); 137 return -1; 138 } 139 printf("# Checked rte_memzone_reserve() OK\n"); 140 141 rte_errno = 0; 142 if ((rte_ring_create( 143 "test_ring", size, rte_socket_id(), flags) == NULL) && 144 (rte_ring_lookup("test_ring") == NULL)){ 145 printf("Error: unexpected return value from rte_ring_create()\n"); 146 return -1; 147 } 148 printf("# Checked rte_ring_create() OK\n"); 149 150 rte_errno = 0; 151 if ((rte_mempool_create("test_mp", size, elt_size, cache_size, 152 priv_data_size, NULL, NULL, NULL, NULL, 153 rte_socket_id(), flags) == NULL) && 154 (rte_mempool_lookup("test_mp") == NULL)){ 155 printf("Error: unexpected return value from rte_mempool_create()\n"); 156 return -1; 157 } 158 printf("# Checked rte_mempool_create() OK\n"); 159 160 #ifdef RTE_LIB_HASH 161 const struct rte_hash_parameters hash_params = { .name = "test_mp_hash" }; 162 rte_errno=0; 163 if ((rte_hash_create(&hash_params) != NULL) && 164 (rte_hash_find_existing(hash_params.name) == NULL)){ 165 printf("Error: unexpected return value from rte_hash_create()\n"); 166 return -1; 167 } 168 printf("# Checked rte_hash_create() OK\n"); 169 170 const struct rte_fbk_hash_params fbk_params = { .name = "test_fbk_mp_hash" }; 171 rte_errno=0; 172 if ((rte_fbk_hash_create(&fbk_params) != NULL) && 173 (rte_fbk_hash_find_existing(fbk_params.name) == NULL)){ 174 printf("Error: unexpected return value from rte_fbk_hash_create()\n"); 175 return -1; 176 } 177 printf("# Checked rte_fbk_hash_create() OK\n"); 178 #endif 179 180 #ifdef RTE_LIB_LPM 181 rte_errno=0; 182 struct rte_lpm_config config; 183 184 config.max_rules = rte_socket_id(); 185 config.number_tbl8s = 256; 186 config.flags = 0; 187 if ((rte_lpm_create("test_lpm", size, &config) != NULL) && 188 (rte_lpm_find_existing("test_lpm") == NULL)){ 189 printf("Error: unexpected return value from rte_lpm_create()\n"); 190 return -1; 191 } 192 printf("# Checked rte_lpm_create() OK\n"); 193 #endif 194 195 return 0; 196 } 197 198 /* if called in a primary process, just spawns off a secondary process to 199 * run validation tests - which brings us right back here again... 200 * if called in a secondary process, this runs a series of API tests to check 201 * how things run in a secondary instance. 202 */ 203 int 204 test_mp_secondary(void) 205 { 206 if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 207 return run_secondary_instances(); 208 } 209 210 printf("IN SECONDARY PROCESS\n"); 211 212 return run_object_creation_tests(); 213 } 214 215 REGISTER_TEST_COMMAND(multiprocess_autotest, test_mp_secondary); 216