get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 8470,
    "url": "http://patches.dpdk.org/api/patches/8470/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1446231319-8185-7-git-send-email-adrien.mazarguil@6wind.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": "<1446231319-8185-7-git-send-email-adrien.mazarguil@6wind.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1446231319-8185-7-git-send-email-adrien.mazarguil@6wind.com",
    "date": "2015-10-30T18:55:09",
    "name": "[dpdk-dev,v2,06/16] mlx5: define specific flow steering rules for each hash RX QP",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "3b3bdddebd148583ab364f935167ffd1bcecb049",
    "submitter": {
        "id": 165,
        "url": "http://patches.dpdk.org/api/people/165/?format=api",
        "name": "Adrien Mazarguil",
        "email": "adrien.mazarguil@6wind.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1446231319-8185-7-git-send-email-adrien.mazarguil@6wind.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/8470/comments/",
    "check": "pending",
    "checks": "http://patches.dpdk.org/api/patches/8470/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 06C069370;\n\tFri, 30 Oct 2015 19:56:17 +0100 (CET)",
            "from mail-wm0-f47.google.com (mail-wm0-f47.google.com\n\t[74.125.82.47]) by dpdk.org (Postfix) with ESMTP id 0CBB89253\n\tfor <dev@dpdk.org>; Fri, 30 Oct 2015 19:56:01 +0100 (CET)",
            "by wmff134 with SMTP id f134so18769999wmf.0\n\tfor <dev@dpdk.org>; Fri, 30 Oct 2015 11:56:01 -0700 (PDT)",
            "from 6wind.com (guy78-3-82-239-227-177.fbx.proxad.net.\n\t[82.239.227.177]) by smtp.gmail.com with ESMTPSA id\n\tgl4sm8369510wjd.49.2015.10.30.11.55.59\n\t(version=TLSv1.2 cipher=RC4-SHA bits=128/128);\n\tFri, 30 Oct 2015 11:56:00 -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:cc:subject:date:message-id:in-reply-to:references;\n\tbh=DHho7DTtig6e25Yog91JJExjDkrHek/SPRDUiAF7qKk=;\n\tb=mhmRKkY71wbfBeRSJISToQgwHNkWDmjiweGjZG22zFD0UUC60waMChcbVYl52ByUlk\n\taFNf8YxQugK15G1r6vSYSk/Ju4Av20XzahHwic37KY4/FMPP4BkbG8eBgRv2rX6uH5sF\n\t8bdR4a9Dabqt8drPQQLoENXI0s4xQNDzLP7Q6R3TyShIcVWRM3UA9fSXMyqCxV14vtEI\n\tQk4kE1ueTwqw+NOm/AyPB2J+gc/LerOQD0wDa8n8r2zOrFK+yR2afOWq12l+oRbSGF2y\n\tqH2XmQvu+EKjDBWx0k/dmkKQDxtFd2Q/7RnCMZGsnMuKFybdk12XnujoD7M7gsLN/GaB\n\tAOkA==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20130820;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=DHho7DTtig6e25Yog91JJExjDkrHek/SPRDUiAF7qKk=;\n\tb=lTR/oZ0bl4qB7ufNnHuZnzOU7DmFINkGtAgEAparU1WQ4OLKpVzMxjpxLgL0yMna/I\n\tOVbv3bxJFWp7jJhtyrtqQe8pMnCZNhzDx/CiZk0yktu5ksjX65YcE5kIWc/Z9k/Fuk7G\n\tyUDH1DTG8Pzb60GxGnigPvVZkeopuuxO9nA2SoPnQBVye/79FI8MOofGAFihtMCBzVlK\n\tr35ZELYLmFWWtEk1W0lH8MnRSqki432YyVk2G/FMusvM/iaZivj0bAClNpsznHHM8Vdj\n\t2w/ngCygMbQiGDeafFVotnfRsHvwzSSFjGBzPy7iz2Bn3IIMlFa4ZBZcbQVDXchDYhnK\n\t2LMw==",
        "X-Gm-Message-State": "ALoCoQm64Iv8n4+lXiIFjkLjzIBLL0JI/7vN9oGAXY+2h5eTbGMI6GXx6An90IeLDgiDtMdcsjhC",
        "X-Received": "by 10.28.137.211 with SMTP id l202mr5315288wmd.90.1446231360920; \n\tFri, 30 Oct 2015 11:56:00 -0700 (PDT)",
        "From": "Adrien Mazarguil <adrien.mazarguil@6wind.com>",
        "To": "dev@dpdk.org",
        "Date": "Fri, 30 Oct 2015 19:55:09 +0100",
        "Message-Id": "<1446231319-8185-7-git-send-email-adrien.mazarguil@6wind.com>",
        "X-Mailer": "git-send-email 2.1.0",
        "In-Reply-To": "<1446231319-8185-1-git-send-email-adrien.mazarguil@6wind.com>",
        "References": "<1444067692-29645-1-git-send-email-adrien.mazarguil@6wind.com>\n\t<1446231319-8185-1-git-send-email-adrien.mazarguil@6wind.com>",
        "Subject": "[dpdk-dev] [PATCH v2 06/16] mlx5: define specific flow steering\n\trules for each hash RX QP",
        "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": "From: Olga Shern <olgas@mellanox.com>\n\nAll hash RX QPs currently use the same flow steering rule (L2 MAC filtering)\nregardless of their type (TCP, UDP, IPv4, IPv6), which prevents them from\nbeing dispatched properly. This is fixed by adding flow information to the\nhash RX queue initialization data and generating specific flow steering\nrules for each of them.\n\nSigned-off-by: Olga Shern <olgas@mellanox.com>\nSigned-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>\nSigned-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>\n---\n drivers/net/mlx5/mlx5_mac.c  | 19 ++++-------\n drivers/net/mlx5/mlx5_rxq.c  | 77 ++++++++++++++++++++++++++++++++++++++++++++\n drivers/net/mlx5/mlx5_rxtx.h | 21 ++++++++++++\n 3 files changed, 105 insertions(+), 12 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5_mac.c b/drivers/net/mlx5/mlx5_mac.c\nindex b580494..d3ab5b9 100644\n--- a/drivers/net/mlx5/mlx5_mac.c\n+++ b/drivers/net/mlx5/mlx5_mac.c\n@@ -242,12 +242,9 @@ hash_rxq_add_mac_flow(struct hash_rxq *hash_rxq, unsigned int mac_index,\n \tconst uint8_t (*mac)[ETHER_ADDR_LEN] =\n \t\t\t(const uint8_t (*)[ETHER_ADDR_LEN])\n \t\t\tpriv->mac[mac_index].addr_bytes;\n-\tstruct __attribute__((packed)) {\n-\t\tstruct ibv_flow_attr attr;\n-\t\tstruct ibv_flow_spec_eth spec;\n-\t} data;\n-\tstruct ibv_flow_attr *attr = &data.attr;\n-\tstruct ibv_flow_spec_eth *spec = &data.spec;\n+\tFLOW_ATTR_SPEC_ETH(data, hash_rxq_flow_attr(hash_rxq, NULL, 0));\n+\tstruct ibv_flow_attr *attr = &data->attr;\n+\tstruct ibv_flow_spec_eth *spec = &data->spec;\n \tunsigned int vlan_enabled = !!priv->vlan_filter_n;\n \tunsigned int vlan_id = priv->vlan_filter[vlan_index];\n \n@@ -260,12 +257,10 @@ hash_rxq_add_mac_flow(struct hash_rxq *hash_rxq, unsigned int mac_index,\n \t * This layout is expected by libibverbs.\n \t */\n \tassert(((uint8_t *)attr + sizeof(*attr)) == (uint8_t *)spec);\n-\t*attr = (struct ibv_flow_attr){\n-\t\t.type = IBV_FLOW_ATTR_NORMAL,\n-\t\t.num_of_specs = 1,\n-\t\t.port = priv->port,\n-\t\t.flags = 0\n-\t};\n+\thash_rxq_flow_attr(hash_rxq, attr, sizeof(data));\n+\t/* The first specification must be Ethernet. */\n+\tassert(spec->type == IBV_FLOW_SPEC_ETH);\n+\tassert(spec->size == sizeof(*spec));\n \t*spec = (struct ibv_flow_spec_eth){\n \t\t.type = IBV_FLOW_SPEC_ETH,\n \t\t.size = sizeof(*spec),\ndiff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c\nindex 41f8811..1e15ff9 100644\n--- a/drivers/net/mlx5/mlx5_rxq.c\n+++ b/drivers/net/mlx5/mlx5_rxq.c\n@@ -71,19 +71,43 @@ static const struct hash_rxq_init hash_rxq_init[] = {\n \t\t\t\tIBV_EXP_RX_HASH_DST_IPV4 |\n \t\t\t\tIBV_EXP_RX_HASH_SRC_PORT_TCP |\n \t\t\t\tIBV_EXP_RX_HASH_DST_PORT_TCP),\n+\t\t.flow_priority = 0,\n+\t\t.flow_spec.tcp_udp = {\n+\t\t\t.type = IBV_FLOW_SPEC_TCP,\n+\t\t\t.size = sizeof(hash_rxq_init[0].flow_spec.tcp_udp),\n+\t\t},\n+\t\t.underlayer = &hash_rxq_init[HASH_RXQ_IPV4],\n \t},\n \t[HASH_RXQ_UDPV4] = {\n \t\t.hash_fields = (IBV_EXP_RX_HASH_SRC_IPV4 |\n \t\t\t\tIBV_EXP_RX_HASH_DST_IPV4 |\n \t\t\t\tIBV_EXP_RX_HASH_SRC_PORT_UDP |\n \t\t\t\tIBV_EXP_RX_HASH_DST_PORT_UDP),\n+\t\t.flow_priority = 0,\n+\t\t.flow_spec.tcp_udp = {\n+\t\t\t.type = IBV_FLOW_SPEC_UDP,\n+\t\t\t.size = sizeof(hash_rxq_init[0].flow_spec.tcp_udp),\n+\t\t},\n+\t\t.underlayer = &hash_rxq_init[HASH_RXQ_IPV4],\n \t},\n \t[HASH_RXQ_IPV4] = {\n \t\t.hash_fields = (IBV_EXP_RX_HASH_SRC_IPV4 |\n \t\t\t\tIBV_EXP_RX_HASH_DST_IPV4),\n+\t\t.flow_priority = 1,\n+\t\t.flow_spec.ipv4 = {\n+\t\t\t.type = IBV_FLOW_SPEC_IPV4,\n+\t\t\t.size = sizeof(hash_rxq_init[0].flow_spec.ipv4),\n+\t\t},\n+\t\t.underlayer = &hash_rxq_init[HASH_RXQ_ETH],\n \t},\n \t[HASH_RXQ_ETH] = {\n \t\t.hash_fields = 0,\n+\t\t.flow_priority = 2,\n+\t\t.flow_spec.eth = {\n+\t\t\t.type = IBV_FLOW_SPEC_ETH,\n+\t\t\t.size = sizeof(hash_rxq_init[0].flow_spec.eth),\n+\t\t},\n+\t\t.underlayer = NULL,\n \t},\n };\n \n@@ -125,6 +149,59 @@ static uint8_t hash_rxq_default_key[] = {\n };\n \n /**\n+ * Populate flow steering rule for a given hash RX queue type using\n+ * information from hash_rxq_init[]. Nothing is written to flow_attr when\n+ * flow_attr_size is not large enough, but the required size is still returned.\n+ *\n+ * @param[in] hash_rxq\n+ *   Pointer to hash RX queue.\n+ * @param[out] flow_attr\n+ *   Pointer to flow attribute structure to fill. Note that the allocated\n+ *   area must be larger and large enough to hold all flow specifications.\n+ * @param flow_attr_size\n+ *   Entire size of flow_attr and trailing room for flow specifications.\n+ *\n+ * @return\n+ *   Total size of the flow attribute buffer. No errors are defined.\n+ */\n+size_t\n+hash_rxq_flow_attr(const struct hash_rxq *hash_rxq,\n+\t\t   struct ibv_flow_attr *flow_attr,\n+\t\t   size_t flow_attr_size)\n+{\n+\tsize_t offset = sizeof(*flow_attr);\n+\tenum hash_rxq_type type = hash_rxq->type;\n+\tconst struct hash_rxq_init *init = &hash_rxq_init[type];\n+\n+\tassert(hash_rxq->priv != NULL);\n+\tassert((size_t)type < RTE_DIM(hash_rxq_init));\n+\tdo {\n+\t\toffset += init->flow_spec.hdr.size;\n+\t\tinit = init->underlayer;\n+\t} while (init != NULL);\n+\tif (offset > flow_attr_size)\n+\t\treturn offset;\n+\tflow_attr_size = offset;\n+\tinit = &hash_rxq_init[type];\n+\t*flow_attr = (struct ibv_flow_attr){\n+\t\t.type = IBV_FLOW_ATTR_NORMAL,\n+\t\t.priority = init->flow_priority,\n+\t\t.num_of_specs = 0,\n+\t\t.port = hash_rxq->priv->port,\n+\t\t.flags = 0,\n+\t};\n+\tdo {\n+\t\toffset -= init->flow_spec.hdr.size;\n+\t\tmemcpy((void *)((uintptr_t)flow_attr + offset),\n+\t\t       &init->flow_spec,\n+\t\t       init->flow_spec.hdr.size);\n+\t\t++flow_attr->num_of_specs;\n+\t\tinit = init->underlayer;\n+\t} while (init != NULL);\n+\treturn flow_attr_size;\n+}\n+\n+/**\n  * Return nearest power of two above input value.\n  *\n  * @param v\ndiff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h\nindex f89d3ec..c31fa8e 100644\n--- a/drivers/net/mlx5/mlx5_rxtx.h\n+++ b/drivers/net/mlx5/mlx5_rxtx.h\n@@ -34,6 +34,7 @@\n #ifndef RTE_PMD_MLX5_RXTX_H_\n #define RTE_PMD_MLX5_RXTX_H_\n \n+#include <stddef.h>\n #include <stdint.h>\n \n /* Verbs header. */\n@@ -126,9 +127,27 @@ enum hash_rxq_type {\n \tHASH_RXQ_ETH,\n };\n \n+/* Flow structure with Ethernet specification. It is packed to prevent padding\n+ * between attr and spec as this layout is expected by libibverbs. */\n+struct flow_attr_spec_eth {\n+\tstruct ibv_flow_attr attr;\n+\tstruct ibv_flow_spec_eth spec;\n+} __attribute__((packed));\n+\n+/* Define a struct flow_attr_spec_eth object as an array of at least\n+ * \"size\" bytes. Room after the first index is normally used to store\n+ * extra flow specifications. */\n+#define FLOW_ATTR_SPEC_ETH(name, size) \\\n+\tstruct flow_attr_spec_eth name \\\n+\t\t[((size) / sizeof(struct flow_attr_spec_eth)) + \\\n+\t\t !!((size) % sizeof(struct flow_attr_spec_eth))]\n+\n /* Initialization data for hash RX queue. */\n struct hash_rxq_init {\n \tuint64_t hash_fields; /* Fields that participate in the hash. */\n+\tunsigned int flow_priority; /* Flow priority to use. */\n+\tstruct ibv_flow_spec flow_spec; /* Flow specification template. */\n+\tconst struct hash_rxq_init *underlayer; /* Pointer to underlayer. */\n };\n \n /* Initialization data for indirection table. */\n@@ -193,6 +212,8 @@ struct txq {\n \n /* mlx5_rxq.c */\n \n+size_t hash_rxq_flow_attr(const struct hash_rxq *, struct ibv_flow_attr *,\n+\t\t\t  size_t);\n int priv_create_hash_rxqs(struct priv *);\n void priv_destroy_hash_rxqs(struct priv *);\n void rxq_cleanup(struct rxq *);\n",
    "prefixes": [
        "dpdk-dev",
        "v2",
        "06/16"
    ]
}