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>
---
 app/test/test_hash_readwrite_lf.c | 694 +++++++++++++++++++++++++++++-
 1 file changed, 693 insertions(+), 1 deletion(-)

diff --git a/app/test/test_hash_readwrite_lf.c 
b/app/test/test_hash_readwrite_lf.c
index 1f2fba41f1b8..0846ed46ae52 100644
--- a/app/test/test_hash_readwrite_lf.c
+++ b/app/test/test_hash_readwrite_lf.c
@@ -13,6 +13,7 @@
 #include <rte_malloc.h>
 #include <rte_random.h>
 #include <rte_spinlock.h>
+#include <rte_rcu_qsbr.h>
 
 #include "test.h"
 
@@ -58,6 +59,7 @@ struct rwc_perf {
        uint32_t w_ks_r_miss[2][NUM_TEST];
        uint32_t multi_rw[NUM_TEST - 1][2][NUM_TEST];
        uint32_t w_ks_r_hit_extbkt[2][NUM_TEST];
+       uint32_t writer_add_del[NUM_TEST];
 };
 
 static struct rwc_perf rwc_lf_results, rwc_non_lf_results;
@@ -84,12 +86,15 @@ struct {
 
 static rte_atomic64_t gread_cycles;
 static rte_atomic64_t greads;
+static rte_atomic64_t gwrite_cycles;
+static rte_atomic64_t gwrites;
 
 static volatile uint8_t writer_done;
 
 uint16_t enabled_core_ids[RTE_MAX_LCORE];
 
 uint8_t *scanned_bkts;
+uint8_t no_free_on_del;
 
 static inline uint16_t
 get_short_sig(const hash_sig_t hash)
@@ -173,6 +178,9 @@ init_params(int rwc_lf, int use_jhash, int htm, int ext_bkt)
        if (ext_bkt)
                hash_params.extra_flag |= RTE_HASH_EXTRA_FLAGS_EXT_TABLE;
 
+       if (no_free_on_del)
+               hash_params.extra_flag |= RTE_HASH_EXTRA_FLAGS_NO_FREE_ON_DEL;
+
        hash_params.name = "tests";
 
        handle = rte_hash_create(&hash_params);
@@ -1240,6 +1248,666 @@ test_hash_add_ks_lookup_hit_extbkt(struct rwc_perf 
*rwc_perf_results,
        return -1;
 }
 
+static uint32_t *hash_data[TOTAL_ENTRY];
+static struct rte_rcu_qsbr *t;
+#define COUNTER_VALUE 4096
+#define TEST_RCU_MAX_LCORE 128
+static int
+test_rwc_rcu_reader(__attribute__((unused))void *arg)
+{
+       struct rte_rcu_qsbr *temp;
+       unsigned int i;
+       uint32_t lcore_id = rte_lcore_id();
+       uint32_t *pdata;
+       temp = t;
+
+       rte_rcu_qsbr_thread_register(temp, lcore_id);
+       do {
+               rte_rcu_qsbr_thread_online(temp, lcore_id);
+               for (i = 0; i < tbl_rwc_test_param.count_keys_no_ks; i++) {
+                       rte_rcu_qsbr_lock(temp, lcore_id);
+                       if (rte_hash_lookup_data(tbl_rwc_test_param.h,
+                                       tbl_rwc_test_param.keys_no_ks + i,
+                                       (void **)&pdata) != -ENOENT) {
+                               if (pdata != NULL) {
+                                       pdata[lcore_id] = 0;
+                                       while (pdata[lcore_id] < COUNTER_VALUE)
+                                               pdata[lcore_id]++;
+                               }
+                       }
+                       rte_rcu_qsbr_unlock(temp, lcore_id);
+               }
+               /* Update quiescent state counter */
+               rte_rcu_qsbr_quiescent(temp, lcore_id);
+               rte_rcu_qsbr_thread_offline(temp, lcore_id);
+       } while (!writer_done);
+       rte_rcu_qsbr_thread_unregister(temp, lcore_id);
+
+       return 0;
+}
+
+static int
+test_rwc_rcu_multi_writer(void *arg)
+{
+       int32_t pos;
+
+       uint32_t i, offset;
+       uint8_t pos_core = (uint32_t)((uintptr_t)arg);
+       offset = pos_core * tbl_rwc_test_param.single_insert;
+
+       for (i = offset; i < offset + tbl_rwc_test_param.single_insert; i++) {
+               /* Delete element from the shared data structure */
+               pos = rte_hash_del_key(tbl_rwc_test_param.h,
+                                       tbl_rwc_test_param.keys_no_ks + i);
+               if (no_free_on_del) {
+                       if 
(rte_hash_free_key_with_position(tbl_rwc_test_param.h,
+                                                               pos) < 0)
+                               return -1;
+               }
+               if (pos < 0) {
+                       printf("Delete key failed #%u at #%d\n",
+                               tbl_rwc_test_param.keys_no_ks[i], i);
+                       return -1;
+               }
+               rte_hash_add_key(tbl_rwc_test_param.h,
+                               tbl_rwc_test_param.keys_no_ks + i);
+       }
+       return 0;
+}
+
+uint8_t error_state;
+static void
+free_hash_data(void *pdata)
+{
+       uint32_t i;
+       uint32_t *h_data = pdata;
+       if (h_data == NULL)
+               return;
+       for (i = 0; i < rwc_core_cnt[NUM_TEST - 1]; i++) {
+               if (h_data[i] != COUNTER_VALUE && h_data[i] != 0) {
+                       printf("Reader did not complete\n");
+                       __atomic_store_n(&error_state, 1, __ATOMIC_RELAXED);
+                       return;
+               }
+       }
+       rte_free(pdata);
+       return;
+}
+
+/*
+ * Test integrated RCU with 'free' on hash_delete
+ * and with extended bkt feature disabled
+ */
+static int
+test_hash_rcu_free_on_del(__attribute__((unused))struct rwc_perf
+                               *rwc_perf_results, int rwc_lf, int htm,
+                               int ext_bkt)
+{
+       unsigned int n, m;
+       uint64_t i;
+       uint8_t write_type;
+       int use_jhash = 0;
+       no_free_on_del = 0;
+
+       if (init_params(rwc_lf, use_jhash, htm, ext_bkt) != 0)
+               goto err;
+
+       uint32_t sz;
+       sz = rte_rcu_qsbr_get_memsize(TEST_RCU_MAX_LCORE);
+       t = (struct rte_rcu_qsbr *)rte_zmalloc(NULL, sz, RTE_CACHE_LINE_SIZE);
+       if (rte_hash_rcu_qsbr_add(tbl_rwc_test_param.h, t,
+                               free_hash_data) < 0) {
+               printf("RCU init in hash failed\n");
+               return -1;
+       }
+       printf("\nTest: RCU - free on hash del - ext bkt disabled\n");
+       uint8_t pos_core;
+
+       for (m = 1; m < NUM_TEST; m++) {
+               /* Calculate keys added by each writer */
+               tbl_rwc_test_param.single_insert =
+                       tbl_rwc_test_param.count_keys_no_ks / rwc_core_cnt[m];
+               for (n = 0; n < NUM_TEST; n++) {
+                       unsigned int tot_lcore = rte_lcore_count();
+                       if (tot_lcore < (rwc_core_cnt[n] +
+                            rwc_core_cnt[m] + 1))
+                               goto finish;
+
+                       printf("\nNumber of writers: %u", rwc_core_cnt[m]);
+                       printf("\nNumber of readers: %u\n", rwc_core_cnt[n]);
+
+                       rte_hash_reset(tbl_rwc_test_param.h);
+                       writer_done = 0;
+                       write_type = WRITE_NO_KEY_SHIFT;
+                       if (write_keys(write_type) < 0)
+                               goto err;
+                       write_type = WRITE_KEY_SHIFT;
+                       if (write_keys(write_type) < 0)
+                               goto err;
+                       for (i = 0; i < tbl_rwc_test_param.count_keys_no_ks;
+                               i++) {
+                               hash_data[i] =
+                                       rte_zmalloc(NULL, sizeof(uint32_t)
+                                               * rwc_core_cnt[NUM_TEST - 1],
+                                               0);
+                               if (hash_data[i] == NULL) {
+                                       printf("No memory\n");
+                                       return -1;
+                               }
+                       }
+                       for (i = 0;
+                               i < tbl_rwc_test_param.count_keys_no_ks;
+                               i++) {
+                               if (rte_hash_add_key_data(tbl_rwc_test_param.h,
+                                       tbl_rwc_test_param.keys_no_ks + i,
+                                       (void *)((uintptr_t)hash_data[i]))
+                                       < 0) {
+                                       printf("Hash key add Failed #%d\n",
+                                               
tbl_rwc_test_param.keys_no_ks[i]);
+                                       return -1;
+                               }
+                       }
+
+                       rte_rcu_qsbr_init(t, TEST_RCU_MAX_LCORE);
+                       /* Launch reader(s) */
+                       for (i = 1; i <= rwc_core_cnt[n]; i++)
+                               rte_eal_remote_launch(test_rwc_rcu_reader,
+                                       (void *)(uintptr_t)rwc_core_cnt[m],
+                                       enabled_core_ids[i]);
+                       pos_core = 0;
+                       /* Launch writers */
+                       for (; i <= rwc_core_cnt[m]
+                            + rwc_core_cnt[n]; i++) {
+                               rte_eal_remote_launch
+                                       (test_rwc_rcu_multi_writer,
+                                       (void *)(uintptr_t)pos_core,
+                                       enabled_core_ids[i]);
+                               pos_core++;
+                       }
+
+                       /* Wait for writers to complete */
+                       for (i = rwc_core_cnt[n] + 1;
+                            i <= rwc_core_cnt[m] + rwc_core_cnt[n];
+                            i++)
+                               rte_eal_wait_lcore(enabled_core_ids[i]);
+
+                       writer_done = 1;
+
+                       for (i = 1; i <= rwc_core_cnt[n]; i++)
+                               if (rte_eal_wait_lcore(enabled_core_ids[i]) < 0)
+                                       goto err;
+
+               }
+       }
+
+finish:
+       rte_hash_free(tbl_rwc_test_param.h);
+       rte_free(t);
+       return 0;
+
+err:
+       rte_hash_free(tbl_rwc_test_param.h);
+       rte_free(t);
+       return -1;
+}
+
+/*
+ * Test integrated RCU with NO 'free' on hash_delete
+ * and with extended bkt feature disabled
+ */
+static int
+test_hash_rcu_no_free_on_del(__attribute__((unused))struct rwc_perf
+                               *rwc_perf_results, int rwc_lf, int htm,
+                               int ext_bkt)
+{
+       unsigned int n, m;
+       uint64_t i;
+       uint8_t write_type;
+       int use_jhash = 0;
+       no_free_on_del = 1;
+
+       if (init_params(rwc_lf, use_jhash, htm, ext_bkt) != 0)
+               goto err;
+
+       uint32_t sz;
+       sz = rte_rcu_qsbr_get_memsize(TEST_RCU_MAX_LCORE);
+       t = (struct rte_rcu_qsbr *)rte_zmalloc(NULL, sz, RTE_CACHE_LINE_SIZE);
+       if (rte_hash_rcu_qsbr_add(tbl_rwc_test_param.h, t,
+                               free_hash_data) < 0) {
+               printf("RCU init in hash failed\n");
+               return -1;
+       }
+
+       printf("\nTest: RCU - no free on hash del - ext bkt disabled\n");
+       uint8_t pos_core;
+
+       for (m = 1; m < NUM_TEST; m++) {
+               /* Calculate keys added by each writer */
+               tbl_rwc_test_param.single_insert =
+                       tbl_rwc_test_param.count_keys_no_ks / rwc_core_cnt[m];
+               for (n = 0; n < NUM_TEST; n++) {
+                       unsigned int tot_lcore = rte_lcore_count();
+                       if (tot_lcore < (rwc_core_cnt[n] +
+                            rwc_core_cnt[m] + 1))
+                               goto finish;
+
+                       printf("\nNumber of writers: %u", rwc_core_cnt[m]);
+                       printf("\nNumber of readers: %u\n", rwc_core_cnt[n]);
+
+                       rte_hash_reset(tbl_rwc_test_param.h);
+                       writer_done = 0;
+                       write_type = WRITE_NO_KEY_SHIFT;
+                       if (write_keys(write_type) < 0)
+                               goto err;
+                       write_type = WRITE_KEY_SHIFT;
+                       if (write_keys(write_type) < 0)
+                               goto err;
+                       for (i = 0; i < tbl_rwc_test_param.count_keys_no_ks;
+                               i++) {
+                               hash_data[i] =
+                                       rte_zmalloc(NULL, sizeof(uint32_t)
+                                               * rwc_core_cnt[NUM_TEST - 1],
+                                               0);
+                               if (hash_data[i] == NULL) {
+                                       printf("No memory\n");
+                                       return -1;
+                               }
+                       }
+                       for (i = 0;
+                               i < tbl_rwc_test_param.count_keys_no_ks;
+                               i++) {
+                               if (rte_hash_add_key_data(tbl_rwc_test_param.h,
+                                       tbl_rwc_test_param.keys_no_ks + i,
+                                       (void *)((uintptr_t)hash_data[i]))
+                                       < 0) {
+                                       printf("Hash key add Failed #%d\n",
+                                               
tbl_rwc_test_param.keys_no_ks[i]);
+                                       return -1;
+                               }
+                       }
+
+                       rte_rcu_qsbr_init(t, TEST_RCU_MAX_LCORE);
+                       /* Launch reader(s) */
+                       for (i = 1; i <= rwc_core_cnt[n]; i++)
+                               rte_eal_remote_launch(test_rwc_rcu_reader,
+                                       (void *)(uintptr_t)rwc_core_cnt[m],
+                                       enabled_core_ids[i]);
+                       pos_core = 0;
+                       /* Launch writers */
+                       for (; i <= rwc_core_cnt[m]
+                            + rwc_core_cnt[n]; i++) {
+                               rte_eal_remote_launch
+                                       (test_rwc_rcu_multi_writer,
+                                       (void *)(uintptr_t)pos_core,
+                                       enabled_core_ids[i]);
+                               pos_core++;
+                       }
+                       /* Wait for writers to complete */
+                       for (i = rwc_core_cnt[n] + 1;
+                            i <= rwc_core_cnt[m] + rwc_core_cnt[n];
+                            i++)
+                               rte_eal_wait_lcore(enabled_core_ids[i]);
+
+                       writer_done = 1;
+
+                       for (i = 1; i <= rwc_core_cnt[n]; i++)
+                               if (rte_eal_wait_lcore(enabled_core_ids[i]) < 0)
+                                       goto err;
+               }
+       }
+
+finish:
+       rte_hash_free(tbl_rwc_test_param.h);
+       rte_free(t);
+       return 0;
+
+err:
+       rte_hash_free(tbl_rwc_test_param.h);
+       rte_free(t);
+       return -1;
+}
+
+/*
+ * Test integrated RCU with 'free' on hash_delete
+ * and with extended bkt feature enabled
+ */
+static int
+test_hash_rcu_ext_bkt_free_on_del(__attribute__((unused))struct rwc_perf
+                                       *rwc_perf_results, int rwc_lf, int htm,
+                                       int ext_bkt)
+{
+       unsigned int n, m;
+       uint64_t i;
+       uint8_t write_type;
+       int use_jhash = 0;
+       no_free_on_del = 0;
+
+       if (init_params(rwc_lf, use_jhash, htm, ext_bkt) != 0)
+               goto err;
+
+       uint32_t sz;
+       sz = rte_rcu_qsbr_get_memsize(TEST_RCU_MAX_LCORE);
+       t = (struct rte_rcu_qsbr *)rte_zmalloc(NULL, sz, RTE_CACHE_LINE_SIZE);
+       if (rte_hash_rcu_qsbr_add(tbl_rwc_test_param.h, t,
+                               free_hash_data) < 0) {
+               printf("RCU init in hash failed\n");
+               return -1;
+       }
+
+       printf("\nTest: RCU - free on hash del - ext bkt enabled\n");
+       uint8_t pos_core;
+
+       for (m = 1; m < NUM_TEST; m++) {
+               /* Calculate keys added by each writer */
+               tbl_rwc_test_param.single_insert =
+                       tbl_rwc_test_param.count_keys_no_ks / rwc_core_cnt[m];
+               for (n = 0; n < NUM_TEST; n++) {
+                       unsigned int tot_lcore = rte_lcore_count();
+                       if (tot_lcore < (rwc_core_cnt[n] +
+                            rwc_core_cnt[m] + 1))
+                               goto finish;
+
+                       printf("\nNumber of writers: %u", rwc_core_cnt[m]);
+                       printf("\nNumber of readers: %u\n", rwc_core_cnt[n]);
+
+                       rte_hash_reset(tbl_rwc_test_param.h);
+                       writer_done = 0;
+                       write_type = WRITE_NO_KEY_SHIFT;
+                       if (write_keys(write_type) < 0)
+                               goto err;
+                       write_type = WRITE_KEY_SHIFT;
+                       if (write_keys(write_type) < 0)
+                               goto err;
+                       for (i = 0; i < tbl_rwc_test_param.count_keys_no_ks;
+                               i++) {
+                               hash_data[i] =
+                                       rte_zmalloc(NULL, sizeof(uint32_t)
+                                               * rwc_core_cnt[NUM_TEST - 1],
+                                               0);
+                               if (hash_data[i] == NULL) {
+                                       printf("No memory\n");
+                                       return -1;
+                               }
+                       }
+                       for (i = 0;
+                               i < tbl_rwc_test_param.count_keys_no_ks;
+                               i++) {
+                               if (rte_hash_add_key_data(tbl_rwc_test_param.h,
+                                       tbl_rwc_test_param.keys_no_ks + i,
+                                       (void *)((uintptr_t)hash_data[i]))
+                                       < 0) {
+                                       printf("Hash key add Failed #%d\n",
+                                               
tbl_rwc_test_param.keys_no_ks[i]);
+                                       return -1;
+                               }
+                       }
+
+                       rte_rcu_qsbr_init(t, TEST_RCU_MAX_LCORE);
+                       /* Launch reader(s) */
+                       for (i = 1; i <= rwc_core_cnt[n]; i++)
+                               rte_eal_remote_launch(test_rwc_rcu_reader,
+                                       (void *)(uintptr_t)rwc_core_cnt[m],
+                                       enabled_core_ids[i]);
+                       pos_core = 0;
+                       /* Launch writers */
+                       for (; i <= rwc_core_cnt[m]
+                            + rwc_core_cnt[n]; i++) {
+                               rte_eal_remote_launch
+                                       (test_rwc_rcu_multi_writer,
+                                       (void *)(uintptr_t)pos_core,
+                                       enabled_core_ids[i]);
+                               pos_core++;
+                       }
+                       /* Wait for writers to complete */
+                       for (i = rwc_core_cnt[n] + 1;
+                            i <= rwc_core_cnt[m] + rwc_core_cnt[n];
+                            i++)
+                               rte_eal_wait_lcore(enabled_core_ids[i]);
+
+                       writer_done = 1;
+
+                       for (i = 1; i <= rwc_core_cnt[n]; i++)
+                               if (rte_eal_wait_lcore(enabled_core_ids[i]) < 0)
+                                       goto err;
+               }
+       }
+
+finish:
+       rte_hash_free(tbl_rwc_test_param.h);
+       rte_free(t);
+       return 0;
+
+err:
+       rte_hash_free(tbl_rwc_test_param.h);
+       rte_free(t);
+       return -1;
+}
+
+/*
+ * Test integrated RCU with NO 'free' on hash_delete
+ * and with extended bkt feature enabled
+ */
+static int
+test_hash_rcu_ext_bkt_no_free_on_del(__attribute__((unused))struct rwc_perf
+                                       *rwc_perf_results, int rwc_lf, int htm,
+                                       int ext_bkt)
+{
+       unsigned int n, m;
+       uint64_t i;
+       uint8_t write_type;
+       int use_jhash = 0;
+       no_free_on_del = 1;
+
+       if (init_params(rwc_lf, use_jhash, htm, ext_bkt) != 0)
+               goto err;
+
+       uint32_t sz;
+       sz = rte_rcu_qsbr_get_memsize(TEST_RCU_MAX_LCORE);
+       t = (struct rte_rcu_qsbr *)rte_zmalloc(NULL, sz, RTE_CACHE_LINE_SIZE);
+       if (rte_hash_rcu_qsbr_add(tbl_rwc_test_param.h, t,
+                               free_hash_data) < 0) {
+               printf("RCU init in hash failed\n");
+               return -1;
+       }
+
+       printf("\nTest: RCU - no free on hash del - ext bkt enabled\n");
+       uint8_t pos_core;
+
+       for (m = 1; m < NUM_TEST; m++) {
+               /* Calculate keys added by each writer */
+               tbl_rwc_test_param.single_insert =
+                       tbl_rwc_test_param.count_keys_no_ks / rwc_core_cnt[m];
+               for (n = 0; n < NUM_TEST; n++) {
+                       unsigned int tot_lcore = rte_lcore_count();
+                       if (tot_lcore < (rwc_core_cnt[n] +
+                            rwc_core_cnt[m] + 1))
+                               goto finish;
+
+                       printf("\nNumber of writers: %u", rwc_core_cnt[m]);
+                       printf("\nNumber of readers: %u\n", rwc_core_cnt[n]);
+
+                       rte_hash_reset(tbl_rwc_test_param.h);
+                       writer_done = 0;
+                       write_type = WRITE_NO_KEY_SHIFT;
+                       if (write_keys(write_type) < 0)
+                               goto err;
+                       write_type = WRITE_KEY_SHIFT;
+                       if (write_keys(write_type) < 0)
+                               goto err;
+                       for (i = 0; i < tbl_rwc_test_param.count_keys_no_ks;
+                               i++) {
+                               hash_data[i] =
+                                       rte_zmalloc(NULL, sizeof(uint32_t)
+                                               * rwc_core_cnt[NUM_TEST - 1],
+                                               0);
+                               if (hash_data[i] == NULL) {
+                                       printf("No memory\n");
+                                       return -1;
+                               }
+                       }
+                       for (i = 0;
+                               i < tbl_rwc_test_param.count_keys_no_ks;
+                               i++) {
+                               if (rte_hash_add_key_data(tbl_rwc_test_param.h,
+                                       tbl_rwc_test_param.keys_no_ks + i,
+                                       (void *)((uintptr_t)hash_data[i]))
+                                       < 0) {
+                                       printf("Hash key add Failed #%d\n",
+                                               
tbl_rwc_test_param.keys_no_ks[i]);
+                                       return -1;
+                               }
+                       }
+
+                       rte_rcu_qsbr_init(t, TEST_RCU_MAX_LCORE);
+                       /* Launch reader(s) */
+                       for (i = 1; i <= rwc_core_cnt[n]; i++)
+                               rte_eal_remote_launch(test_rwc_rcu_reader,
+                                       (void *)(uintptr_t)rwc_core_cnt[m],
+                                       enabled_core_ids[i]);
+                       pos_core = 0;
+                       /* Launch writers */
+                       for (; i <= rwc_core_cnt[m]
+                            + rwc_core_cnt[n]; i++) {
+                               rte_eal_remote_launch
+                                       (test_rwc_rcu_multi_writer,
+                                       (void *)(uintptr_t)pos_core,
+                                       enabled_core_ids[i]);
+                               pos_core++;
+                       }
+                       /* Wait for writers to complete */
+                       for (i = rwc_core_cnt[n] + 1;
+                            i <= rwc_core_cnt[m] + rwc_core_cnt[n];
+                            i++)
+                               rte_eal_wait_lcore(enabled_core_ids[i]);
+
+                       writer_done = 1;
+
+                       for (i = 1; i <= rwc_core_cnt[n]; i++)
+                               if (rte_eal_wait_lcore(enabled_core_ids[i]) < 0)
+                                       goto err;
+               }
+       }
+
+finish:
+       rte_hash_free(tbl_rwc_test_param.h);
+       rte_free(t);
+       return 0;
+
+err:
+       rte_hash_free(tbl_rwc_test_param.h);
+       rte_free(t);
+       return -1;
+}
+
+static int
+test_multiwriter_perf(void *arg)
+{
+       uint32_t i, offset;
+       uint64_t begin, cycles;
+       uint8_t pos_core = (uint32_t)((uintptr_t)arg);
+       offset = pos_core * tbl_rwc_test_param.single_insert;
+
+       begin = rte_rdtsc_precise();
+       for (i = offset; i < offset + tbl_rwc_test_param.single_insert; i++) {
+               /* Delete element from the shared data structure */
+               rte_hash_del_key(tbl_rwc_test_param.h,
+                                       tbl_rwc_test_param.keys_no_ks + i);
+               rte_hash_add_key(tbl_rwc_test_param.h,
+                               tbl_rwc_test_param.keys_no_ks + i);
+       }
+       cycles = rte_rdtsc_precise() - begin;
+       rte_atomic64_add(&gwrite_cycles, cycles);
+       rte_atomic64_add(&gwrites, tbl_rwc_test_param.single_insert);
+       return 0;
+}
+
+/*
+ * Test RCU perf:
+ * Writer(s) delete and add keys in the table.
+ */
+static int
+test_hash_writer_perf(struct rwc_perf *rwc_perf_results, int rwc_lf,
+                               int htm, int ext_bkt)
+{
+       unsigned int n;
+       uint64_t i;
+       int use_jhash = 0;
+       uint8_t write_type;
+
+       no_free_on_del = 0;
+
+       rte_atomic64_init(&gwrites);
+       rte_atomic64_init(&gwrite_cycles);
+
+       if (init_params(rwc_lf, use_jhash, htm, ext_bkt) != 0)
+               goto err;
+
+       if (rwc_lf) {
+               uint32_t sz;
+               sz = rte_rcu_qsbr_get_memsize(TEST_RCU_MAX_LCORE);
+               t = (struct rte_rcu_qsbr *)rte_zmalloc(NULL, sz, 
RTE_CACHE_LINE_SIZE);
+               if (rte_hash_rcu_qsbr_add(tbl_rwc_test_param.h, t,
+                                       free_hash_data) < 0) {
+                       printf("RCU init in hash failed\n");
+                       return -1;
+               }
+               printf("\nTest: Writer perf with integrated RCU\n");
+       } else
+               printf("\nTest: Writer perf without integrated RCU\n");
+
+       for (n = 0; n < NUM_TEST; n++) {
+               unsigned int tot_lcore = rte_lcore_count();
+               if (tot_lcore < rwc_core_cnt[n] + 1)
+                       goto finish;
+
+               /* Calculate keys added by each writer */
+               tbl_rwc_test_param.single_insert =
+                       tbl_rwc_test_param.count_keys_no_ks /
+                               rwc_core_cnt[n];
+               printf("\nNumber of writers: %u\n", rwc_core_cnt[n]);
+
+               rte_atomic64_clear(&gwrites);
+               rte_atomic64_clear(&gwrite_cycles);
+
+               rte_hash_reset(tbl_rwc_test_param.h);
+               if (rwc_lf)
+                       rte_rcu_qsbr_init(t, TEST_RCU_MAX_LCORE);
+               write_type = WRITE_NO_KEY_SHIFT;
+               if (write_keys(write_type) < 0)
+                       goto err;
+               write_type = WRITE_KEY_SHIFT;
+               if (write_keys(write_type) < 0)
+                       goto err;
+               for (i = 1; i <= rwc_core_cnt[n]; i++)
+                       rte_eal_remote_launch(test_multiwriter_perf,
+                                       (void *)(uintptr_t)(i - 1),
+                                               enabled_core_ids[i]);
+
+               rte_eal_mp_wait_lcore();
+
+               unsigned long long cycles_per_write_operation =
+                       rte_atomic64_read(&gwrite_cycles) /
+                       rte_atomic64_read(&gwrites);
+               rwc_perf_results->writer_add_del[n]
+                                       = cycles_per_write_operation;
+               printf("Cycles per write operation: %llu\n",
+                               cycles_per_write_operation);
+       }
+
+finish:
+       rte_hash_free(tbl_rwc_test_param.h);
+       if (rwc_lf)
+               rte_free(t);
+       return 0;
+
+err:
+       rte_eal_mp_wait_lcore();
+       rte_hash_free(tbl_rwc_test_param.h);
+       if (rwc_lf)
+               rte_free(t);
+       return -1;
+}
+
 static int
 test_hash_readwrite_lf_main(void)
 {
@@ -1272,7 +1940,6 @@ test_hash_readwrite_lf_main(void)
                return -1;
        if (get_enabled_cores_list() != 0)
                return -1;
-
        if (RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY_LF) {
                rwc_lf = 1;
                ext_bkt = 1;
@@ -1299,6 +1966,23 @@ test_hash_readwrite_lf_main(void)
                if (test_hash_add_ks_lookup_hit_extbkt(&rwc_lf_results, rwc_lf,
                                                        htm, ext_bkt) < 0)
                        return -1;
+               ext_bkt = 0;
+               if (test_hash_rcu_free_on_del(&rwc_lf_results, rwc_lf, htm,
+                                               ext_bkt) < 0)
+                       return -1;
+               if (test_hash_rcu_no_free_on_del(&rwc_lf_results, rwc_lf, htm,
+                                               ext_bkt) < 0)
+                       return -1;
+               ext_bkt = 1;
+               if (test_hash_rcu_ext_bkt_free_on_del(&rwc_lf_results, rwc_lf,
+                                                       htm, ext_bkt) < 0)
+                       return -1;
+               if (test_hash_rcu_ext_bkt_no_free_on_del(&rwc_lf_results, rwc_lf
+                                                       , htm, ext_bkt) < 0)
+                       return -1;
+               if (test_hash_writer_perf(&rwc_lf_results, rwc_lf
+                                                       , htm, ext_bkt) < 0)
+                       return -1;
        }
        printf("\nTest lookup with read-write concurrency lock free support"
               " disabled\n");
@@ -1330,9 +2014,17 @@ test_hash_readwrite_lf_main(void)
        if (test_hash_multi_add_lookup(&rwc_non_lf_results, rwc_lf, htm,
                                                        ext_bkt) < 0)
                return -1;
+       no_free_on_del = 0;
        if (test_hash_add_ks_lookup_hit_extbkt(&rwc_non_lf_results, rwc_lf,
                                                htm, ext_bkt) < 0)
                return -1;
+       if (test_hash_writer_perf(&rwc_non_lf_results, rwc_lf,
+                                               htm, ext_bkt) < 0)
+               return -1;
+
+       if (error_state != 0)
+               return -1;
+
 results:
        printf("\n\t\t\t\t\t\t********** Results summary **********\n\n");
        int i, j, k;
-- 
2.17.1

Reply via email to