static int fbk_hash_perf_test(void) { struct rte_fbk_hash_params params = { .name = "fbk_hash_test", .entries = ENTRIES, .entries_per_bucket = 4, .socket_id = rte_socket_id(), }; struct rte_fbk_hash_table *handle; uint32_t keys[ENTRIES] = {0}; unsigned indexes[TEST_SIZE]; uint64_t lookup_time = 0; unsigned added = 0; unsigned value = 0; unsigned i, j; handle = rte_fbk_hash_create(¶ms); RETURN_IF_ERROR_FBK(handle == NULL, "fbk hash creation failed"); /* Generate random keys and values. */ for (i = 0; i < ENTRIES; i++) { uint32_t key = (uint32_t)rte_rand(); key = ((uint64_t)key << 32) | (uint64_t)rte_rand(); uint16_t val = (uint16_t)rte_rand(); if (rte_fbk_hash_add_key(handle, key, val) == 0) { keys[added] = key; added++; } if (added > (LOAD_FACTOR * ENTRIES)) { break; } } for (i = 0; i < TEST_ITERATIONS; i++) { uint64_t begin; uint64_t end; /* Generate random indexes into keys[] array. */ for (j = 0; j < TEST_SIZE; j++) { indexes[j] = rte_rand() % added; } begin = rte_rdtsc(); /* Do lookups */ for (j = 0; j < TEST_SIZE; j++) { value += rte_fbk_hash_lookup(handle, keys[indexes[j]]); } end = rte_rdtsc(); lookup_time += (double)(end - begin); } printf("\n\n *** FBK Hash function performance test results ***\n"); /* * The use of the 'value' variable ensures that the hash lookup is not * being optimised out by the compiler. */ if (value != 0) printf("Number of ticks per lookup = %g\n", (double)lookup_time / ((double)TEST_ITERATIONS * (double)TEST_SIZE)); rte_fbk_hash_free(handle); return 0; } /* * Do all unit and performance tests. */ int test_hash_perf(void) { if (run_all_tbl_perf_tests() < 0) return -1; run_hash_func_tests(); if (fbk_hash_perf_test() < 0) return -1; return 0; } #else /* RTE_LIBRTE_HASH */ int test_hash_perf(void) { printf("The Hash library is not included in this build\n"); return 0; }
static int fbk_hash_perf_test(void) { struct rte_fbk_hash_params params = { .name = "fbk_hash_test", .entries = ENTRIES, .entries_per_bucket = 4, .socket_id = rte_socket_id(), }; struct rte_fbk_hash_table *handle = NULL; uint32_t *keys = NULL; unsigned indexes[TEST_SIZE]; uint64_t lookup_time = 0; unsigned added = 0; unsigned value = 0; uint32_t key; uint16_t val; unsigned i, j; handle = rte_fbk_hash_create(¶ms); if (handle == NULL) { printf("Error creating table\n"); return -1; } keys = rte_zmalloc(NULL, ENTRIES * sizeof(*keys), 0); if (keys == NULL) { printf("fbk hash: memory allocation for key store failed\n"); return -1; } /* Generate random keys and values. */ for (i = 0; i < ENTRIES; i++) { key = (uint32_t)rte_rand(); key = ((uint64_t)key << 32) | (uint64_t)rte_rand(); val = (uint16_t)rte_rand(); if (rte_fbk_hash_add_key(handle, key, val) == 0) { keys[added] = key; added++; } if (added > (LOAD_FACTOR * ENTRIES)) break; } for (i = 0; i < TEST_ITERATIONS; i++) { uint64_t begin; uint64_t end; /* Generate random indexes into keys[] array. */ for (j = 0; j < TEST_SIZE; j++) indexes[j] = rte_rand() % added; begin = rte_rdtsc(); /* Do lookups */ for (j = 0; j < TEST_SIZE; j++) value += rte_fbk_hash_lookup(handle, keys[indexes[j]]); end = rte_rdtsc(); lookup_time += (double)(end - begin); } printf("\n\n *** FBK Hash function performance test results ***\n"); /* * The use of the 'value' variable ensures that the hash lookup is not * being optimised out by the compiler. */ if (value != 0) printf("Number of ticks per lookup = %g\n", (double)lookup_time / ((double)TEST_ITERATIONS * (double)TEST_SIZE)); rte_fbk_hash_free(handle); return 0; } static int test_hash_perf(void) { unsigned with_pushes; for (with_pushes = 0; with_pushes <= 1; with_pushes++) { if (with_pushes == 0) printf("\nALL ELEMENTS IN PRIMARY LOCATION\n"); else printf("\nELEMENTS IN PRIMARY OR SECONDARY LOCATION\n"); if (run_all_tbl_perf_tests(with_pushes) < 0) return -1; } if (fbk_hash_perf_test() < 0) return -1; return 0; }
/* * This function is run in the secondary instance to test that creation of * objects fails in a secondary */ static int run_object_creation_tests(void) { const unsigned flags = 0; const unsigned size = 1024; const unsigned elt_size = 64; const unsigned cache_size = 64; const unsigned priv_data_size = 32; printf("### Testing object creation - expect lots of mz reserve errors!\n"); rte_errno = 0; if ((rte_memzone_reserve("test_mz", size, rte_socket_id(), flags) == NULL) && (rte_memzone_lookup("test_mz") == NULL)) { printf("Error: unexpected return value from rte_memzone_reserve\n"); return -1; } printf("# Checked rte_memzone_reserve() OK\n"); rte_errno = 0; if ((rte_ring_create( "test_ring", size, rte_socket_id(), flags) == NULL) && (rte_ring_lookup("test_ring") == NULL)){ printf("Error: unexpected return value from rte_ring_create()\n"); return -1; } printf("# Checked rte_ring_create() OK\n"); rte_errno = 0; if ((rte_mempool_create("test_mp", size, elt_size, cache_size, priv_data_size, NULL, NULL, NULL, NULL, rte_socket_id(), flags) == NULL) && (rte_mempool_lookup("test_mp") == NULL)){ printf("Error: unexpected return value from rte_mempool_create()\n"); return -1; } printf("# Checked rte_mempool_create() OK\n"); #ifdef RTE_LIBRTE_HASH const struct rte_hash_parameters hash_params = { .name = "test_mp_hash" }; rte_errno=0; if ((rte_hash_create(&hash_params) != NULL) && (rte_hash_find_existing(hash_params.name) == NULL)){ printf("Error: unexpected return value from rte_hash_create()\n"); return -1; } printf("# Checked rte_hash_create() OK\n"); const struct rte_fbk_hash_params fbk_params = { .name = "test_fbk_mp_hash" }; rte_errno=0; if ((rte_fbk_hash_create(&fbk_params) != NULL) && (rte_fbk_hash_find_existing(fbk_params.name) == NULL)){ printf("Error: unexpected return value from rte_fbk_hash_create()\n"); return -1; } printf("# Checked rte_fbk_hash_create() OK\n"); #endif #ifdef RTE_LIBRTE_LPM rte_errno=0; struct rte_lpm_config config; config.max_rules = rte_socket_id(); config.number_tbl8s = 256; config.flags = 0; if ((rte_lpm_create("test_lpm", size, &config) != NULL) && (rte_lpm_find_existing("test_lpm") == NULL)){ printf("Error: unexpected return value from rte_lpm_create()\n"); return -1; } printf("# Checked rte_lpm_create() OK\n"); #endif /* Run a test_pci call */ if (test_pci() != 0) { printf("PCI scan failed in secondary\n"); if (getuid() == 0) /* pci scans can fail as non-root */ return -1; } else printf("PCI scan succeeded in secondary\n"); return 0; } /* if called in a primary process, just spawns off a secondary process to * run validation tests - which brings us right back here again... * if called in a secondary process, this runs a series of API tests to check * how things run in a secondary instance. */ int test_mp_secondary(void) { if (rte_eal_process_type() == RTE_PROC_PRIMARY) { if (!test_pci_run) { printf("=== Running pre-requisite test of test_pci\n"); test_pci(); printf("=== Requisite test done\n"); } return run_secondary_instances(); } printf("IN SECONDARY PROCESS\n"); return run_object_creation_tests(); } static struct test_command multiprocess_cmd = { .command = "multiprocess_autotest", .callback = test_mp_secondary, }; REGISTER_TEST_COMMAND(multiprocess_cmd);