> -----Original Message----- > From: Dharmik Thakkar <dharmik.thak...@arm.com> > Sent: Tuesday, October 20, 2020 9:13 AM > To: Wang, Yipeng1 <yipeng1.w...@intel.com>; Gobriel, Sameh > <sameh.gobr...@intel.com>; Richardson, Bruce <bruce.richard...@intel.com> > Cc: dev@dpdk.org; n...@arm.com; Dharmik Thakkar > <dharmik.thak...@arm.com> > Subject: [PATCH v5 4/4] test/hash: add tests for integrated RCU QSBR > > Add functional and performance tests for the integrated RCU QSBR. > > Suggested-by: Honnappa Nagarahalli <honnappa.nagaraha...@arm.com> > Signed-off-by: Dharmik Thakkar <dharmik.thak...@arm.com> > Reviewed-by: Ruifeng Wang <ruifeng.w...@arm.com> > --- > app/test/test_hash.c | 390 ++++++++++++++++++++++++- > app/test/test_hash_readwrite_lf_perf.c | 170 ++++++++++- > 2 files changed, 556 insertions(+), 4 deletions(-) > > diff --git a/app/test/test_hash.c b/app/test/test_hash.c index > 990a1815f893..22b47b3e7728 100644 > --- a/app/test/test_hash.c > +++ b/app/test/test_hash.c > @@ -52,7 +52,7 @@ static uint32_t hashtest_key_lens[] = {0, 2, 4, 5, 6, 7, 8, > 10, > 11, 15, 16, 21, > } \ > } while(0) > > -#define RETURN_IF_ERROR_FBK(cond, str, ...) do { > \ > +#define RETURN_IF_ERROR_FBK(cond, str, ...) do { \ > if (cond) { \ > printf("ERROR line %d: " str "\n", __LINE__, ##__VA_ARGS__); > \ > if (handle) rte_fbk_hash_free(handle); \ > @@ -60,6 +60,20 @@ static uint32_t hashtest_key_lens[] = {0, 2, 4, 5, 6, 7, 8, > 10, 11, 15, 16, 21, > } \ > } while(0) > > +#define RETURN_IF_ERROR_RCU_QSBR(cond, str, ...) do { > \ > + if (cond) { \ > + printf("ERROR line %d: " str "\n", __LINE__, ##__VA_ARGS__); > \ > + if (rcu_cfg.mode == RTE_HASH_QSBR_MODE_SYNC) { > \ > + writer_done = 1; \ > + /* Wait until reader exited. */ \ > + rte_eal_mp_wait_lcore(); \ > + } \ > + if (g_handle) rte_hash_free(g_handle); \ > + if (g_qsv) rte_free(g_qsv); \ > + return -1; \ > + } \ > +} while(0) > + > /* 5-tuple key type */ > struct flow_key { > uint32_t ip_src; > @@ -1801,6 +1815,365 @@ test_hash_add_delete_jhash_3word(void) > return ret; > } > > +static struct rte_hash *g_handle; > +static struct rte_rcu_qsbr *g_qsv; > +static volatile uint8_t writer_done; > +struct flow_key g_rand_keys[9]; > +/* > + * rte_hash_rcu_qsbr_add positive and negative tests. > + * - Add RCU QSBR variable to Hash > + * - Add another RCU QSBR variable to Hash > + * - Check returns > + */ > +static int > +test_hash_rcu_qsbr_add(void) > +{ > + size_t sz; > + struct rte_rcu_qsbr *qsv2 = NULL; > + int32_t status; > + struct rte_hash_rcu_config rcu_cfg = {0}; > + > + struct rte_hash_parameters params; > + > + printf("\n# Running RCU QSBR add tests\n"); > + memcpy(¶ms, &ut_params, sizeof(params)); > + params.name = "test_hash_rcu_qsbr_add"; > + params.extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY_LF > | > + > RTE_HASH_EXTRA_FLAGS_MULTI_WRITER_ADD; > + g_handle = rte_hash_create(¶ms); > + RETURN_IF_ERROR_RCU_QSBR(g_handle == NULL, "Hash creation > failed"); > + > + /* Create RCU QSBR variable */ > + sz = rte_rcu_qsbr_get_memsize(RTE_MAX_LCORE); > + g_qsv = (struct rte_rcu_qsbr *)rte_zmalloc_socket(NULL, sz, > + RTE_CACHE_LINE_SIZE, > SOCKET_ID_ANY); > + RETURN_IF_ERROR_RCU_QSBR(g_qsv == NULL, > + "RCU QSBR variable creation failed"); > + > + status = rte_rcu_qsbr_init(g_qsv, RTE_MAX_LCORE); [Wang, Yipeng] It reminds me that could we hide this function in the rte_cuckoo_hash.c as well? I saw most of the rcu related functions are hidden in the hash implementation, it would be less confusing if we hide this one as well.
> + RETURN_IF_ERROR_RCU_QSBR(status != 0, > + "RCU QSBR variable initialization failed"); > + > + rcu_cfg.v = g_qsv; > + /* Invalid QSBR mode */ > + rcu_cfg.mode = 2; [Wang, Yipeng] Any other way rather than hardcode 2 here? Maybe just a large number like 0xff? > + status = rte_hash_rcu_qsbr_add(g_handle, &rcu_cfg); > + RETURN_IF_ERROR_RCU_QSBR(status == 0, "Invalid QSBR mode test > +failed"); > + > + rcu_cfg.mode = RTE_HASH_QSBR_MODE_DQ; [Wang, Yipeng] This reminds me that if there is an explanation on the difference of the two modes for users to easy to choose? > + /* Attach RCU QSBR to hash table */ > + status = rte_hash_rcu_qsbr_add(g_handle, &rcu_cfg); > + RETURN_IF_ERROR_RCU_QSBR(status != 0, > + "Attach RCU QSBR to hash table failed"); > + > + /* Create and attach another RCU QSBR to hash table */ > + qsv2 = (struct rte_rcu_qsbr *)rte_zmalloc_socket(NULL, sz, > + RTE_CACHE_LINE_SIZE, > SOCKET_ID_ANY); > + RETURN_IF_ERROR_RCU_QSBR(qsv2 == NULL, > + "RCU QSBR variable creation failed"); > + > + rcu_cfg.v = qsv2; > + rcu_cfg.mode = RTE_HASH_QSBR_MODE_SYNC; > + status = rte_hash_rcu_qsbr_add(g_handle, &rcu_cfg); > + rte_free(qsv2); > + RETURN_IF_ERROR_RCU_QSBR(status == 0, > + "Attach RCU QSBR to hash table succeeded where > failure" > + " is expected"); > + > + rte_hash_free(g_handle); > + rte_free(g_qsv); > + > + return 0; > +} <...>