get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 91076,
    "url": "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"
    ]
}