Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/91076/?format=api
http://patches.dpdk.org/api/patches/91076/?format=api", "web_url": "http://patches.dpdk.org/project/dpdk/patch/1618168266-338017-2-git-send-email-vladimir.medvedkin@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": "<1618168266-338017-2-git-send-email-vladimir.medvedkin@intel.com>", "list_archive_url": "https://inbox.dpdk.org/dev/1618168266-338017-2-git-send-email-vladimir.medvedkin@intel.com", "date": "2021-04-11T19:11:04", "name": "[v3,1/3] hash: add predictable RSS API", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": true, "hash": "36cfec30dd0f7914a9c4922ed0d037d30afd5383", "submitter": { "id": 1216, "url": "http://patches.dpdk.org/api/people/1216/?format=api", "name": "Vladimir Medvedkin", "email": "vladimir.medvedkin@intel.com" }, "delegate": { "id": 24651, "url": "http://patches.dpdk.org/api/users/24651/?format=api", "username": "dmarchand", "first_name": "David", "last_name": "Marchand", "email": "david.marchand@redhat.com" }, "mbox": "http://patches.dpdk.org/project/dpdk/patch/1618168266-338017-2-git-send-email-vladimir.medvedkin@intel.com/mbox/", "series": [ { "id": 16279, "url": "http://patches.dpdk.org/api/series/16279/?format=api", "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=16279", "date": "2021-04-11T19:11:03", "name": "Predictable RSS feature", "version": 3, "mbox": "http://patches.dpdk.org/series/16279/mbox/" } ], "comments": "http://patches.dpdk.org/api/patches/91076/comments/", "check": "warning", "checks": "http://patches.dpdk.org/api/patches/91076/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<dev-bounces@dpdk.org>", "X-Original-To": "patchwork@inbox.dpdk.org", "Delivered-To": "patchwork@inbox.dpdk.org", "Received": [ "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 5DBEEA0524;\n\tSun, 11 Apr 2021 21:11:24 +0200 (CEST)", "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 245B1141446;\n\tSun, 11 Apr 2021 21:11:21 +0200 (CEST)", "from mga11.intel.com (mga11.intel.com [192.55.52.93])\n by mails.dpdk.org (Postfix) with ESMTP id 457C6141439\n for <dev@dpdk.org>; Sun, 11 Apr 2021 21:11:18 +0200 (CEST)", "from orsmga003.jf.intel.com ([10.7.209.27])\n by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 11 Apr 2021 12:11:17 -0700", "from silpixa00400072.ir.intel.com ([10.237.222.213])\n by orsmga003.jf.intel.com with ESMTP; 11 Apr 2021 12:11:15 -0700" ], "IronPort-SDR": [ "\n YGF+4xrXuMVn6+oOO/iXeCmN7AaRffXopZmeEp1OmvmVfsVKmyIT6pek0kyfQZdvlzKibD+nL8\n ix6pC+nqe9EA==", "\n 9FpgLP81fufAt5edC56q51AyHoQh0hyX+VW3KMDKDZRlOBZ7KbmMXBink6B3Kl6umw3VGCzNJq\n NiK8KsIm1CUQ==" ], "X-IronPort-AV": [ "E=McAfee;i=\"6000,8403,9951\"; a=\"190875040\"", "E=Sophos;i=\"5.82,214,1613462400\"; d=\"scan'208\";a=\"190875040\"", "E=Sophos;i=\"5.82,214,1613462400\"; d=\"scan'208\";a=\"381304908\"" ], "X-ExtLoop1": "1", "From": "Vladimir Medvedkin <vladimir.medvedkin@intel.com>", "To": "dev@dpdk.org", "Cc": "konstantin.ananyev@intel.com, andrey.chilikin@intel.com,\n ray.kinsella@intel.com, yipeng1.wang@intel.com, sameh.gobriel@intel.com,\n bruce.richardson@intel.com", "Date": "Sun, 11 Apr 2021 20:11:04 +0100", "Message-Id": "<1618168266-338017-2-git-send-email-vladimir.medvedkin@intel.com>", "X-Mailer": "git-send-email 2.7.4", "In-Reply-To": [ "<1618168266-338017-1-git-send-email-vladimir.medvedkin@intel.com>", "<1617738643-258635-1-git-send-email-vladimir.medvedkin@intel.com>" ], "References": [ "<1618168266-338017-1-git-send-email-vladimir.medvedkin@intel.com>", "<1617738643-258635-1-git-send-email-vladimir.medvedkin@intel.com>" ], "Subject": "[dpdk-dev] [PATCH v3 1/3] hash: add predictable RSS API", "X-BeenThere": "dev@dpdk.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "DPDK patches and discussions <dev.dpdk.org>", "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <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 <mailto:dev-request@dpdk.org?subject=subscribe>", "Errors-To": "dev-bounces@dpdk.org", "Sender": "\"dev\" <dev-bounces@dpdk.org>" }, "content": "This patch adds predictable RSS API.\nIt is based on the idea of searching partial Toeplitz hash collisions.\n\nSigned-off-by: Vladimir Medvedkin <vladimir.medvedkin@intel.com>\n---\n lib/librte_hash/meson.build | 3 +-\n lib/librte_hash/rte_thash.c | 109 +++++++++++++++++++++++++\n lib/librte_hash/rte_thash.h | 193 ++++++++++++++++++++++++++++++++++++++++++++\n lib/librte_hash/version.map | 8 ++\n 4 files changed, 312 insertions(+), 1 deletion(-)\n create mode 100644 lib/librte_hash/rte_thash.c", "diff": "diff --git a/lib/librte_hash/meson.build b/lib/librte_hash/meson.build\nindex 242859f..3546014 100644\n--- a/lib/librte_hash/meson.build\n+++ b/lib/librte_hash/meson.build\n@@ -8,6 +8,7 @@ headers = files('rte_fbk_hash.h',\n \t'rte_thash.h')\n indirect_headers += files('rte_crc_arm64.h')\n \n-sources = files('rte_cuckoo_hash.c', 'rte_fbk_hash.c')\n+sources = files('rte_cuckoo_hash.c', 'rte_fbk_hash.c', 'rte_thash.c')\n+deps += ['net']\n deps += ['ring']\n deps += ['rcu']\ndiff --git a/lib/librte_hash/rte_thash.c b/lib/librte_hash/rte_thash.c\nnew file mode 100644\nindex 0000000..1325678\n--- /dev/null\n+++ b/lib/librte_hash/rte_thash.c\n@@ -0,0 +1,109 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2021 Intel Corporation\n+ */\n+\n+#include <rte_thash.h>\n+#include <rte_tailq.h>\n+#include <rte_random.h>\n+#include <rte_memcpy.h>\n+#include <rte_errno.h>\n+#include <rte_eal.h>\n+#include <rte_eal_memconfig.h>\n+#include <rte_malloc.h>\n+\n+#define THASH_NAME_LEN\t\t64\n+\n+struct thash_lfsr {\n+\tuint32_t\tref_cnt;\n+\tuint32_t\tpoly;\n+\t/**< polynomial associated with the lfsr */\n+\tuint32_t\trev_poly;\n+\t/**< polynomial to generate the sequence in reverse direction */\n+\tuint32_t\tstate;\n+\t/**< current state of the lfsr */\n+\tuint32_t\trev_state;\n+\t/**< current state of the lfsr for reverse direction */\n+\tuint32_t\tdeg;\t/**< polynomial degree*/\n+\tuint32_t\tbits_cnt; /**< number of bits generated by lfsr*/\n+};\n+\n+struct rte_thash_subtuple_helper {\n+\tchar\tname[THASH_NAME_LEN];\t/** < Name of subtuple configuration */\n+\tLIST_ENTRY(rte_thash_subtuple_helper)\tnext;\n+\tstruct thash_lfsr\t*lfsr;\n+\tuint32_t\toffset;\t\t/** < Offset of the m-sequence */\n+\tuint32_t\tlen;\t\t/** < Length of the m-sequence */\n+\tuint32_t\ttuple_offset;\t/** < Offset in bits of the subtuple */\n+\tuint32_t\ttuple_len;\t/** < Length in bits of the subtuple */\n+\tuint32_t\tlsb_msk;\t/** < (1 << reta_sz_log) - 1 */\n+\t__extension__ uint32_t\tcompl_table[0] __rte_cache_aligned;\n+\t/** < Complementary table */\n+};\n+\n+struct rte_thash_ctx {\n+\tchar\t\tname[THASH_NAME_LEN];\n+\tLIST_HEAD(, rte_thash_subtuple_helper) head;\n+\tuint32_t\tkey_len;\t/** < Length of the NIC RSS hash key */\n+\tuint32_t\treta_sz_log;\t/** < size of the RSS ReTa in bits */\n+\tuint32_t\tsubtuples_nb;\t/** < number of subtuples */\n+\tuint32_t\tflags;\n+\tuint8_t\t\thash_key[0];\n+};\n+\n+struct rte_thash_ctx *\n+rte_thash_init_ctx(const char *name __rte_unused,\n+\tuint32_t key_len __rte_unused, uint32_t reta_sz __rte_unused,\n+\tuint8_t *key __rte_unused, uint32_t flags __rte_unused)\n+{\n+\treturn NULL;\n+}\n+\n+struct rte_thash_ctx *\n+rte_thash_find_existing(const char *name __rte_unused)\n+{\n+\treturn NULL;\n+}\n+\n+void\n+rte_thash_free_ctx(struct rte_thash_ctx *ctx __rte_unused)\n+{\n+}\n+\n+int\n+rte_thash_add_helper(struct rte_thash_ctx *ctx __rte_unused,\n+\tconst char *name __rte_unused, uint32_t len __rte_unused,\n+\tuint32_t offset __rte_unused)\n+{\n+\treturn 0;\n+}\n+\n+struct rte_thash_subtuple_helper *\n+rte_thash_get_helper(struct rte_thash_ctx *ctx __rte_unused,\n+\tconst char *name __rte_unused)\n+{\n+\treturn NULL;\n+}\n+\n+uint32_t\n+rte_thash_get_complement(struct rte_thash_subtuple_helper *h __rte_unused,\n+\tuint32_t hash __rte_unused, uint32_t desired_hash __rte_unused)\n+{\n+\treturn 0;\n+}\n+\n+const uint8_t *\n+rte_thash_get_key(struct rte_thash_ctx *ctx __rte_unused)\n+{\n+\treturn NULL;\n+}\n+\n+int\n+rte_thash_adjust_tuple(struct rte_thash_ctx *ctx __rte_unused,\n+\tstruct rte_thash_subtuple_helper *h __rte_unused,\n+\tuint8_t *tuple __rte_unused, unsigned int tuple_len __rte_unused,\n+\tuint32_t desired_value __rte_unused,\n+\tunsigned int attempts __rte_unused,\n+\trte_thash_check_tuple_t fn __rte_unused, void *userdata __rte_unused)\n+{\n+\treturn 0;\n+}\ndiff --git a/lib/librte_hash/rte_thash.h b/lib/librte_hash/rte_thash.h\nindex 061efa2..f5602ba 100644\n--- a/lib/librte_hash/rte_thash.h\n+++ b/lib/librte_hash/rte_thash.h\n@@ -1,5 +1,6 @@\n /* SPDX-License-Identifier: BSD-3-Clause\n * Copyright(c) 2015-2019 Vladimir Medvedkin <medvedkinv@gmail.com>\n+ * Copyright(c) 2021 Intel Corporation\n */\n \n #ifndef _RTE_THASH_H\n@@ -222,6 +223,198 @@ rte_softrss_be(uint32_t *input_tuple, uint32_t input_len,\n \treturn ret;\n }\n \n+/**\n+ * LFSR will ignore if generated m-sequence has more than 2^n -1 bits\n+ */\n+#define RTE_THASH_IGNORE_PERIOD_OVERFLOW\t0x1\n+/**\n+ * Generate minimal required bit (equal to ReTa LSB) sequence into\n+ * the hash_key\n+ */\n+#define RTE_THASH_MINIMAL_SEQ\t\t\t0x2\n+\n+/** @internal thash context structure. */\n+struct rte_thash_ctx;\n+/** @internal thash helper structure. */\n+struct rte_thash_subtuple_helper;\n+\n+/**\n+ * Create a new thash context.\n+ *\n+ * @param name\n+ * context name\n+ * @param key_len\n+ * length of the toeplitz hash key\n+ * @param reta_sz\n+ * logarithm of the NIC's Redirection Table (ReTa) size,\n+ * i.e. number of the LSBs if the hash used to determine\n+ * the reta entry.\n+ * @param key\n+ * pointer to the key used to init an internal key state.\n+ * Could be NULL, in this case internal key will be inited with random.\n+ * @param flags\n+ * supported flags are:\n+ * RTE_THASH_IGNORE_PERIOD_OVERFLOW\n+ * RTE_THASH_MINIMAL_SEQ\n+ * @return\n+ * A pointer to the created context on success\n+ * NULL otherwise\n+ */\n+__rte_experimental\n+struct rte_thash_ctx *\n+rte_thash_init_ctx(const char *name, uint32_t key_len, uint32_t reta_sz,\n+\tuint8_t *key, uint32_t flags);\n+\n+/**\n+ * Find an existing thash context and return a pointer to it.\n+ *\n+ * @param name\n+ * Name of the thash context\n+ * @return\n+ * Pointer to the thash context or NULL if it was not found with rte_errno\n+ * set appropriately. Possible rte_errno values include:\n+ * - ENOENT - required entry not available to return.\n+ */\n+__rte_experimental\n+struct rte_thash_ctx *\n+rte_thash_find_existing(const char *name);\n+\n+/**\n+ * Free a thash context object\n+ *\n+ * @param ctx\n+ * thash context\n+ * @return\n+ * None\n+ */\n+__rte_experimental\n+void\n+rte_thash_free_ctx(struct rte_thash_ctx *ctx);\n+\n+/**\n+ * Add a special properties to the toeplitz hash key inside a thash context.\n+ * Creates an internal helper struct which has a complementary table\n+ * to calculate toeplitz hash collisions.\n+ * This function is not multi-thread safe.\n+ *\n+ * @param ctx\n+ * thash context\n+ * @param name\n+ * name of the helper\n+ * @param len\n+ * length in bits of the target subtuple\n+ * Must be no shorter than reta_sz passed on rte_thash_init_ctx().\n+ * @param offset\n+ * offset in bits of the subtuple\n+ * @return\n+ * 0 on success\n+ * negative on error\n+ */\n+__rte_experimental\n+int\n+rte_thash_add_helper(struct rte_thash_ctx *ctx, const char *name, uint32_t len,\n+\tuint32_t offset);\n+\n+/**\n+ * Find a helper in the context by the given name\n+ *\n+ * @param ctx\n+ * thash context\n+ * @param name\n+ * name of the helper\n+ * @return\n+ * Pointer to the thash helper or NULL if it was not found.\n+ */\n+__rte_experimental\n+struct rte_thash_subtuple_helper *\n+rte_thash_get_helper(struct rte_thash_ctx *ctx, const char *name);\n+\n+/**\n+ * Get a complementary value for the subtuple to produce a\n+ * partial toeplitz hash collision. It must be XOR'ed with the\n+ * subtuple to produce the hash value with the desired hash LSB's\n+ * This function is multi-thread safe.\n+ *\n+ * @param h\n+ * Pointer to the helper struct\n+ * @param hash\n+ * toeplitz hash value calculated for the given tuple\n+ * @param desired_hash\n+ * desired hash value to find a collision for\n+ * @return\n+ * A complementary value which must be xored with the corresponding subtuple\n+ */\n+__rte_experimental\n+uint32_t\n+rte_thash_get_complement(struct rte_thash_subtuple_helper *h,\n+\tuint32_t hash, uint32_t desired_hash);\n+\n+/**\n+ * Get a pointer to the toeplitz hash contained in the context.\n+ * It changes after each addition of a helper. It should be installed to\n+ * the NIC.\n+ *\n+ * @param ctx\n+ * thash context\n+ * @return\n+ * A pointer to the toeplitz hash key\n+ */\n+__rte_experimental\n+const uint8_t *\n+rte_thash_get_key(struct rte_thash_ctx *ctx);\n+\n+/**\n+ * Function prototype for the rte_thash_adjust_tuple\n+ * to check if adjusted tuple could be used.\n+ * Generally it is some kind of lookup function to check\n+ * if adjusted tuple is already in use.\n+ *\n+ * @param userdata\n+ * Pointer to the userdata. It could be a pointer to the\n+ * table with used tuples to search.\n+ * @param tuple\n+ * Pointer to the tuple to check\n+ *\n+ * @return\n+ * 1 on success\n+ * 0 otherwise\n+ */\n+typedef int (*rte_thash_check_tuple_t)(void *userdata, uint8_t *tuple);\n+\n+/**\n+ * Adjusts tuple in the way to make Toeplitz hash has\n+ * desired least significant bits.\n+ * This function is multi-thread safe.\n+ *\n+ * @param ctx\n+ * thash context\n+ * @param h\n+ * Pointer to the helper struct\n+ * @param tuple\n+ * Pointer to the tuple to be adjusted\n+ * @param tuple_len\n+ * Length of the tuple. Must be multiple of 4.\n+ * @param desired_value\n+ * Desired value of least significant bits of the hash\n+ * @param attempts\n+ * Number of attempts to adjust tuple with fn() calling\n+ * @param fn\n+ * Callback function to check adjusted tuple. Could be NULL\n+ * @param userdata\n+ * Pointer to the userdata to be passed to fn(). Could be NULL\n+ *\n+ * @return\n+ * 0 on success\n+ * negative otherwise\n+ */\n+__rte_experimental\n+int\n+rte_thash_adjust_tuple(struct rte_thash_ctx *ctx,\n+\tstruct rte_thash_subtuple_helper *h,\n+\tuint8_t *tuple, unsigned int tuple_len,\n+\tuint32_t desired_value, unsigned int attempts,\n+\trte_thash_check_tuple_t fn, void *userdata);\n+\n #ifdef __cplusplus\n }\n #endif\ndiff --git a/lib/librte_hash/version.map b/lib/librte_hash/version.map\nindex c6d7308..17cb8aa 100644\n--- a/lib/librte_hash/version.map\n+++ b/lib/librte_hash/version.map\n@@ -32,9 +32,17 @@ DPDK_21 {\n EXPERIMENTAL {\n \tglobal:\n \n+\trte_thash_adjust_tuple;\n \trte_hash_free_key_with_position;\n \trte_hash_lookup_with_hash_bulk;\n \trte_hash_lookup_with_hash_bulk_data;\n \trte_hash_max_key_id;\n \trte_hash_rcu_qsbr_add;\n+\trte_thash_add_helper;\n+\trte_thash_find_existing;\n+\trte_thash_free_ctx;\n+\trte_thash_get_complement;\n+\trte_thash_get_helper;\n+\trte_thash_get_key;\n+\trte_thash_init_ctx;\n };\n", "prefixes": [ "v3", "1/3" ] }{ "id": 91076, "url": "