get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 41673,
    "url": "http://patchwork.dpdk.org/api/patches/41673/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20180627145525.8659-1-nelio.laranjeiro@6wind.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.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": "<20180627145525.8659-1-nelio.laranjeiro@6wind.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20180627145525.8659-1-nelio.laranjeiro@6wind.com",
    "date": "2018-06-27T14:55:25",
    "name": "[v4] ethdev: add flow API to expand RSS flows",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "78fe1352d1c26e22e20b8ffe3f762d91c49bb9ec",
    "submitter": {
        "id": 243,
        "url": "http://patchwork.dpdk.org/api/people/243/?format=api",
        "name": "Nélio Laranjeiro",
        "email": "nelio.laranjeiro@6wind.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patchwork.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20180627145525.8659-1-nelio.laranjeiro@6wind.com/mbox/",
    "series": [
        {
            "id": 267,
            "url": "http://patchwork.dpdk.org/api/series/267/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=267",
            "date": "2018-06-27T14:55:25",
            "name": "[v4] ethdev: add flow API to expand RSS flows",
            "version": 4,
            "mbox": "http://patchwork.dpdk.org/series/267/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/41673/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/41673/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 D0D861BECD;\n\tWed, 27 Jun 2018 16:55:07 +0200 (CEST)",
            "from mail-wm0-f65.google.com (mail-wm0-f65.google.com\n\t[74.125.82.65]) by dpdk.org (Postfix) with ESMTP id 1EB5D1BF64\n\tfor <dev@dpdk.org>; Wed, 27 Jun 2018 16:55:06 +0200 (CEST)",
            "by mail-wm0-f65.google.com with SMTP id i139-v6so6147899wmf.4\n\tfor <dev@dpdk.org>; Wed, 27 Jun 2018 07:55:06 -0700 (PDT)",
            "from laranjeiro-vm.dev.6wind.com\n\t(host.78.145.23.62.rev.coltfrance.com. [62.23.145.78])\n\tby smtp.gmail.com with ESMTPSA id\n\td1-v6sm2194359wrm.9.2018.06.27.07.55.04\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tWed, 27 Jun 2018 07:55:04 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=6wind-com.20150623.gappssmtp.com; s=20150623;\n\th=from:to:subject:date:message-id:in-reply-to:references;\n\tbh=j4EJUMJzt9NDT78V+zsXY39TIFa6hRXHPmYPvV86vEk=;\n\tb=B9yLr4opidsc2qTtNtbCGezerpRfYWJsNoHI8dU4PhMGK3C765yubU0p7Kaofxsmcw\n\tidki8Q7iJDfxsruIz5ksdWIBJTJiQNaIMZ/zAUw/7WVeryNi1vBFDXddckJiKsrq6/0Q\n\tZlNFLMZms6Ag4f3zOwGGw/g0xylsYgijS3l7BR2UDL4D7L/kURzLSMmune0NTDevEGgN\n\t4ZqnW6Hgj7T2iHNMJo5N4g77B3rtknMhBjZ01aU882IOjKg68YH8t/3pS/Ds+OOMhSMG\n\tx8OvVyjTSQ3JPiVy6m5+B2TvServV1g02alkwTcfgOea1Ijyzw8upOQY9HAKySTCFQtm\n\tT5tg==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=j4EJUMJzt9NDT78V+zsXY39TIFa6hRXHPmYPvV86vEk=;\n\tb=IrLbYQEEzAkIxKKB3uElJvbuJBxuX8zAlczRQSINFc5KCOtmno5KbHcp8S93TP7d3R\n\tHxcclaBMIazoQk+CSmDc6RRcWeLCSLDbgGU/qNAdNuqq4Gsj8MOwt3LLewVTGecqwq1U\n\t81LmUl82/6sbYw5LaNLpbvdpg7qijpxgjxhTDf1EbKRYD5i2tMPUYEVHgzcgiXOSETQE\n\tyfQtdwKv0whR1TnRNo8SmCrkX489jq01OCf3SEmGBs/aJQNYW2qDud89zsl6Xi6bhKaM\n\tetI/aprCAcO6ORmz+Co5a6BZ7XRad0VVbceWHKGKHkdwr1FzJzvnLa7s2l+W5uv3Ep4n\n\tZDtg==",
        "X-Gm-Message-State": "APt69E3jdMjEp+QF3tVDABhI07yKwhLj+YKXNID+NQdPRouIVvxocKh1\n\tUP7tDkhlfSEQUkogJNISk//JIz2zFQ==",
        "X-Google-Smtp-Source": "AAOMgpfAxfiQ5f52Cc8fO5ffs4hSvX5krYo8QPKbnx1MimxDbl2YwOvTMo8lJU8YCbgsfQ2i4vXzJA==",
        "X-Received": "by 2002:a1c:ae94:: with SMTP id\n\tx142-v6mr5063811wme.22.1530111305530; \n\tWed, 27 Jun 2018 07:55:05 -0700 (PDT)",
        "From": "Nelio Laranjeiro <nelio.laranjeiro@6wind.com>",
        "To": "dev@dpdk.org,\n\tAdrien Mazarguil <adrien.mazarguil@6wind.com>",
        "Date": "Wed, 27 Jun 2018 16:55:25 +0200",
        "Message-Id": "<20180627145525.8659-1-nelio.laranjeiro@6wind.com>",
        "X-Mailer": "git-send-email 2.18.0",
        "In-Reply-To": "<15e22f72e9b4c56e79809c413ce3001e4f6067d8.1529565844.git.nelio.laranjeiro@6wind.com>",
        "References": "<15e22f72e9b4c56e79809c413ce3001e4f6067d8.1529565844.git.nelio.laranjeiro@6wind.com>",
        "Subject": "[dpdk-dev] [PATCH v4] ethdev: add flow API to expand RSS flows",
        "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": "Introduce an helper for PMD to expand easily flows items list with RSS\naction into multiple flow items lists with priority information.\n\nFor instance a user items list being \"eth / end\" with rss action types\n\"ipv4-udp ipv6-udp end\" needs to be expanded into three items lists:\n\n - eth\n - eth / ipv4 / udp\n - eth / ipv6 / udp\n\nto match the user request.  Some drivers are unable to reach such\nrequest without this expansion, this API is there to help those.\nOnly PMD should use such API for their internal cooking, the application\nwill still handle a single flow.\n\nSigned-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>\n\n---\n\nChanges in v4:\n\n- Replace the expanded algorithm with a graph to support also tunnel\npattern matching.\n\nChanges in v3:\n\n- Fix a segmentation fault due to an uninitialized pointer.\n\nChanges in v2:\n\n- Fix expansion for UDP/TCP layers where L3 may not be in the original\n  items list and thus is missing in the expansion.\n- Fix size verification for some layers causing a segfault\n---\n lib/librte_ethdev/rte_flow.c        | 105 ++++++++++++++++++++++++++++\n lib/librte_ethdev/rte_flow_driver.h |  48 +++++++++++++\n 2 files changed, 153 insertions(+)",
    "diff": "diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c\nindex 2e87e59f3..96af18e16 100644\n--- a/lib/librte_ethdev/rte_flow.c\n+++ b/lib/librte_ethdev/rte_flow.c\n@@ -526,3 +526,108 @@ rte_flow_copy(struct rte_flow_desc *desc, size_t len,\n \t}\n \treturn 0;\n }\n+\n+int\n+rte_flow_expand_rss(struct rte_flow_expand_rss *buf, size_t size,\n+\t\t    const struct rte_flow_item *pat, uint64_t types,\n+\t\t    const struct rte_flow_expand_node nodes[],\n+\t\t    const int node_entry_index)\n+{\n+\tconst int elt_n = 8;\n+\tconst struct rte_flow_item *item;\n+\tconst struct rte_flow_expand_node *node = &nodes[node_entry_index];\n+\tconst int *next_node;\n+\tconst int *stack[elt_n];\n+\tint stack_n = 0;\n+\tstruct rte_flow_item flow_items[elt_n];\n+\tunsigned int i;\n+\tsize_t lsize;\n+\tsize_t user_pattern_size = 0;\n+\tvoid *addr = NULL;\n+\n+\tlsize = sizeof(*buf) +\n+\t\t/* Size for the list of patterns. */\n+\t\tsizeof(*buf->patterns) +\n+\t\tRTE_ALIGN_CEIL(elt_n * sizeof(*item), sizeof(void *)) +\n+\t\t/* Size for priorities. */\n+\t\tsizeof(*buf->priority) +\n+\t\tRTE_ALIGN_CEIL(elt_n * sizeof(uint32_t), sizeof(void *));\n+\tif (lsize <= size) {\n+\t\tbuf->priority = (void *)(buf + 1);\n+\t\tbuf->priority[0] = 0;\n+\t\tbuf->patterns = (void *)&buf->priority[elt_n];\n+\t\tbuf->patterns[0] = (void *)&buf->patterns[elt_n];\n+\t\tbuf->entries = 0;\n+\t\taddr = buf->patterns[0];\n+\t}\n+\tfor (item = pat; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {\n+\t\tconst struct rte_flow_expand_node *next = NULL;\n+\n+\t\tfor (i = 0; node->next && node->next[i]; ++i) {\n+\t\t\tnext = &nodes[node->next[i]];\n+\t\t\tif (next->type == item->type)\n+\t\t\t\tbreak;\n+\t\t}\n+\t\tif (next)\n+\t\t\tnode = next;\n+\t\tuser_pattern_size += sizeof(*item);\n+\t}\n+\tuser_pattern_size += sizeof(*item); /**< Handle END item. */\n+\tlsize += user_pattern_size;\n+\t/* Copy the user pattern in the first entry of the buffer. */\n+\tif (lsize <= size) {\n+\t\trte_memcpy(addr, pat, user_pattern_size);\n+\t\taddr = (void *)(((uintptr_t)addr) + user_pattern_size);\n+\t\tbuf->priority[buf->entries] = 0;\n+\t\tbuf->entries = 1;\n+\t}\n+\t/* Start expanding. */\n+\tmemset(flow_items, 0, sizeof(flow_items));\n+\tuser_pattern_size -= sizeof(*item);\n+\tnext_node = node->next;\n+\tstack[stack_n] = next_node;\n+\tnode = next_node ? &nodes[*next_node] : NULL;\n+\twhile (node) {\n+\t\tflow_items[stack_n].type = node->type;\n+\t\tif ((node->rss_types & types) == node->rss_types) {\n+\t\t\t/*\n+\t\t\t * compute the number of items to copy from the\n+\t\t\t * expansion and copy it.\n+\t\t\t * When the stack_n is 0, there are 1 element in it,\n+\t\t\t * plus the addition END item.\n+\t\t\t */\n+\t\t\tint elt = stack_n + 2;\n+\n+\t\t\tflow_items[stack_n + 1].type = RTE_FLOW_ITEM_TYPE_END;\n+\t\t\tlsize += elt * sizeof(*item) + user_pattern_size;\n+\t\t\tif (lsize <= size) {\n+\t\t\t\tsize_t n = elt * sizeof(*item);\n+\n+\t\t\t\tbuf->priority[buf->entries] = stack_n + 1;\n+\t\t\t\tbuf->patterns[buf->entries++] = addr;\n+\t\t\t\trte_memcpy(addr, buf->patterns[0],\n+\t\t\t\t\t   user_pattern_size);\n+\t\t\t\taddr = (void *)(((uintptr_t)addr) +\n+\t\t\t\t\t\tuser_pattern_size);\n+\t\t\t\trte_memcpy(addr, flow_items, n);\n+\t\t\t\taddr = (void *) (((uintptr_t)addr) + n);\n+\t\t\t}\n+\t\t}\n+\t\t/* Go deeper. */\n+\t\tif (node->next) {\n+\t\t\tnext_node = node->next;\n+\t\t\tstack[++stack_n] = next_node;\n+\t\t} else if (*(next_node + 1)) {\n+\t\t\t/* Follow up with the next possibility. */\n+\t\t\t++next_node;\n+\t\t} else {\n+\t\t\t/* Move to the next path. */\n+\t\t\tif (stack_n)\n+\t\t\t\tnext_node = stack[--stack_n];\n+\t\t\tnext_node++;\n+\t\t\tstack[stack_n] = next_node;\n+\t\t}\n+\t\tnode = *next_node ? &nodes[*next_node] : NULL;\n+\t};\n+\treturn lsize;\n+}\ndiff --git a/lib/librte_ethdev/rte_flow_driver.h b/lib/librte_ethdev/rte_flow_driver.h\nindex 1c90c600d..538b46e54 100644\n--- a/lib/librte_ethdev/rte_flow_driver.h\n+++ b/lib/librte_ethdev/rte_flow_driver.h\n@@ -114,6 +114,54 @@ struct rte_flow_ops {\n const struct rte_flow_ops *\n rte_flow_ops_get(uint16_t port_id, struct rte_flow_error *error);\n \n+/** Macro to create the expansion graph. */\n+#define RTE_FLOW_EXPAND_ITEMS(...) \\\n+\t(const int []){ \\\n+\t\t__VA_ARGS__, 0, \\\n+\t}\n+\n+/** structure to generate the expansion graph. */\n+struct rte_flow_expand_node {\n+\tconst int *const next; /**< list of items finalised by 0. */\n+\tconst enum rte_flow_item_type type; /**< Item type to add. */\n+\tuint64_t rss_types; /**< RSS bit-field value. */\n+};\n+\n+/**\n+ * Expansion structure for RSS flows.\n+ */\n+struct rte_flow_expand_rss {\n+\tuint32_t entries; /**< Number of entries in the following arrays. */\n+\tstruct rte_flow_item **patterns; /**< Expanded pattern array. */\n+\tuint32_t *priority; /**< Priority offset for each expansion. */\n+};\n+\n+/**\n+ * Expand RSS flows into several possible flows according to the RSS hash\n+ * fields requested and the driver capabilities.\n+ *\n+ * @param[in,out] buf\n+ *   Buffer to store the result expansion.\n+ * @param[in] size\n+ *   Size in octets of the buffer.\n+ * @param[in] pat\n+ *   User flow pattern.\n+ * @param[in] types\n+ *   RSS types expected (see ETH_RSS_*).\n+ * @param[in] nodes.\n+ *   Expansion graph of possibilities for the RSS.\n+ * @param[in] node_entry_index\n+ *   The index in the \\p nodes array as start point.\n+ *\n+ * @return\n+ *   The size in octets used to expand.\n+ */\n+int\n+rte_flow_expand_rss(struct rte_flow_expand_rss *buf, size_t size,\n+\t\t    const struct rte_flow_item *pat, uint64_t types,\n+\t\t    const struct rte_flow_expand_node nodes[],\n+\t\t    const int node_entry_index);\n+\n #ifdef __cplusplus\n }\n #endif\n",
    "prefixes": [
        "v4"
    ]
}