get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/52131/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 52131,
    "url": "http://patches.dpdk.org/api/patches/52131/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20190402194455.9269-3-dharmik.thakkar@arm.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20190402194455.9269-3-dharmik.thakkar@arm.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20190402194455.9269-3-dharmik.thakkar@arm.com",
    "date": "2019-04-02T19:44:55",
    "name": "[v5,2/2] test/hash: lock-free rw concurrency test ext bkt",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "10ff2c00f8681d0e438693bbde64a715049c7b51",
    "submitter": {
        "id": 1108,
        "url": "http://patches.dpdk.org/api/people/1108/?format=api",
        "name": "Dharmik Thakkar",
        "email": "dharmik.thakkar@arm.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20190402194455.9269-3-dharmik.thakkar@arm.com/mbox/",
    "series": [
        {
            "id": 4070,
            "url": "http://patches.dpdk.org/api/series/4070/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=4070",
            "date": "2019-04-02T19:44:53",
            "name": "hash: add lock free support for ext bkt",
            "version": 5,
            "mbox": "http://patches.dpdk.org/series/4070/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/52131/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/52131/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id B89081B138;\n\tTue,  2 Apr 2019 21:45:19 +0200 (CEST)",
            "from foss.arm.com (foss.arm.com [217.140.101.70])\n\tby dpdk.org (Postfix) with ESMTP id C8D6B1B127\n\tfor <dev@dpdk.org>; Tue,  2 Apr 2019 21:45:13 +0200 (CEST)",
            "from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249])\n\tby usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 35A721688;\n\tTue,  2 Apr 2019 12:45:13 -0700 (PDT)",
            "from dp6132.austin.arm.com (dp6132.austin.arm.com [10.118.12.38])\n\tby usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id\n\tC3BD93F68F; Tue,  2 Apr 2019 12:45:12 -0700 (PDT)"
        ],
        "From": "Dharmik Thakkar <dharmik.thakkar@arm.com>",
        "To": "Yipeng Wang <yipeng1.wang@intel.com>,\n\tSameh Gobriel <sameh.gobriel@intel.com>,\n\tBruce Richardson <bruce.richardson@intel.com>,\n\tPablo de Lara <pablo.de.lara.guarch@intel.com>",
        "Cc": "dev@dpdk.org, honnappa.nagarahalli@arm.com,\n\tDharmik Thakkar <dharmik.thakkar@arm.com>",
        "Date": "Tue,  2 Apr 2019 19:44:55 +0000",
        "Message-Id": "<20190402194455.9269-3-dharmik.thakkar@arm.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20190402194455.9269-1-dharmik.thakkar@arm.com>",
        "References": "<20190401230830.17931-1-dharmik.thakkar@arm.com>\n\t<20190402194455.9269-1-dharmik.thakkar@arm.com>",
        "Subject": "[dpdk-dev] [PATCH v5 2/2] test/hash: lock-free rw concurrency test\n\text bkt",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Add unit test to check for hash lookup and bulk-lookup perf for\nextendable bucket feature.\nIt is tested with both lock-free enabled and lock-free disabled case.\n\nTest includes:\n\n- hash lookup on keys in ext bkt\n- hash delete causing key-shifts of keys from ext bkt to secondary bkt\n\nSuggested-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>\nSigned-off-by: Dharmik Thakkar <dharmik.thakkar@arm.com>\nAcked-by: Yipeng Wang <yipeng1.wang@intel.com>\n---\n app/test/test_hash_readwrite_lf.c | 352 ++++++++++++++++++++++++------\n 1 file changed, 285 insertions(+), 67 deletions(-)",
    "diff": "diff --git a/app/test/test_hash_readwrite_lf.c b/app/test/test_hash_readwrite_lf.c\nindex cbfd9322696b..4ab4c8ee64cf 100644\n--- a/app/test/test_hash_readwrite_lf.c\n+++ b/app/test/test_hash_readwrite_lf.c\n@@ -41,6 +41,12 @@\n #define READ_PASS_SHIFT_PATH 4\n #define READ_PASS_NON_SHIFT_PATH 8\n #define BULK_LOOKUP 16\n+#define READ_PASS_KEY_SHIFTS_EXTBKT 32\n+\n+#define WRITE_NO_KEY_SHIFT 0\n+#define WRITE_KEY_SHIFT 1\n+#define WRITE_EXT_BKT 2\n+\n #define NUM_TEST 3\n unsigned int rwc_core_cnt[NUM_TEST] = {1, 2, 4};\n \n@@ -51,6 +57,7 @@ struct rwc_perf {\n \tuint32_t w_ks_r_hit_sp[2][NUM_TEST];\n \tuint32_t w_ks_r_miss[2][NUM_TEST];\n \tuint32_t multi_rw[NUM_TEST - 1][2][NUM_TEST];\n+\tuint32_t w_ks_r_hit_extbkt[2][NUM_TEST];\n };\n \n static struct rwc_perf rwc_lf_results, rwc_non_lf_results;\n@@ -62,11 +69,15 @@ struct {\n \tuint32_t *keys_absent;\n \tuint32_t *keys_shift_path;\n \tuint32_t *keys_non_shift_path;\n+\tuint32_t *keys_ext_bkt;\n+\tuint32_t *keys_ks_extbkt;\n \tuint32_t count_keys_no_ks;\n \tuint32_t count_keys_ks;\n \tuint32_t count_keys_absent;\n \tuint32_t count_keys_shift_path;\n \tuint32_t count_keys_non_shift_path;\n+\tuint32_t count_keys_extbkt;\n+\tuint32_t count_keys_ks_extbkt;\n \tuint32_t single_insert;\n \tstruct rte_hash *h;\n } tbl_rwc_test_param;\n@@ -81,6 +92,35 @@ uint16_t enabled_core_ids[RTE_MAX_LCORE];\n \n uint8_t *scanned_bkts;\n \n+static inline uint16_t\n+get_short_sig(const hash_sig_t hash)\n+{\n+\treturn hash >> 16;\n+}\n+\n+static inline uint32_t\n+get_prim_bucket_index(__attribute__((unused)) const struct rte_hash *h,\n+\t\t      const hash_sig_t hash)\n+{\n+\tuint32_t num_buckets;\n+\tuint32_t bucket_bitmask;\n+\tnum_buckets  = rte_align32pow2(TOTAL_ENTRY) / 8;\n+\tbucket_bitmask = num_buckets - 1;\n+\treturn hash & bucket_bitmask;\n+}\n+\n+static inline uint32_t\n+get_alt_bucket_index(__attribute__((unused)) const struct rte_hash *h,\n+\t\t\tuint32_t cur_bkt_idx, uint16_t sig)\n+{\n+\tuint32_t num_buckets;\n+\tuint32_t bucket_bitmask;\n+\tnum_buckets  = rte_align32pow2(TOTAL_ENTRY) / 8;\n+\tbucket_bitmask = num_buckets - 1;\n+\treturn (cur_bkt_idx ^ sig) & bucket_bitmask;\n+}\n+\n+\n static inline int\n get_enabled_cores_list(void)\n {\n@@ -168,9 +208,12 @@ generate_keys(void)\n \tuint32_t *keys_ks = NULL;\n \tuint32_t *keys_absent = NULL;\n \tuint32_t *keys_non_shift_path = NULL;\n+\tuint32_t *keys_ext_bkt = NULL;\n+\tuint32_t *keys_ks_extbkt = NULL;\n \tuint32_t *found = NULL;\n \tuint32_t count_keys_no_ks = 0;\n \tuint32_t count_keys_ks = 0;\n+\tuint32_t count_keys_extbkt = 0;\n \tuint32_t i;\n \n \t/*\n@@ -251,14 +294,32 @@ generate_keys(void)\n \t\tgoto err;\n \t}\n \n+\t/*\n+\t * This consist of keys which will be stored in extended buckets\n+\t */\n+\tkeys_ext_bkt = rte_malloc(NULL, sizeof(uint32_t) * TOTAL_INSERT, 0);\n+\tif (keys_ext_bkt == NULL) {\n+\t\tprintf(\"RTE_MALLOC failed\\n\");\n+\t\tgoto err;\n+\t}\n+\n+\t/*\n+\t * This consist of keys which when deleted causes shifting of keys\n+\t * in extended buckets to respective secondary buckets\n+\t */\n+\tkeys_ks_extbkt = rte_malloc(NULL, sizeof(uint32_t) * TOTAL_INSERT, 0);\n+\tif (keys_ks_extbkt == NULL) {\n+\t\tprintf(\"RTE_MALLOC failed\\n\");\n+\t\tgoto err;\n+\t}\n \n \thash_sig_t sig;\n \tuint32_t prim_bucket_idx;\n-\tint ret;\n+\tuint32_t sec_bucket_idx;\n+\tuint16_t short_sig;\n \tuint32_t num_buckets;\n-\tuint32_t bucket_bitmask;\n \tnum_buckets  = rte_align32pow2(TOTAL_ENTRY) / 8;\n-\tbucket_bitmask = num_buckets - 1;\n+\tint ret;\n \n \t/*\n \t * Used to mark bkts in which at least one key was shifted to its\n@@ -275,6 +336,8 @@ generate_keys(void)\n \ttbl_rwc_test_param.keys_ks = keys_ks;\n \ttbl_rwc_test_param.keys_absent = keys_absent;\n \ttbl_rwc_test_param.keys_non_shift_path = keys_non_shift_path;\n+\ttbl_rwc_test_param.keys_ext_bkt = keys_ext_bkt;\n+\ttbl_rwc_test_param.keys_ks_extbkt = keys_ks_extbkt;\n \t/* Generate keys by adding previous two keys, neglect overflow */\n \tprintf(\"Generating keys...\\n\");\n \tkeys[0] = 0;\n@@ -287,7 +350,8 @@ generate_keys(void)\n \t\t/* Check if primary bucket has space.*/\n \t\tsig = rte_hash_hash(tbl_rwc_test_param.h,\n \t\t\t\t\ttbl_rwc_test_param.keys+i);\n-\t\tprim_bucket_idx = sig & bucket_bitmask;\n+\t\tprim_bucket_idx = get_prim_bucket_index(tbl_rwc_test_param.h,\n+\t\t\t\t\t\t\tsig);\n \t\tret = check_bucket(prim_bucket_idx, keys[i]);\n \t\tif (ret < 0) {\n \t\t\t/*\n@@ -368,6 +432,47 @@ generate_keys(void)\n \ttbl_rwc_test_param.count_keys_absent = count_keys_absent;\n \ttbl_rwc_test_param.count_keys_non_shift_path = count;\n \n+\tmemset(scanned_bkts, 0, num_buckets);\n+\tcount = 0;\n+\t/* Find keys that will be in extended buckets */\n+\tfor (i = 0; i < count_keys_ks; i++) {\n+\t\tret = rte_hash_add_key(tbl_rwc_test_param.h, keys_ks + i);\n+\t\tif (ret < 0) {\n+\t\t\t/* Key will be added to ext bkt */\n+\t\t\tkeys_ext_bkt[count_keys_extbkt++] = keys_ks[i];\n+\t\t\t/* Sec bkt to be added to keys_ks_extbkt */\n+\t\t\tsig = rte_hash_hash(tbl_rwc_test_param.h,\n+\t\t\t\t\ttbl_rwc_test_param.keys_ks + i);\n+\t\t\tprim_bucket_idx = get_prim_bucket_index(\n+\t\t\t\t\t\ttbl_rwc_test_param.h, sig);\n+\t\t\tshort_sig = get_short_sig(sig);\n+\t\t\tsec_bucket_idx = get_alt_bucket_index(\n+\t\t\t\t\t\ttbl_rwc_test_param.h,\n+\t\t\t\t\t\tprim_bucket_idx, short_sig);\n+\t\t\tif (scanned_bkts[sec_bucket_idx] == 0)\n+\t\t\t\tscanned_bkts[sec_bucket_idx] = 1;\n+\t\t}\n+\t}\n+\n+\t/* Find keys that will shift keys in ext bucket*/\n+\tfor (i = 0; i < num_buckets; i++) {\n+\t\tif (scanned_bkts[i] == 1) {\n+\t\t\titer = i * 8;\n+\t\t\twhile (rte_hash_iterate(tbl_rwc_test_param.h,\n+\t\t\t\t&next_key, &next_data, &iter) >= 0) {\n+\t\t\t\t/* Check if key belongs to the current bucket */\n+\t\t\t\tif (i >= (iter-1)/8)\n+\t\t\t\t\tkeys_ks_extbkt[count++]\n+\t\t\t\t\t\t= *(const uint32_t *)next_key;\n+\t\t\t\telse\n+\t\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\ttbl_rwc_test_param.count_keys_ks_extbkt = count;\n+\ttbl_rwc_test_param.count_keys_extbkt = count_keys_extbkt;\n+\n \tprintf(\"\\nCount of keys NOT causing shifting of existing keys to \"\n \t\"alternate location: %d\\n\", tbl_rwc_test_param.count_keys_no_ks);\n \tprintf(\"\\nCount of keys causing shifting of existing keys to alternate \"\n@@ -378,6 +483,10 @@ generate_keys(void)\n \t       tbl_rwc_test_param.count_keys_shift_path);\n \tprintf(\"Count of keys not likely to be on the shift path: %d\\n\\n\",\n \t       tbl_rwc_test_param.count_keys_non_shift_path);\n+\tprintf(\"Count of keys in extended buckets: %d\\n\\n\",\n+\t       tbl_rwc_test_param.count_keys_extbkt);\n+\tprintf(\"Count of keys shifting keys in ext buckets: %d\\n\\n\",\n+\t       tbl_rwc_test_param.count_keys_ks_extbkt);\n \n \trte_free(found);\n \trte_hash_free(tbl_rwc_test_param.h);\n@@ -390,12 +499,14 @@ generate_keys(void)\n \trte_free(keys_absent);\n \trte_free(found);\n \trte_free(tbl_rwc_test_param.keys_shift_path);\n+\trte_free(keys_ext_bkt);\n+\trte_free(keys_ks_extbkt);\n \trte_free(scanned_bkts);\n \treturn -1;\n }\n \n static int\n-init_params(int rwc_lf, int use_jhash, int htm)\n+init_params(int rwc_lf, int use_jhash, int htm, int ext_bkt)\n {\n \tstruct rte_hash *handle;\n \n@@ -425,6 +536,9 @@ init_params(int rwc_lf, int use_jhash, int htm)\n \t\t\tRTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY |\n \t\t\tRTE_HASH_EXTRA_FLAGS_MULTI_WRITER_ADD;\n \n+\tif (ext_bkt)\n+\t\thash_params.extra_flag |= RTE_HASH_EXTRA_FLAGS_EXT_TABLE;\n+\n \thash_params.name = \"tests\";\n \n \thandle = rte_hash_create(&hash_params);\n@@ -452,7 +566,7 @@ test_rwc_reader(__attribute__((unused)) void *arg)\n \tvoid *temp_a[BULK_LOOKUP_SIZE];\n \n \t/* Used to identify keys not inserted in the hash table */\n-\tpos = rte_zmalloc(NULL, sizeof(uint32_t) * BULK_LOOKUP_SIZE, 0);\n+\tpos = rte_malloc(NULL, sizeof(uint32_t) * BULK_LOOKUP_SIZE, 0);\n \tif (pos == NULL) {\n \t\tprintf(\"RTE_MALLOC failed\\n\");\n \t\treturn -1;\n@@ -467,6 +581,9 @@ test_rwc_reader(__attribute__((unused)) void *arg)\n \t} else if (read_type & READ_PASS_SHIFT_PATH) {\n \t\tkeys = tbl_rwc_test_param.keys_shift_path;\n \t\tread_cnt = tbl_rwc_test_param.count_keys_shift_path;\n+\t} else if (read_type & READ_PASS_KEY_SHIFTS_EXTBKT) {\n+\t\tkeys = tbl_rwc_test_param.keys_ext_bkt;\n+\t\tread_cnt = tbl_rwc_test_param.count_keys_extbkt;\n \t} else {\n \t\tkeys = tbl_rwc_test_param.keys_non_shift_path;\n \t\tread_cnt = tbl_rwc_test_param.count_keys_non_shift_path;\n@@ -482,7 +599,6 @@ test_rwc_reader(__attribute__((unused)) void *arg)\n \t\t\t\t/* Array of  pointer to the list of keys */\n \t\t\t\tfor (j = 0; j < BULK_LOOKUP_SIZE; j++)\n \t\t\t\t\ttemp_a[j] = keys + i + j;\n-\n \t\t\t\trte_hash_lookup_bulk(tbl_rwc_test_param.h,\n \t\t\t\t\t\t   (const void **)\n \t\t\t\t\t\t   ((uintptr_t)temp_a),\n@@ -539,22 +655,25 @@ test_rwc_reader(__attribute__((unused)) void *arg)\n }\n \n static int\n-write_keys(uint8_t key_shift)\n+write_keys(uint8_t write_type)\n {\n \tuint32_t i;\n \tint ret;\n-\tuint32_t key_cnt;\n+\tuint32_t key_cnt = 0;\n \tuint32_t *keys;\n-\tif (key_shift) {\n+\tif (write_type == WRITE_KEY_SHIFT) {\n \t\tkey_cnt = tbl_rwc_test_param.count_keys_ks;\n \t\tkeys = tbl_rwc_test_param.keys_ks;\n-\t} else {\n+\t} else if (write_type == WRITE_NO_KEY_SHIFT) {\n \t\tkey_cnt = tbl_rwc_test_param.count_keys_no_ks;\n \t\tkeys = tbl_rwc_test_param.keys_no_ks;\n+\t} else if (write_type == WRITE_EXT_BKT) {\n+\t\tkey_cnt = tbl_rwc_test_param.count_keys_extbkt;\n+\t\tkeys = tbl_rwc_test_param.keys_ext_bkt;\n \t}\n \tfor (i = 0; i < key_cnt; i++) {\n \t\tret = rte_hash_add_key(tbl_rwc_test_param.h, keys + i);\n-\t\tif (!key_shift && ret < 0) {\n+\t\tif ((write_type == WRITE_NO_KEY_SHIFT) && ret < 0) {\n \t\t\tprintf(\"writer failed %\"PRIu32\"\\n\", i);\n \t\t\treturn -1;\n \t\t}\n@@ -581,18 +700,18 @@ test_rwc_multi_writer(__attribute__((unused)) void *arg)\n  */\n static int\n test_hash_add_no_ks_lookup_hit(struct rwc_perf *rwc_perf_results, int rwc_lf,\n-\t\t\t\tint htm)\n+\t\t\t\tint htm, int ext_bkt)\n {\n \tunsigned int n, m;\n \tuint64_t i;\n \tint use_jhash = 0;\n-\tuint8_t key_shift = 0;\n+\tuint8_t write_type = WRITE_NO_KEY_SHIFT;\n \tuint8_t read_type = READ_PASS_NO_KEY_SHIFTS;\n \n \trte_atomic64_init(&greads);\n \trte_atomic64_init(&gread_cycles);\n \n-\tif (init_params(rwc_lf, use_jhash, htm) != 0)\n+\tif (init_params(rwc_lf, use_jhash, htm, ext_bkt) != 0)\n \t\tgoto err;\n \tprintf(\"\\nTest: Hash add - no key-shifts, read - hit\\n\");\n \tfor (m = 0; m < 2; m++) {\n@@ -612,7 +731,7 @@ test_hash_add_no_ks_lookup_hit(struct rwc_perf *rwc_perf_results, int rwc_lf,\n \n \t\t\trte_hash_reset(tbl_rwc_test_param.h);\n \t\t\twriter_done = 0;\n-\t\t\tif (write_keys(key_shift) < 0)\n+\t\t\tif (write_keys(write_type) < 0)\n \t\t\t\tgoto err;\n \t\t\twriter_done = 1;\n \t\t\tfor (i = 1; i <= rwc_core_cnt[n]; i++)\n@@ -650,19 +769,19 @@ test_hash_add_no_ks_lookup_hit(struct rwc_perf *rwc_perf_results, int rwc_lf,\n  */\n static int\n test_hash_add_no_ks_lookup_miss(struct rwc_perf *rwc_perf_results, int rwc_lf,\n-\t\t\t\tint htm)\n+\t\t\t\tint htm, int ext_bkt)\n {\n \tunsigned int n, m;\n \tuint64_t i;\n \tint use_jhash = 0;\n-\tuint8_t key_shift = 0;\n+\tuint8_t write_type = WRITE_NO_KEY_SHIFT;\n \tuint8_t read_type = READ_FAIL;\n \tint ret;\n \n \trte_atomic64_init(&greads);\n \trte_atomic64_init(&gread_cycles);\n \n-\tif (init_params(rwc_lf, use_jhash, htm) != 0)\n+\tif (init_params(rwc_lf, use_jhash, htm, ext_bkt) != 0)\n \t\tgoto err;\n \tprintf(\"\\nTest: Hash add - no key-shifts, Hash lookup - miss\\n\");\n \tfor (m = 0; m < 2; m++) {\n@@ -687,7 +806,7 @@ test_hash_add_no_ks_lookup_miss(struct rwc_perf *rwc_perf_results, int rwc_lf,\n \t\t\t\trte_eal_remote_launch(test_rwc_reader,\n \t\t\t\t\t\t(void *)(uintptr_t)read_type,\n \t\t\t\t\t\t\tenabled_core_ids[i]);\n-\t\t\tret = write_keys(key_shift);\n+\t\t\tret = write_keys(write_type);\n \t\t\twriter_done = 1;\n \t\t\trte_eal_mp_wait_lcore();\n \n@@ -722,19 +841,19 @@ test_hash_add_no_ks_lookup_miss(struct rwc_perf *rwc_perf_results, int rwc_lf,\n  */\n static int\n test_hash_add_ks_lookup_hit_non_sp(struct rwc_perf *rwc_perf_results,\n-\t\t\t\t    int rwc_lf, int htm)\n+\t\t\t\t    int rwc_lf, int htm, int ext_bkt)\n {\n \tunsigned int n, m;\n \tuint64_t i;\n \tint use_jhash = 0;\n \tint ret;\n-\tuint8_t key_shift;\n+\tuint8_t write_type;\n \tuint8_t read_type = READ_PASS_NON_SHIFT_PATH;\n \n \trte_atomic64_init(&greads);\n \trte_atomic64_init(&gread_cycles);\n \n-\tif (init_params(rwc_lf, use_jhash, htm) != 0)\n+\tif (init_params(rwc_lf, use_jhash, htm, ext_bkt) != 0)\n \t\tgoto err;\n \tprintf(\"\\nTest: Hash add - key shift, Hash lookup - hit\"\n \t       \" (non-shift-path)\\n\");\n@@ -755,15 +874,15 @@ test_hash_add_ks_lookup_hit_non_sp(struct rwc_perf *rwc_perf_results,\n \n \t\t\trte_hash_reset(tbl_rwc_test_param.h);\n \t\t\twriter_done = 0;\n-\t\t\tkey_shift = 0;\n-\t\t\tif (write_keys(key_shift) < 0)\n+\t\t\twrite_type = WRITE_NO_KEY_SHIFT;\n+\t\t\tif (write_keys(write_type) < 0)\n \t\t\t\tgoto err;\n \t\t\tfor (i = 1; i <= rwc_core_cnt[n]; i++)\n \t\t\t\trte_eal_remote_launch(test_rwc_reader,\n \t\t\t\t\t\t(void *)(uintptr_t)read_type,\n \t\t\t\t\t\t\tenabled_core_ids[i]);\n-\t\t\tkey_shift = 1;\n-\t\t\tret = write_keys(key_shift);\n+\t\t\twrite_type = WRITE_KEY_SHIFT;\n+\t\t\tret = write_keys(write_type);\n \t\t\twriter_done = 1;\n \t\t\trte_eal_mp_wait_lcore();\n \n@@ -798,19 +917,19 @@ test_hash_add_ks_lookup_hit_non_sp(struct rwc_perf *rwc_perf_results,\n  */\n static int\n test_hash_add_ks_lookup_hit_sp(struct rwc_perf *rwc_perf_results, int rwc_lf,\n-\t\t\t\tint htm)\n+\t\t\t\tint htm, int ext_bkt)\n {\n \tunsigned int n, m;\n \tuint64_t i;\n \tint use_jhash = 0;\n \tint ret;\n-\tuint8_t key_shift;\n+\tuint8_t write_type;\n \tuint8_t read_type = READ_PASS_SHIFT_PATH;\n \n \trte_atomic64_init(&greads);\n \trte_atomic64_init(&gread_cycles);\n \n-\tif (init_params(rwc_lf, use_jhash, htm) != 0)\n+\tif (init_params(rwc_lf, use_jhash, htm, ext_bkt) != 0)\n \t\tgoto err;\n \tprintf(\"\\nTest: Hash add - key shift, Hash lookup - hit (shift-path)\"\n \t       \"\\n\");\n@@ -831,15 +950,15 @@ test_hash_add_ks_lookup_hit_sp(struct rwc_perf *rwc_perf_results, int rwc_lf,\n \n \t\t\trte_hash_reset(tbl_rwc_test_param.h);\n \t\t\twriter_done = 0;\n-\t\t\tkey_shift = 0;\n-\t\t\tif (write_keys(key_shift) < 0)\n+\t\t\twrite_type = WRITE_NO_KEY_SHIFT;\n+\t\t\tif (write_keys(write_type) < 0)\n \t\t\t\tgoto err;\n \t\t\tfor (i = 1; i <= rwc_core_cnt[n]; i++)\n \t\t\t\trte_eal_remote_launch(test_rwc_reader,\n \t\t\t\t\t\t(void *)(uintptr_t)read_type,\n \t\t\t\t\t\tenabled_core_ids[i]);\n-\t\t\tkey_shift = 1;\n-\t\t\tret = write_keys(key_shift);\n+\t\t\twrite_type = WRITE_KEY_SHIFT;\n+\t\t\tret = write_keys(write_type);\n \t\t\twriter_done = 1;\n \t\t\trte_eal_mp_wait_lcore();\n \n@@ -874,19 +993,19 @@ test_hash_add_ks_lookup_hit_sp(struct rwc_perf *rwc_perf_results, int rwc_lf,\n  */\n static int\n test_hash_add_ks_lookup_miss(struct rwc_perf *rwc_perf_results, int rwc_lf, int\n-\t\t\t     htm)\n+\t\t\t     htm, int ext_bkt)\n {\n \tunsigned int n, m;\n \tuint64_t i;\n \tint use_jhash = 0;\n \tint ret;\n-\tuint8_t key_shift;\n+\tuint8_t write_type;\n \tuint8_t read_type = READ_FAIL;\n \n \trte_atomic64_init(&greads);\n \trte_atomic64_init(&gread_cycles);\n \n-\tif (init_params(rwc_lf, use_jhash, htm) != 0)\n+\tif (init_params(rwc_lf, use_jhash, htm, ext_bkt) != 0)\n \t\tgoto err;\n \tprintf(\"\\nTest: Hash add - key shift, Hash lookup - miss\\n\");\n \tfor (m = 0; m < 2; m++) {\n@@ -906,15 +1025,15 @@ test_hash_add_ks_lookup_miss(struct rwc_perf *rwc_perf_results, int rwc_lf, int\n \n \t\t\trte_hash_reset(tbl_rwc_test_param.h);\n \t\t\twriter_done = 0;\n-\t\t\tkey_shift = 0;\n-\t\t\tif (write_keys(key_shift) < 0)\n+\t\t\twrite_type = WRITE_NO_KEY_SHIFT;\n+\t\t\tif (write_keys(write_type) < 0)\n \t\t\t\tgoto err;\n \t\t\tfor (i = 1; i <= rwc_core_cnt[n]; i++)\n \t\t\t\trte_eal_remote_launch(test_rwc_reader,\n \t\t\t\t\t\t(void *)(uintptr_t)read_type,\n \t\t\t\t\t\t\tenabled_core_ids[i]);\n-\t\t\tkey_shift = 1;\n-\t\t\tret = write_keys(key_shift);\n+\t\t\twrite_type = WRITE_KEY_SHIFT;\n+\t\t\tret = write_keys(write_type);\n \t\t\twriter_done = 1;\n \t\t\trte_eal_mp_wait_lcore();\n \n@@ -949,18 +1068,18 @@ test_hash_add_ks_lookup_miss(struct rwc_perf *rwc_perf_results, int rwc_lf, int\n  */\n static int\n test_hash_multi_add_lookup(struct rwc_perf *rwc_perf_results, int rwc_lf,\n-\t\t\t   int htm)\n+\t\t\t   int htm, int ext_bkt)\n {\n \tunsigned int n, m, k;\n \tuint64_t i;\n \tint use_jhash = 0;\n-\tuint8_t key_shift;\n+\tuint8_t write_type;\n \tuint8_t read_type = READ_PASS_SHIFT_PATH;\n \n \trte_atomic64_init(&greads);\n \trte_atomic64_init(&gread_cycles);\n \n-\tif (init_params(rwc_lf, use_jhash, htm) != 0)\n+\tif (init_params(rwc_lf, use_jhash, htm, ext_bkt) != 0)\n \t\tgoto err;\n \tprintf(\"\\nTest: Multi-add-lookup\\n\");\n \tuint8_t pos_core;\n@@ -991,8 +1110,8 @@ test_hash_multi_add_lookup(struct rwc_perf *rwc_perf_results, int rwc_lf,\n \t\t\t\twriter_done = 0;\n \t\t\t\tfor (i = 0; i < 4; i++)\n \t\t\t\t\tmulti_writer_done[i] = 0;\n-\t\t\t\tkey_shift = 0;\n-\t\t\t\tif (write_keys(key_shift) < 0)\n+\t\t\t\twrite_type = WRITE_NO_KEY_SHIFT;\n+\t\t\t\tif (write_keys(write_type) < 0)\n \t\t\t\t\tgoto err;\n \n \t\t\t\t/* Launch reader(s) */\n@@ -1000,7 +1119,7 @@ test_hash_multi_add_lookup(struct rwc_perf *rwc_perf_results, int rwc_lf,\n \t\t\t\t\trte_eal_remote_launch(test_rwc_reader,\n \t\t\t\t\t\t(void *)(uintptr_t)read_type,\n \t\t\t\t\t\tenabled_core_ids[i]);\n-\t\t\t\tkey_shift = 1;\n+\t\t\t\twrite_type = WRITE_KEY_SHIFT;\n \t\t\t\tpos_core = 0;\n \n \t\t\t\t/* Launch writers */\n@@ -1045,6 +1164,88 @@ test_hash_multi_add_lookup(struct rwc_perf *rwc_perf_results, int rwc_lf,\n \treturn -1;\n }\n \n+/*\n+ * Test lookup perf:\n+ * Reader(s) lookup keys present in the extendable bkt.\n+ */\n+static int\n+test_hash_add_ks_lookup_hit_extbkt(struct rwc_perf *rwc_perf_results,\n+\t\t\t\tint rwc_lf, int htm, int ext_bkt)\n+{\n+\tunsigned int n, m;\n+\tuint64_t i;\n+\tint use_jhash = 0;\n+\tuint8_t write_type;\n+\tuint8_t read_type = READ_PASS_KEY_SHIFTS_EXTBKT;\n+\n+\trte_atomic64_init(&greads);\n+\trte_atomic64_init(&gread_cycles);\n+\n+\tif (init_params(rwc_lf, use_jhash, htm, ext_bkt) != 0)\n+\t\tgoto err;\n+\tprintf(\"\\nTest: Hash add - key-shifts, read - hit (ext_bkt)\\n\");\n+\tfor (m = 0; m < 2; m++) {\n+\t\tif (m == 1) {\n+\t\t\tprintf(\"\\n** With bulk-lookup **\\n\");\n+\t\t\tread_type |= BULK_LOOKUP;\n+\t\t}\n+\t\tfor (n = 0; n < NUM_TEST; n++) {\n+\t\t\tunsigned int tot_lcore = rte_lcore_count();\n+\t\t\tif (tot_lcore < rwc_core_cnt[n] + 1)\n+\t\t\t\tgoto finish;\n+\n+\t\t\tprintf(\"\\nNumber of readers: %u\\n\", rwc_core_cnt[n]);\n+\n+\t\t\trte_atomic64_clear(&greads);\n+\t\t\trte_atomic64_clear(&gread_cycles);\n+\n+\t\t\trte_hash_reset(tbl_rwc_test_param.h);\n+\t\t\twrite_type = WRITE_NO_KEY_SHIFT;\n+\t\t\tif (write_keys(write_type) < 0)\n+\t\t\t\tgoto err;\n+\t\t\twrite_type = WRITE_KEY_SHIFT;\n+\t\t\tif (write_keys(write_type) < 0)\n+\t\t\t\tgoto err;\n+\t\t\twriter_done = 0;\n+\t\t\tfor (i = 1; i <= rwc_core_cnt[n]; i++)\n+\t\t\t\trte_eal_remote_launch(test_rwc_reader,\n+\t\t\t\t\t\t(void *)(uintptr_t)read_type,\n+\t\t\t\t\t\t\tenabled_core_ids[i]);\n+\t\t\tfor (i = 0; i < tbl_rwc_test_param.count_keys_ks_extbkt;\n+\t\t\t     i++) {\n+\t\t\t\tif (rte_hash_del_key(tbl_rwc_test_param.h,\n+\t\t\t\t\ttbl_rwc_test_param.keys_ks_extbkt + i)\n+\t\t\t\t\t\t\t< 0) {\n+\t\t\t\t\tprintf(\"Delete Failed: %u\\n\",\n+\t\t\t\t\ttbl_rwc_test_param.keys_ks_extbkt[i]);\n+\t\t\t\t\tgoto err;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\twriter_done = 1;\n+\t\t\trte_eal_mp_wait_lcore();\n+\n+\t\t\tfor (i = 1; i <= rwc_core_cnt[n]; i++)\n+\t\t\t\tif (lcore_config[i].ret < 0)\n+\t\t\t\t\tgoto err;\n+\n+\t\t\tunsigned long long cycles_per_lookup =\n+\t\t\t\trte_atomic64_read(&gread_cycles) /\n+\t\t\t\trte_atomic64_read(&greads);\n+\t\t\trwc_perf_results->w_ks_r_hit_extbkt[m][n]\n+\t\t\t\t\t\t= cycles_per_lookup;\n+\t\t\tprintf(\"Cycles per lookup: %llu\\n\", cycles_per_lookup);\n+\t\t}\n+\t}\n+\n+finish:\n+\trte_hash_free(tbl_rwc_test_param.h);\n+\treturn 0;\n+\n+err:\n+\trte_hash_free(tbl_rwc_test_param.h);\n+\treturn -1;\n+}\n+\n static int\n test_hash_readwrite_lf_main(void)\n {\n@@ -1057,6 +1258,7 @@ test_hash_readwrite_lf_main(void)\n \tint rwc_lf = 0;\n \tint htm;\n \tint use_jhash = 0;\n+\tint ext_bkt = 0;\n \tif (rte_lcore_count() == 1) {\n \t\tprintf(\"More than one lcore is required \"\n \t\t\t\"to do read write lock-free concurrency test\\n\");\n@@ -1070,7 +1272,7 @@ test_hash_readwrite_lf_main(void)\n \telse\n \t\thtm = 0;\n \n-\tif (init_params(rwc_lf, use_jhash, htm) != 0)\n+\tif (init_params(rwc_lf, use_jhash, htm, ext_bkt) != 0)\n \t\treturn -1;\n \tif (generate_keys() != 0)\n \t\treturn -1;\n@@ -1079,25 +1281,29 @@ test_hash_readwrite_lf_main(void)\n \n \tif (RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY_LF) {\n \t\trwc_lf = 1;\n+\t\text_bkt = 1;\n \t\tprintf(\"Test lookup with read-write concurrency lock free support\"\n \t\t       \" enabled\\n\");\n \t\tif (test_hash_add_no_ks_lookup_hit(&rwc_lf_results, rwc_lf,\n-\t\t\t\t\t\t\thtm) < 0)\n+\t\t\t\t\t\t\thtm, ext_bkt) < 0)\n \t\t\treturn -1;\n \t\tif (test_hash_add_no_ks_lookup_miss(&rwc_lf_results, rwc_lf,\n-\t\t\t\t\t\t\thtm) < 0)\n+\t\t\t\t\t\t\thtm, ext_bkt) < 0)\n \t\t\treturn -1;\n \t\tif (test_hash_add_ks_lookup_hit_non_sp(&rwc_lf_results, rwc_lf,\n-\t\t\t\t\t\t\thtm) < 0)\n+\t\t\t\t\t\t\thtm, ext_bkt) < 0)\n \t\t\treturn -1;\n \t\tif (test_hash_add_ks_lookup_hit_sp(&rwc_lf_results, rwc_lf,\n-\t\t\t\t\t\t\thtm) < 0)\n+\t\t\t\t\t\t\thtm, ext_bkt) < 0)\n \t\t\treturn -1;\n-\t\tif (test_hash_add_ks_lookup_miss(&rwc_lf_results, rwc_lf, htm)\n-\t\t\t\t\t\t\t< 0)\n+\t\tif (test_hash_add_ks_lookup_miss(&rwc_lf_results, rwc_lf, htm,\n+\t\t\t\t\t\t ext_bkt) < 0)\n \t\t\treturn -1;\n-\t\tif (test_hash_multi_add_lookup(&rwc_lf_results, rwc_lf, htm)\n-\t\t\t\t\t\t\t< 0)\n+\t\tif (test_hash_multi_add_lookup(&rwc_lf_results, rwc_lf, htm,\n+\t\t\t\t\t       ext_bkt) < 0)\n+\t\t\treturn -1;\n+\t\tif (test_hash_add_ks_lookup_hit_extbkt(&rwc_lf_results, rwc_lf,\n+\t\t\t\t\t\t\thtm, ext_bkt) < 0)\n \t\t\treturn -1;\n \t}\n \tprintf(\"\\nTest lookup with read-write concurrency lock free support\"\n@@ -1112,21 +1318,26 @@ test_hash_readwrite_lf_main(void)\n \t\t}\n \t} else\n \t\tprintf(\"With HTM Enabled\\n\");\n-\tif (test_hash_add_no_ks_lookup_hit(&rwc_non_lf_results, rwc_lf, htm)\n-\t\t\t\t\t\t< 0)\n+\tif (test_hash_add_no_ks_lookup_hit(&rwc_non_lf_results, rwc_lf, htm,\n+\t\t\t\t\t   ext_bkt) < 0)\n \t\treturn -1;\n-\tif (test_hash_add_no_ks_lookup_miss(&rwc_non_lf_results, rwc_lf, htm)\n-\t\t\t\t\t\t< 0)\n+\tif (test_hash_add_no_ks_lookup_miss(&rwc_non_lf_results, rwc_lf, htm,\n+\t\t\t\t\t\text_bkt) < 0)\n \t\treturn -1;\n \tif (test_hash_add_ks_lookup_hit_non_sp(&rwc_non_lf_results, rwc_lf,\n-\t\t\t\t\t\thtm) < 0)\n+\t\t\t\t\t\thtm, ext_bkt) < 0)\n+\t\treturn -1;\n+\tif (test_hash_add_ks_lookup_hit_sp(&rwc_non_lf_results, rwc_lf, htm,\n+\t\t\t\t\t\text_bkt) < 0)\n \t\treturn -1;\n-\tif (test_hash_add_ks_lookup_hit_sp(&rwc_non_lf_results, rwc_lf, htm)\n-\t\t\t\t\t\t< 0)\n+\tif (test_hash_add_ks_lookup_miss(&rwc_non_lf_results, rwc_lf, htm,\n+\t\t\t\t\t ext_bkt) < 0)\n \t\treturn -1;\n-\tif (test_hash_add_ks_lookup_miss(&rwc_non_lf_results, rwc_lf, htm) < 0)\n+\tif (test_hash_multi_add_lookup(&rwc_non_lf_results, rwc_lf, htm,\n+\t\t\t\t\t\t\text_bkt) < 0)\n \t\treturn -1;\n-\tif (test_hash_multi_add_lookup(&rwc_non_lf_results, rwc_lf, htm) < 0)\n+\tif (test_hash_add_ks_lookup_hit_extbkt(&rwc_non_lf_results, rwc_lf,\n+\t\t\t\t\t\thtm, ext_bkt) < 0)\n \t\treturn -1;\n results:\n \tprintf(\"\\n\\t\\t\\t\\t\\t\\t********** Results summary **********\\n\\n\");\n@@ -1158,8 +1369,11 @@ test_hash_readwrite_lf_main(void)\n \t\t\t       \"(shift-path)\\t\\t%u\\n\\t\\t\\t\\t\\t\\t\\t\\t\",\n \t\t\t       rwc_lf_results.w_ks_r_hit_sp[j][i]);\n \t\t\tprintf(\"Hash add - key-shifts, Hash lookup miss\\t\\t\\t\\t\"\n-\t\t\t\t\"%u\\n\\n\\t\\t\\t\\t\",\n+\t\t\t\t\"%u\\n\\t\\t\\t\\t\\t\\t\\t\\t\",\n \t\t\t\trwc_lf_results.w_ks_r_miss[j][i]);\n+\t\t\tprintf(\"Hash add - key-shifts, Hash lookup hit (ext_bkt)\\t\\t\"\n+\t\t\t\t\"%u\\n\\n\\t\\t\\t\\t\",\n+\t\t\t\trwc_lf_results.w_ks_r_hit_extbkt[j][i]);\n \n \t\t\tprintf(\"Disabled\\t\");\n \t\t\tif (htm)\n@@ -1179,7 +1393,11 @@ test_hash_readwrite_lf_main(void)\n \t\t\t       \"(shift-path)\\t\\t%u\\n\\t\\t\\t\\t\\t\\t\\t\\t\",\n \t\t\t       rwc_non_lf_results.w_ks_r_hit_sp[j][i]);\n \t\t\tprintf(\"Hash add - key-shifts, Hash lookup miss\\t\\t\\t\\t\"\n-\t\t\t       \"%u\\n\", rwc_non_lf_results.w_ks_r_miss[j][i]);\n+\t\t\t       \"%u\\n\\t\\t\\t\\t\\t\\t\\t\\t\",\n+\t\t\t       rwc_non_lf_results.w_ks_r_miss[j][i]);\n+\t\t\tprintf(\"Hash add - key-shifts, Hash lookup hit (ext_bkt)\\t\\t\"\n+\t\t\t\t\"%u\\n\",\n+\t\t\t\trwc_non_lf_results.w_ks_r_hit_extbkt[j][i]);\n \n \t\t\tprintf(\"_______\\t\\t_______\\t\\t_________\\t___\\t\\t\"\n \t\t\t       \"_________\\t\\t\\t\\t\\t\\t_________________\\n\");\n",
    "prefixes": [
        "v5",
        "2/2"
    ]
}