X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest%2Ftest_hash.c;h=afa3a1a3cb486ea9f877f340034b49d104399107;hb=f2fc83b40f06da6a6b2476005279ba52d4ce3c44;hp=390fbef87f42b7bc1bf6748fbdc63769653ee1c9;hpb=54e5545d33eff911c1024479eb52d68dbf45139b;p=dpdk.git diff --git a/app/test/test_hash.c b/app/test/test_hash.c index 390fbef87f..afa3a1a3cb 100644 --- a/app/test/test_hash.c +++ b/app/test/test_hash.c @@ -67,7 +67,7 @@ struct flow_key { uint16_t port_src; uint16_t port_dst; uint8_t proto; -} __attribute__((packed)); +} __rte_packed; int hash_logtype_test; @@ -75,9 +75,9 @@ int hash_logtype_test; * Hash function that always returns the same value, to easily test what * happens when a bucket is full. */ -static uint32_t pseudo_hash(__attribute__((unused)) const void *keys, - __attribute__((unused)) uint32_t key_len, - __attribute__((unused)) uint32_t init_val) +static uint32_t pseudo_hash(__rte_unused const void *keys, + __rte_unused uint32_t key_len, + __rte_unused uint32_t init_val) { return 3; } @@ -104,32 +104,32 @@ static void print_key_info(const char *msg, const struct flow_key *key, /* Keys used by unit test functions */ static struct flow_key keys[5] = { { - .ip_src = IPv4(0x03, 0x02, 0x01, 0x00), - .ip_dst = IPv4(0x07, 0x06, 0x05, 0x04), + .ip_src = RTE_IPV4(0x03, 0x02, 0x01, 0x00), + .ip_dst = RTE_IPV4(0x07, 0x06, 0x05, 0x04), .port_src = 0x0908, .port_dst = 0x0b0a, .proto = 0x0c, }, { - .ip_src = IPv4(0x13, 0x12, 0x11, 0x10), - .ip_dst = IPv4(0x17, 0x16, 0x15, 0x14), + .ip_src = RTE_IPV4(0x13, 0x12, 0x11, 0x10), + .ip_dst = RTE_IPV4(0x17, 0x16, 0x15, 0x14), .port_src = 0x1918, .port_dst = 0x1b1a, .proto = 0x1c, }, { - .ip_src = IPv4(0x23, 0x22, 0x21, 0x20), - .ip_dst = IPv4(0x27, 0x26, 0x25, 0x24), + .ip_src = RTE_IPV4(0x23, 0x22, 0x21, 0x20), + .ip_dst = RTE_IPV4(0x27, 0x26, 0x25, 0x24), .port_src = 0x2928, .port_dst = 0x2b2a, .proto = 0x2c, }, { - .ip_src = IPv4(0x33, 0x32, 0x31, 0x30), - .ip_dst = IPv4(0x37, 0x36, 0x35, 0x34), + .ip_src = RTE_IPV4(0x33, 0x32, 0x31, 0x30), + .ip_dst = RTE_IPV4(0x37, 0x36, 0x35, 0x34), .port_src = 0x3938, .port_dst = 0x3b3a, .proto = 0x3c, }, { - .ip_src = IPv4(0x43, 0x42, 0x41, 0x40), - .ip_dst = IPv4(0x47, 0x46, 0x45, 0x44), + .ip_src = RTE_IPV4(0x43, 0x42, 0x41, 0x40), + .ip_dst = RTE_IPV4(0x47, 0x46, 0x45, 0x44), .port_src = 0x4948, .port_dst = 0x4b4a, .proto = 0x4c, @@ -235,15 +235,9 @@ static void run_hash_func_tests(void) { unsigned i, j, k; - for (i = 0; - i < sizeof(hashtest_funcs) / sizeof(rte_hash_function); - i++) { - for (j = 0; - j < sizeof(hashtest_initvals) / sizeof(uint32_t); - j++) { - for (k = 0; - k < sizeof(hashtest_key_lens) / sizeof(uint32_t); - k++) { + for (i = 0; i < RTE_DIM(hashtest_funcs); i++) { + for (j = 0; j < RTE_DIM(hashtest_initvals); j++) { + for (k = 0; k < RTE_DIM(hashtest_key_lens); k++) { run_hash_func_test(hashtest_funcs[i], hashtest_initvals[j], hashtest_key_lens[k]); @@ -481,6 +475,98 @@ static int test_add_update_delete_free(void) return 0; } +/* + * Sequence of operations for a single key with 'rw concurrency lock free' set: + * - add + * - delete: hit + * - free: hit + * Repeat the test case when 'multi writer add' is enabled. + * - add + * - delete: hit + * - free: hit + */ +static int test_add_delete_free_lf(void) +{ +/* Should match the #define LCORE_CACHE_SIZE value in rte_cuckoo_hash.h */ +#define LCORE_CACHE_SIZE 64 + struct rte_hash *handle; + hash_sig_t hash_value; + int pos, expectedPos, delPos; + uint8_t extra_flag; + uint32_t i, ip_src; + + extra_flag = ut_params.extra_flag; + ut_params.extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY_LF; + handle = rte_hash_create(&ut_params); + RETURN_IF_ERROR(handle == NULL, "hash creation failed"); + ut_params.extra_flag = extra_flag; + + /* + * The number of iterations is at least the same as the number of slots + * rte_hash allocates internally. This is to reveal potential issues of + * not freeing keys successfully. + */ + for (i = 0; i < ut_params.entries + 1; i++) { + hash_value = rte_hash_hash(handle, &keys[0]); + pos = rte_hash_add_key_with_hash(handle, &keys[0], hash_value); + print_key_info("Add", &keys[0], pos); + RETURN_IF_ERROR(pos < 0, "failed to add key (pos=%d)", pos); + expectedPos = pos; + + pos = rte_hash_del_key_with_hash(handle, &keys[0], hash_value); + print_key_info("Del", &keys[0], pos); + RETURN_IF_ERROR(pos != expectedPos, + "failed to delete key (pos=%d)", pos); + delPos = pos; + + pos = rte_hash_free_key_with_position(handle, delPos); + print_key_info("Free", &keys[0], delPos); + RETURN_IF_ERROR(pos != 0, + "failed to free key (pos=%d)", delPos); + } + + rte_hash_free(handle); + + extra_flag = ut_params.extra_flag; + ut_params.extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY_LF | + RTE_HASH_EXTRA_FLAGS_MULTI_WRITER_ADD; + handle = rte_hash_create(&ut_params); + RETURN_IF_ERROR(handle == NULL, "hash creation failed"); + ut_params.extra_flag = extra_flag; + + ip_src = keys[0].ip_src; + /* + * The number of iterations is at least the same as the number of slots + * rte_hash allocates internally. This is to reveal potential issues of + * not freeing keys successfully. + */ + for (i = 0; i < ut_params.entries + (RTE_MAX_LCORE - 1) * + (LCORE_CACHE_SIZE - 1) + 1; i++) { + keys[0].ip_src++; + hash_value = rte_hash_hash(handle, &keys[0]); + pos = rte_hash_add_key_with_hash(handle, &keys[0], hash_value); + print_key_info("Add", &keys[0], pos); + RETURN_IF_ERROR(pos < 0, "failed to add key (pos=%d)", pos); + expectedPos = pos; + + pos = rte_hash_del_key_with_hash(handle, &keys[0], hash_value); + print_key_info("Del", &keys[0], pos); + RETURN_IF_ERROR(pos != expectedPos, + "failed to delete key (pos=%d)", pos); + delPos = pos; + + pos = rte_hash_free_key_with_position(handle, delPos); + print_key_info("Free", &keys[0], delPos); + RETURN_IF_ERROR(pos != 0, + "failed to free key (pos=%d)", delPos); + } + keys[0].ip_src = ip_src; + + rte_hash_free(handle); + + return 0; +} + /* * Sequence of operations for retrieving a key with its position * @@ -1050,8 +1136,11 @@ fbk_hash_unit_test(void) handle = rte_fbk_hash_create(&invalid_params_7); RETURN_IF_ERROR_FBK(handle != NULL, "fbk hash creation should have failed"); - handle = rte_fbk_hash_create(&invalid_params_8); - RETURN_IF_ERROR_FBK(handle != NULL, "fbk hash creation should have failed"); + if (rte_eal_has_hugepages()) { + handle = rte_fbk_hash_create(&invalid_params_8); + RETURN_IF_ERROR_FBK(handle != NULL, + "fbk hash creation should have failed"); + } handle = rte_fbk_hash_create(&invalid_params_same_name_1); RETURN_IF_ERROR_FBK(handle == NULL, "fbk hash creation should have succeeded"); @@ -1743,6 +1832,8 @@ test_hash(void) return -1; if (test_add_update_delete_free() < 0) return -1; + if (test_add_delete_free_lf() < 0) + return -1; if (test_five_keys() < 0) return -1; if (test_full_bucket() < 0)