get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 115300,
    "url": "https://patches.dpdk.org/api/patches/115300/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20220819195225.1483020-5-cristian.dumitrescu@intel.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<20220819195225.1483020-5-cristian.dumitrescu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20220819195225.1483020-5-cristian.dumitrescu@intel.com",
    "date": "2022-08-19T19:52:23",
    "name": "[V2,4/6] pipeline: configure the hash function for regular tables",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "a52592d4e01004de1cc192befbd8e294c77963e3",
    "submitter": {
        "id": 19,
        "url": "https://patches.dpdk.org/api/people/19/?format=api",
        "name": "Cristian Dumitrescu",
        "email": "cristian.dumitrescu@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20220819195225.1483020-5-cristian.dumitrescu@intel.com/mbox/",
    "series": [
        {
            "id": 24366,
            "url": "https://patches.dpdk.org/api/series/24366/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=24366",
            "date": "2022-08-19T19:52:19",
            "name": "pipeline: make the hash function configurable per table",
            "version": 2,
            "mbox": "https://patches.dpdk.org/series/24366/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/115300/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/115300/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 35AAAA034C;\n\tFri, 19 Aug 2022 21:52:54 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 8D6AD427F6;\n\tFri, 19 Aug 2022 21:52:35 +0200 (CEST)",
            "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n by mails.dpdk.org (Postfix) with ESMTP id ADFE141614\n for <dev@dpdk.org>; Fri, 19 Aug 2022 21:52:31 +0200 (CEST)",
            "from orsmga007.jf.intel.com ([10.7.209.58])\n by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 19 Aug 2022 12:52:31 -0700",
            "from silpixa00400573.ir.intel.com (HELO\n silpixa00400573.ger.corp.intel.com.) ([10.237.223.157])\n by orsmga007.jf.intel.com with ESMTP; 19 Aug 2022 12:52:30 -0700"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1660938752; x=1692474752;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=vguaOuw5SvAbd26k6AzG+VohkW5iEeyA04ZXJPwHIbE=;\n b=CAEhtKQMz/zkPjqfF4yi5CyPJjL5kYCHZqJF4hmuzn+bOyKHmaXZ3fDx\n 14Fb0NgszRjWpH3VeOwMTsScYmRjbJ3uJS5sgtBB3eFh1yoAdNOU8Ubwg\n 0nLX0BdN95y2sDPKZ7swmFaqMNmGrLJ3qO4C8gHgvaR1wWtLr/KEADvtL\n 9wSGHCCGiR8lw22kHDHVjyclWKzijQ2p0aDmtajhFBO+LdA12xTY7+EDy\n QmseEtzJY4nb/VTFIBdLhv08Lg6uDWmUFw4JG8t8vENgzV58FFIp2KPTi\n VviKp33YOEEiHUrLwx9f54+2Mkn5wXeOlBjNhfIcJPTF7t7hsBrBd5Diz w==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6500,9779,10444\"; a=\"280047523\"",
            "E=Sophos;i=\"5.93,249,1654585200\"; d=\"scan'208\";a=\"280047523\"",
            "E=Sophos;i=\"5.93,248,1654585200\"; d=\"scan'208\";a=\"604695954\""
        ],
        "X-ExtLoop1": "1",
        "From": "Cristian Dumitrescu <cristian.dumitrescu@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "\"Kamalakannan R .\" <kamalakannan.r@intel.com>",
        "Subject": "[PATCH V2 4/6] pipeline: configure the hash function for regular\n tables",
        "Date": "Fri, 19 Aug 2022 19:52:23 +0000",
        "Message-Id": "<20220819195225.1483020-5-cristian.dumitrescu@intel.com>",
        "X-Mailer": "git-send-email 2.34.1",
        "In-Reply-To": "<20220819195225.1483020-1-cristian.dumitrescu@intel.com>",
        "References": "<20220818114449.1408226-1-cristian.dumitrescu@intel.com>\n <20220819195225.1483020-1-cristian.dumitrescu@intel.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "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"
    },
    "content": "Make the hash function configurable for the regular pipeline tables.\n\nSigned-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>\nSigned-off-by: Kamalakannan R. <kamalakannan.r@intel.com>\n---\n lib/pipeline/rte_swx_ctl.c               |  1 +\n lib/pipeline/rte_swx_ctl.h               |  3 ++\n lib/pipeline/rte_swx_pipeline.c          | 56 +++++++++++++++++++-----\n lib/pipeline/rte_swx_pipeline.h          | 24 +++-------\n lib/pipeline/rte_swx_pipeline_internal.h |  1 +\n lib/pipeline/rte_swx_pipeline_spec.c     | 42 +++++++++++++++++-\n lib/pipeline/rte_swx_pipeline_spec.h     |  1 +\n 7 files changed, 100 insertions(+), 28 deletions(-)",
    "diff": "diff --git a/lib/pipeline/rte_swx_ctl.c b/lib/pipeline/rte_swx_ctl.c\nindex bdbcd8f50a..b6449f5f0c 100644\n--- a/lib/pipeline/rte_swx_ctl.c\n+++ b/lib/pipeline/rte_swx_ctl.c\n@@ -272,6 +272,7 @@ table_params_get(struct rte_swx_ctl_pipeline *ctl, uint32_t table_id)\n \ttable->params.key_offset = key_offset;\n \ttable->params.key_mask0 = key_mask;\n \ttable->params.action_data_size = action_data_size;\n+\ttable->params.hash_func = table->info.hash_func;\n \ttable->params.n_keys_max = table->info.size;\n \n \ttable->mf_first = first;\ndiff --git a/lib/pipeline/rte_swx_ctl.h b/lib/pipeline/rte_swx_ctl.h\nindex 63ee479e47..0694df557a 100644\n--- a/lib/pipeline/rte_swx_ctl.h\n+++ b/lib/pipeline/rte_swx_ctl.h\n@@ -236,6 +236,9 @@ struct rte_swx_ctl_table_info {\n \t */\n \tint default_action_is_const;\n \n+\t/**  Hash function. */\n+\trte_swx_hash_func_t hash_func;\n+\n \t/** Table size parameter. */\n \tuint32_t size;\n };\ndiff --git a/lib/pipeline/rte_swx_pipeline.c b/lib/pipeline/rte_swx_pipeline.c\nindex 2cac4caa95..0b21adacbc 100644\n--- a/lib/pipeline/rte_swx_pipeline.c\n+++ b/lib/pipeline/rte_swx_pipeline.c\n@@ -7866,6 +7866,7 @@ rte_swx_pipeline_table_type_register(struct rte_swx_pipeline *p,\n static int\n table_match_type_resolve(struct rte_swx_match_field_params *fields,\n \t\t\t uint32_t n_fields,\n+\t\t\t int contiguous_fields,\n \t\t\t enum rte_swx_table_match_type *match_type)\n {\n \tuint32_t n_fields_em = 0, n_fields_lpm = 0, i;\n@@ -7884,7 +7885,7 @@ table_match_type_resolve(struct rte_swx_match_field_params *fields,\n \t    (n_fields_lpm && (n_fields_em != n_fields - 1)))\n \t\treturn -EINVAL;\n \n-\t*match_type = (n_fields_em == n_fields) ?\n+\t*match_type = ((n_fields_em == n_fields) && contiguous_fields) ?\n \t\t       RTE_SWX_TABLE_MATCH_EXACT :\n \t\t       RTE_SWX_TABLE_MATCH_WILDCARD;\n \n@@ -7894,11 +7895,12 @@ table_match_type_resolve(struct rte_swx_match_field_params *fields,\n static int\n table_match_fields_check(struct rte_swx_pipeline *p,\n \t\t\t struct rte_swx_pipeline_table_params *params,\n-\t\t\t struct header **header)\n+\t\t\t struct header **header,\n+\t\t\t int *contiguous_fields)\n {\n \tstruct header *h0 = NULL;\n \tstruct field *hf, *mf;\n-\tuint32_t *offset = NULL, i;\n+\tuint32_t *offset = NULL, *n_bits = NULL, n_fields_with_valid_next = 0, i;\n \tint status = 0;\n \n \t/* Return if no match fields. */\n@@ -7911,12 +7913,16 @@ table_match_fields_check(struct rte_swx_pipeline *p,\n \t\tif (header)\n \t\t\t*header = NULL;\n \n+\t\tif (contiguous_fields)\n+\t\t\t*contiguous_fields = 0;\n+\n \t\treturn 0;\n \t}\n \n \t/* Memory allocation. */\n \toffset = calloc(params->n_fields, sizeof(uint32_t));\n-\tif (!offset) {\n+\tn_bits = calloc(params->n_fields, sizeof(uint32_t));\n+\tif (!offset || !n_bits) {\n \t\tstatus = -ENOMEM;\n \t\tgoto end;\n \t}\n@@ -7932,6 +7938,7 @@ table_match_fields_check(struct rte_swx_pipeline *p,\n \t}\n \n \toffset[0] = h0 ? hf->offset : mf->offset;\n+\tn_bits[0] = h0 ? hf->n_bits : mf->n_bits;\n \n \tfor (i = 1; i < params->n_fields; i++)\n \t\tif (h0) {\n@@ -7944,6 +7951,7 @@ table_match_fields_check(struct rte_swx_pipeline *p,\n \t\t\t}\n \n \t\t\toffset[i] = hf->offset;\n+\t\t\tn_bits[i] = hf->n_bits;\n \t\t} else {\n \t\t\tmf = metadata_field_parse(p, params->fields[i].name);\n \t\t\tif (!mf) {\n@@ -7952,6 +7960,7 @@ table_match_fields_check(struct rte_swx_pipeline *p,\n \t\t\t}\n \n \t\t\toffset[i] = mf->offset;\n+\t\t\tn_bits[i] = mf->n_bits;\n \t\t}\n \n \t/* Check that there are no duplicated match fields. */\n@@ -7965,12 +7974,28 @@ table_match_fields_check(struct rte_swx_pipeline *p,\n \t\t\t}\n \t}\n \n+\t/* Detect if the match fields are contiguous or not. */\n+\tfor (i = 0; i < params->n_fields; i++) {\n+\t\tuint32_t offset_next = offset[i] + n_bits[i];\n+\t\tuint32_t j;\n+\n+\t\tfor (j = 0; j < params->n_fields; j++)\n+\t\t\tif (offset[j] == offset_next) {\n+\t\t\t\tn_fields_with_valid_next++;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t}\n+\n \t/* Return. */\n \tif (header)\n \t\t*header = h0;\n \n+\tif (contiguous_fields)\n+\t\t*contiguous_fields = (n_fields_with_valid_next == params->n_fields - 1) ? 1 : 0;\n+\n end:\n \tfree(offset);\n+\tfree(n_bits);\n \treturn status;\n }\n \n@@ -7982,12 +8007,13 @@ rte_swx_pipeline_table_config(struct rte_swx_pipeline *p,\n \t\t\t      const char *args,\n \t\t\t      uint32_t size)\n {\n-\tstruct table_type *type;\n+\tstruct table_type *type = NULL;\n \tstruct table *t = NULL;\n \tstruct action *default_action;\n \tstruct header *header = NULL;\n+\tstruct hash_func *hf = NULL;\n \tuint32_t action_data_size_max = 0, i;\n-\tint status = 0;\n+\tint contiguous_fields = 0, status = 0;\n \n \tCHECK(p, EINVAL);\n \n@@ -7999,7 +8025,7 @@ rte_swx_pipeline_table_config(struct rte_swx_pipeline *p,\n \tCHECK(params, EINVAL);\n \n \t/* Match checks. */\n-\tstatus = table_match_fields_check(p, params, &header);\n+\tstatus = table_match_fields_check(p, params, &header, &contiguous_fields);\n \tif (status)\n \t\treturn status;\n \n@@ -8042,6 +8068,12 @@ rte_swx_pipeline_table_config(struct rte_swx_pipeline *p,\n \tCHECK((default_action->st && params->default_action_args) || !params->default_action_args,\n \t      EINVAL);\n \n+\t/* Hash function checks. */\n+\tif (params->hash_func_name) {\n+\t\thf = hash_func_find(p, params->hash_func_name);\n+\t\tCHECK(hf, EINVAL);\n+\t}\n+\n \t/* Table type checks. */\n \tif (recommended_table_type_name)\n \t\tCHECK_NAME(recommended_table_type_name, EINVAL);\n@@ -8049,14 +8081,15 @@ rte_swx_pipeline_table_config(struct rte_swx_pipeline *p,\n \tif (params->n_fields) {\n \t\tenum rte_swx_table_match_type match_type;\n \n-\t\tstatus = table_match_type_resolve(params->fields, params->n_fields, &match_type);\n+\t\tstatus = table_match_type_resolve(params->fields,\n+\t\t\t\t\t\t  params->n_fields,\n+\t\t\t\t\t\t  contiguous_fields,\n+\t\t\t\t\t\t  &match_type);\n \t\tif (status)\n \t\t\treturn status;\n \n \t\ttype = table_type_resolve(p, recommended_table_type_name, match_type);\n \t\tCHECK(type, EINVAL);\n-\t} else {\n-\t\ttype = NULL;\n \t}\n \n \t/* Memory allocation. */\n@@ -8141,6 +8174,7 @@ rte_swx_pipeline_table_config(struct rte_swx_pipeline *p,\n \tt->default_action_is_const = params->default_action_is_const;\n \tt->action_data_size_max = action_data_size_max;\n \n+\tt->hf = hf;\n \tt->size = size;\n \tt->id = p->n_tables;\n \n@@ -8227,6 +8261,7 @@ table_params_get(struct table *table)\n \tparams->key_offset = key_offset;\n \tparams->key_mask0 = key_mask;\n \tparams->action_data_size = action_data_size;\n+\tparams->hash_func = table->hf ? table->hf->func : NULL;\n \tparams->n_keys_max = table->size;\n \n \treturn params;\n@@ -10265,6 +10300,7 @@ rte_swx_ctl_table_info_get(struct rte_swx_pipeline *p,\n \ttable->n_match_fields = t->n_fields;\n \ttable->n_actions = t->n_actions;\n \ttable->default_action_is_const = t->default_action_is_const;\n+\ttable->hash_func = t->hf ? t->hf->func : NULL;\n \ttable->size = t->size;\n \treturn 0;\n }\ndiff --git a/lib/pipeline/rte_swx_pipeline.h b/lib/pipeline/rte_swx_pipeline.h\nindex 9c629d4118..09c75180f8 100644\n--- a/lib/pipeline/rte_swx_pipeline.h\n+++ b/lib/pipeline/rte_swx_pipeline.h\n@@ -331,23 +331,6 @@ rte_swx_pipeline_extern_func_register(struct rte_swx_pipeline *p,\n  * Hash function.\n  */\n \n-/**\n- * Hash function prototype\n- *\n- * @param[in] key\n- *   Key to hash. Must be non-NULL.\n- * @param[in] length\n- *   Key length in bytes.\n- * @param[in] seed\n- *   Hash seed.\n- * @return\n- *   Hash value.\n- */\n-typedef uint32_t\n-(*rte_swx_hash_func_t)(const void *key,\n-\t\t       uint32_t length,\n-\t\t       uint32_t seed);\n-\n /**\n  * Pipeline hash function register\n  *\n@@ -699,6 +682,13 @@ struct rte_swx_pipeline_table_params {\n \t * list.\n \t */\n \tint default_action_is_const;\n+\n+\t/** Hash function name. When not set to NULL, it must point to one of\n+\t * the hash functions that were registered for the current pipeline.\n+\t * Ignored by the table implementation when not needed. When needed but\n+\t * NULL, the table implementation will select the hash function to use.\n+\t */\n+\tconst char *hash_func_name;\n };\n \n /**\ndiff --git a/lib/pipeline/rte_swx_pipeline_internal.h b/lib/pipeline/rte_swx_pipeline_internal.h\nindex 6d65b635c6..ee579c6656 100644\n--- a/lib/pipeline/rte_swx_pipeline_internal.h\n+++ b/lib/pipeline/rte_swx_pipeline_internal.h\n@@ -828,6 +828,7 @@ struct table {\n \tint *action_is_for_table_entries;\n \tint *action_is_for_default_entry;\n \n+\tstruct hash_func *hf;\n \tuint32_t size;\n \tuint32_t id;\n };\ndiff --git a/lib/pipeline/rte_swx_pipeline_spec.c b/lib/pipeline/rte_swx_pipeline_spec.c\nindex 1b4183ef55..e9fde4f241 100644\n--- a/lib/pipeline/rte_swx_pipeline_spec.c\n+++ b/lib/pipeline/rte_swx_pipeline_spec.c\n@@ -509,7 +509,7 @@ action_block_parse(struct action_spec *s,\n static void\n table_spec_free(struct table_spec *s)\n {\n-\tuintptr_t default_action_name, default_action_args;\n+\tuintptr_t default_action_name, default_action_args, hash_func_name;\n \tuint32_t i;\n \n \tif (!s)\n@@ -556,6 +556,10 @@ table_spec_free(struct table_spec *s)\n \n \ts->params.default_action_is_const = 0;\n \n+\thash_func_name = (uintptr_t)s->params.hash_func_name;\n+\tfree((void *)hash_func_name);\n+\ts->params.hash_func_name = NULL;\n+\n \tfree(s->recommended_table_type_name);\n \ts->recommended_table_type_name = NULL;\n \n@@ -935,6 +939,35 @@ table_block_parse(struct table_spec *s,\n \t\t\t\t\t\t\t    err_line,\n \t\t\t\t\t\t\t    err_msg);\n \n+\tif (!strcmp(tokens[0], \"hash\")) {\n+\t\tif (n_tokens != 2) {\n+\t\t\tif (err_line)\n+\t\t\t\t*err_line = n_lines;\n+\t\t\tif (err_msg)\n+\t\t\t\t*err_msg = \"Invalid hash statement.\";\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tif (s->params.hash_func_name) {\n+\t\t\tif (err_line)\n+\t\t\t\t*err_line = n_lines;\n+\t\t\tif (err_msg)\n+\t\t\t\t*err_msg = \"Duplicate hash statement.\";\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\ts->params.hash_func_name = strdup(tokens[1]);\n+\t\tif (!s->params.hash_func_name) {\n+\t\t\tif (err_line)\n+\t\t\t\t*err_line = n_lines;\n+\t\t\tif (err_msg)\n+\t\t\t\t*err_msg = \"Memory allocation failed.\";\n+\t\t\treturn -ENOMEM;\n+\t\t}\n+\n+\t\treturn 0;\n+\t}\n+\n \tif (!strcmp(tokens[0], \"instanceof\")) {\n \t\tif (n_tokens != 2) {\n \t\t\tif (err_line)\n@@ -2419,6 +2452,13 @@ pipeline_spec_codegen(FILE *f,\n \n \t\tfprintf(f, \"\\t\\t\\t.default_action_is_const = %d,\\n\",\n \t\t\ttable_spec->params.default_action_is_const);\n+\n+\t\tif (table_spec->params.hash_func_name)\n+\t\t\tfprintf(f, \"\\t\\t\\t.hash_func_name = \\\"%s\\\",\\n\",\n+\t\t\t\ttable_spec->params.hash_func_name);\n+\t\telse\n+\t\t\tfprintf(f, \"\\t\\t\\t.hash_func_name = NULL,\\n\");\n+\n \t\tfprintf(f, \"\\t\\t},\\n\");\n \n \t\tif (table_spec->recommended_table_type_name)\ndiff --git a/lib/pipeline/rte_swx_pipeline_spec.h b/lib/pipeline/rte_swx_pipeline_spec.h\nindex 62ac4ecfc4..dbe1b40adc 100644\n--- a/lib/pipeline/rte_swx_pipeline_spec.h\n+++ b/lib/pipeline/rte_swx_pipeline_spec.h\n@@ -88,6 +88,7 @@ struct action_spec {\n  *\t\t...\n  *\t}\n  *\tdefault_action ACTION_NAME args none | ARG0_NAME ARG0_VALUE ... [ const ]\n+ *\thash HASH_FUNCTION_NAME\n  *\tinstanceof TABLE_TYPE_NAME\n  *\tpragma ARGS\n  *\tsize SIZE\n",
    "prefixes": [
        "V2",
        "4/6"
    ]
}