Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/11696/?format=api
http://patches.dpdk.org/api/patches/11696/?format=api", "web_url": "http://patches.dpdk.org/project/dpdk/patch/1458827804-25496-1-git-send-email-pablo.de.lara.guarch@intel.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": "<1458827804-25496-1-git-send-email-pablo.de.lara.guarch@intel.com>", "list_archive_url": "https://inbox.dpdk.org/dev/1458827804-25496-1-git-send-email-pablo.de.lara.guarch@intel.com", "date": "2016-03-24T13:56:44", "name": "[dpdk-dev] hash: fix to support multi process", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": true, "hash": "7c422f61f39df7edd86a9fb03b7198263b5aa3d5", "submitter": { "id": 9, "url": "http://patches.dpdk.org/api/people/9/?format=api", "name": "De Lara Guarch, Pablo", "email": "pablo.de.lara.guarch@intel.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/1458827804-25496-1-git-send-email-pablo.de.lara.guarch@intel.com/mbox/", "series": [], "comments": "http://patches.dpdk.org/api/patches/11696/comments/", "check": "pending", "checks": "http://patches.dpdk.org/api/patches/11696/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 [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 9AFB22BF5;\n\tThu, 24 Mar 2016 14:53:57 +0100 (CET)", "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n\tby dpdk.org (Postfix) with ESMTP id 4AAF72BE3\n\tfor <dev@dpdk.org>; Thu, 24 Mar 2016 14:53:56 +0100 (CET)", "from fmsmga001.fm.intel.com ([10.253.24.23])\n\tby orsmga101.jf.intel.com with ESMTP; 24 Mar 2016 06:53:55 -0700", "from sie-lab-212-116.ir.intel.com (HELO localhost.ir.intel.com)\n\t([10.237.212.116])\n\tby fmsmga001.fm.intel.com with ESMTP; 24 Mar 2016 06:53:54 -0700" ], "X-ExtLoop1": "1", "X-IronPort-AV": "E=Sophos;i=\"5.24,385,1455004800\"; d=\"scan'208\";a=\"930917983\"", "From": "Pablo de Lara <pablo.de.lara.guarch@intel.com>", "To": "dev@dpdk.org", "Cc": "bruce.richardson@intel.com, edreddy@gmail.com,\n\tPablo de Lara <pablo.de.lara.guarch@intel.com>", "Date": "Thu, 24 Mar 2016 13:56:44 +0000", "Message-Id": "<1458827804-25496-1-git-send-email-pablo.de.lara.guarch@intel.com>", "X-Mailer": "git-send-email 2.5.0", "Subject": "[dpdk-dev] [PATCH] hash: fix to support multi process", "X-BeenThere": "dev@dpdk.org", "X-Mailman-Version": "2.1.15", "Precedence": "list", "List-Id": "patches and discussions about DPDK <dev.dpdk.org>", "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>", "List-Archive": "<http://dpdk.org/ml/archives/dev/>", "List-Post": "<mailto:dev@dpdk.org>", "List-Help": "<mailto:dev-request@dpdk.org?subject=help>", "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>", "Errors-To": "dev-bounces@dpdk.org", "Sender": "\"dev\" <dev-bounces@dpdk.org>" }, "content": "Hash library used a function pointer to choose a different\nkey compare function, depending on the key size.\nAs a result, multiple processes could not use the same hash table,\nas the function addresses vary from one process to another.\n\nInstead, a jump table is used, so each process has its own\nfunction addresses, accessing this table with an index stored\nin the hash table (note that using a custom key compare function\nis not supported in multi-process mode).\n\nFixes: 48a399119619 (\"hash: replace with cuckoo hash implementation\")\n\nSigned-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>\n---\n doc/guides/rel_notes/release_16_04.rst | 5 ++\n lib/librte_hash/rte_cuckoo_hash.c | 85 ++++++++++++++++++++++++++--------\n 2 files changed, 71 insertions(+), 19 deletions(-)", "diff": "diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst\nindex 2785b29..c4359dd 100644\n--- a/doc/guides/rel_notes/release_16_04.rst\n+++ b/doc/guides/rel_notes/release_16_04.rst\n@@ -351,6 +351,11 @@ Libraries\n Fix crc32c hash functions to return a valid crc32c value for data lengths\n not multiple of 4 bytes.\n \n+* **hash: Fixed hash library to support multi-process mode.**\n+\n+ Fix hash library to support multi-process mode, using a jump table,\n+ instead of storing a function pointer to the key compare function.\n+\n * **librte_port: Fixed segmentation fault for ring and ethdev writer nodrop.**\n \n Fixed core dump issue on txq and swq when dropless is set to yes.\ndiff --git a/lib/librte_hash/rte_cuckoo_hash.c b/lib/librte_hash/rte_cuckoo_hash.c\nindex 71b5b76..38c19ab 100644\n--- a/lib/librte_hash/rte_cuckoo_hash.c\n+++ b/lib/librte_hash/rte_cuckoo_hash.c\n@@ -102,6 +102,41 @@ EAL_REGISTER_TAILQ(rte_hash_tailq)\n \n #define LCORE_CACHE_SIZE\t\t8\n \n+/*\n+ * All different options to select a key compare function,\n+ * based on the key size and custom function.\n+ */\n+enum cmp_jump_table_case {\n+\tKEY_CUSTOM = 0,\n+\tKEY_16_BYTES,\n+\tKEY_32_BYTES,\n+\tKEY_48_BYTES,\n+\tKEY_64_BYTES,\n+\tKEY_80_BYTES,\n+\tKEY_96_BYTES,\n+\tKEY_112_BYTES,\n+\tKEY_128_BYTES,\n+\tKEY_OTHER_BYTES,\n+\tNUM_KEY_CMP_CASES,\n+};\n+\n+/*\n+ * Table storing all different key compare functions\n+ * (multi-process supported)\n+ */\n+rte_hash_cmp_eq_t cmp_jump_table[NUM_KEY_CMP_CASES] = {\n+\tNULL,\n+\trte_hash_k16_cmp_eq,\n+\trte_hash_k32_cmp_eq,\n+\trte_hash_k48_cmp_eq,\n+\trte_hash_k64_cmp_eq,\n+\trte_hash_k80_cmp_eq,\n+\trte_hash_k96_cmp_eq,\n+\trte_hash_k112_cmp_eq,\n+\trte_hash_k128_cmp_eq,\n+\tmemcmp\n+};\n+\n struct lcore_cache {\n \tunsigned len; /**< Cache len */\n \tvoid *objs[LCORE_CACHE_SIZE]; /**< Cache objects */\n@@ -115,7 +150,10 @@ struct rte_hash {\n \tuint32_t key_len; /**< Length of hash key. */\n \trte_hash_function hash_func; /**< Function used to calculate hash. */\n \tuint32_t hash_func_init_val; /**< Init value used by hash_func. */\n-\trte_hash_cmp_eq_t rte_hash_cmp_eq; /**< Function used to compare keys. */\n+\trte_hash_cmp_eq_t rte_hash_custom_cmp_eq;\n+\t/**< Custom function used to compare keys. */\n+\tenum cmp_jump_table_case cmp_jump_table_idx;\n+\t/**< Indicates which compare function to use. */\n \tuint32_t bucket_bitmask; /**< Bitmask for getting bucket index\n \t\t\t\t\t\tfrom hash signature. */\n \tuint32_t key_entry_size; /**< Size of each key entry. */\n@@ -187,7 +225,16 @@ rte_hash_find_existing(const char *name)\n \n void rte_hash_set_cmp_func(struct rte_hash *h, rte_hash_cmp_eq_t func)\n {\n-\th->rte_hash_cmp_eq = func;\n+\th->rte_hash_custom_cmp_eq = func;\n+}\n+\n+static inline int\n+rte_hash_cmp_eq(const void *key1, const void *key2, const struct rte_hash *h)\n+{\n+\tif (h->cmp_jump_table_idx == KEY_CUSTOM)\n+\t\treturn h->rte_hash_custom_cmp_eq(key1, key2, h->key_len);\n+\telse\n+\t\treturn cmp_jump_table[h->cmp_jump_table_idx](key1, key2, h->key_len);\n }\n \n struct rte_hash *\n@@ -292,35 +339,35 @@ rte_hash_create(const struct rte_hash_parameters *params)\n \t/* Select function to compare keys */\n \tswitch (params->key_len) {\n \tcase 16:\n-\t\th->rte_hash_cmp_eq = rte_hash_k16_cmp_eq;\n+\t\th->cmp_jump_table_idx = KEY_16_BYTES;\n \t\tbreak;\n \tcase 32:\n-\t\th->rte_hash_cmp_eq = rte_hash_k32_cmp_eq;\n+\t\th->cmp_jump_table_idx = KEY_32_BYTES;\n \t\tbreak;\n \tcase 48:\n-\t\th->rte_hash_cmp_eq = rte_hash_k48_cmp_eq;\n+\t\th->cmp_jump_table_idx = KEY_48_BYTES;\n \t\tbreak;\n \tcase 64:\n-\t\th->rte_hash_cmp_eq = rte_hash_k64_cmp_eq;\n+\t\th->cmp_jump_table_idx = KEY_64_BYTES;\n \t\tbreak;\n \tcase 80:\n-\t\th->rte_hash_cmp_eq = rte_hash_k80_cmp_eq;\n+\t\th->cmp_jump_table_idx = KEY_80_BYTES;\n \t\tbreak;\n \tcase 96:\n-\t\th->rte_hash_cmp_eq = rte_hash_k96_cmp_eq;\n+\t\th->cmp_jump_table_idx = KEY_96_BYTES;\n \t\tbreak;\n \tcase 112:\n-\t\th->rte_hash_cmp_eq = rte_hash_k112_cmp_eq;\n+\t\th->cmp_jump_table_idx = KEY_112_BYTES;\n \t\tbreak;\n \tcase 128:\n-\t\th->rte_hash_cmp_eq = rte_hash_k128_cmp_eq;\n+\t\th->cmp_jump_table_idx = KEY_128_BYTES;\n \t\tbreak;\n \tdefault:\n \t\t/* If key is not multiple of 16, use generic memcmp */\n-\t\th->rte_hash_cmp_eq = memcmp;\n+\t\th->cmp_jump_table_idx = KEY_OTHER_BYTES;\n \t}\n #else\n-\th->rte_hash_cmp_eq = memcmp;\n+\th->cmp_jump_table_idx = KEY_OTHER_BYTES;\n #endif\n \n \tsnprintf(ring_name, sizeof(ring_name), \"HT_%s\", params->name);\n@@ -594,7 +641,7 @@ __rte_hash_add_key_with_hash(const struct rte_hash *h, const void *key,\n \t\t\t\tprim_bkt->signatures[i].alt == alt_hash) {\n \t\t\tk = (struct rte_hash_key *) ((char *)keys +\n \t\t\t\t\tprim_bkt->key_idx[i] * h->key_entry_size);\n-\t\t\tif (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {\n+\t\t\tif (rte_hash_cmp_eq(key, k->key, h) == 0) {\n \t\t\t\t/* Enqueue index of free slot back in the ring. */\n \t\t\t\tenqueue_slot_back(h, cached_free_slots, slot_id);\n \t\t\t\t/* Update data */\n@@ -614,7 +661,7 @@ __rte_hash_add_key_with_hash(const struct rte_hash *h, const void *key,\n \t\t\t\tsec_bkt->signatures[i].current == alt_hash) {\n \t\t\tk = (struct rte_hash_key *) ((char *)keys +\n \t\t\t\t\tsec_bkt->key_idx[i] * h->key_entry_size);\n-\t\t\tif (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {\n+\t\t\tif (rte_hash_cmp_eq(key, k->key, h) == 0) {\n \t\t\t\t/* Enqueue index of free slot back in the ring. */\n \t\t\t\tenqueue_slot_back(h, cached_free_slots, slot_id);\n \t\t\t\t/* Update data */\n@@ -725,7 +772,7 @@ __rte_hash_lookup_with_hash(const struct rte_hash *h, const void *key,\n \t\t\t\tbkt->signatures[i].sig != NULL_SIGNATURE) {\n \t\t\tk = (struct rte_hash_key *) ((char *)keys +\n \t\t\t\t\tbkt->key_idx[i] * h->key_entry_size);\n-\t\t\tif (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {\n+\t\t\tif (rte_hash_cmp_eq(key, k->key, h) == 0) {\n \t\t\t\tif (data != NULL)\n \t\t\t\t\t*data = k->pdata;\n \t\t\t\t/*\n@@ -748,7 +795,7 @@ __rte_hash_lookup_with_hash(const struct rte_hash *h, const void *key,\n \t\t\t\tbkt->signatures[i].alt == sig) {\n \t\t\tk = (struct rte_hash_key *) ((char *)keys +\n \t\t\t\t\tbkt->key_idx[i] * h->key_entry_size);\n-\t\t\tif (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {\n+\t\t\tif (rte_hash_cmp_eq(key, k->key, h) == 0) {\n \t\t\t\tif (data != NULL)\n \t\t\t\t\t*data = k->pdata;\n \t\t\t\t/*\n@@ -840,7 +887,7 @@ __rte_hash_del_key_with_hash(const struct rte_hash *h, const void *key,\n \t\t\t\tbkt->signatures[i].sig != NULL_SIGNATURE) {\n \t\t\tk = (struct rte_hash_key *) ((char *)keys +\n \t\t\t\t\tbkt->key_idx[i] * h->key_entry_size);\n-\t\t\tif (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {\n+\t\t\tif (rte_hash_cmp_eq(key, k->key, h) == 0) {\n \t\t\t\tremove_entry(h, bkt, i);\n \n \t\t\t\t/*\n@@ -863,7 +910,7 @@ __rte_hash_del_key_with_hash(const struct rte_hash *h, const void *key,\n \t\t\t\tbkt->signatures[i].sig != NULL_SIGNATURE) {\n \t\t\tk = (struct rte_hash_key *) ((char *)keys +\n \t\t\t\t\tbkt->key_idx[i] * h->key_entry_size);\n-\t\t\tif (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {\n+\t\t\tif (rte_hash_cmp_eq(key, k->key, h) == 0) {\n \t\t\t\tremove_entry(h, bkt, i);\n \n \t\t\t\t/*\n@@ -980,7 +1027,7 @@ lookup_stage3(unsigned idx, const struct rte_hash_key *key_slot, const void * co\n \tunsigned hit;\n \tunsigned key_idx;\n \n-\thit = !h->rte_hash_cmp_eq(key_slot->key, keys[idx], h->key_len);\n+\thit = !rte_hash_cmp_eq(key_slot->key, keys[idx], h);\n \tif (data != NULL)\n \t\tdata[idx] = key_slot->pdata;\n \n", "prefixes": [ "dpdk-dev" ] }{ "id": 11696, "url": "