get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 28214,
    "url": "http://patches.dpdk.org/api/patches/28214/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/2e35fbe91b57ab2755f0a5b10664691eadc79a93.1504252977.git.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": "<2e35fbe91b57ab2755f0a5b10664691eadc79a93.1504252977.git.adrien.mazarguil@6wind.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/2e35fbe91b57ab2755f0a5b10664691eadc79a93.1504252977.git.adrien.mazarguil@6wind.com",
    "date": "2017-09-01T08:06:30",
    "name": "[dpdk-dev,v2,15/51] net/mlx4: revert RSS parent queue refactoring",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "450ef1e3d9c1bb5c196e7a6c0de64a52ca9afd11",
    "submitter": {
        "id": 165,
        "url": "http://patches.dpdk.org/api/people/165/?format=api",
        "name": "Adrien Mazarguil",
        "email": "adrien.mazarguil@6wind.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/2e35fbe91b57ab2755f0a5b10664691eadc79a93.1504252977.git.adrien.mazarguil@6wind.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/28214/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/28214/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 EFE198CEE;\n\tFri,  1 Sep 2017 10:07:45 +0200 (CEST)",
            "from mail-wr0-f172.google.com (mail-wr0-f172.google.com\n\t[209.85.128.172]) by dpdk.org (Postfix) with ESMTP id C4B7B7D86\n\tfor <dev@dpdk.org>; Fri,  1 Sep 2017 10:07:43 +0200 (CEST)",
            "by mail-wr0-f172.google.com with SMTP id z91so4525699wrc.1\n\tfor <dev@dpdk.org>; Fri, 01 Sep 2017 01:07:43 -0700 (PDT)",
            "from 6wind.com (host.78.145.23.62.rev.coltfrance.com.\n\t[62.23.145.78]) by smtp.gmail.com with ESMTPSA id\n\tm15sm1377557wrb.86.2017.09.01.01.07.41 for <dev@dpdk.org>\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tFri, 01 Sep 2017 01:07:41 -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=g5rNpyM5ptpy8Y7CKUUdbGTyTPQ8HfDyrnt7OSAjxZ0=;\n\tb=eOfUgtsqc6oQqe1F0P0TJ59c5alNm/tKrFt/gL2QYSyL+eWwdnCM8p2kBdQN+JLU8L\n\tg0N4R2d2lAQLYaZQD27fZOgz6Kr3xwONMNDO3r4SOhkI7wQZaAraIMpOpeDI5s1crSF5\n\todDf8Hvgffs1kNJ+hXADPD1DYhTRjpOgm4ZLPbOeVHHiy2uLMVXPjoTz2EsQDmEbFJz0\n\tceZwOzS+Sa2fo9axQjwXyhblRXo3QfLAnS1G6gjDo2lfxVwewp8FrG1qA6JG9JBBoJ+4\n\tfZA78pM9S1Tkf7R9PV8OddQx6WhDQKdRRQ699F/Bw/9XG/8mOZQftNIEvLOZiyJJUKQ2\n\tE2NA==",
        "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=g5rNpyM5ptpy8Y7CKUUdbGTyTPQ8HfDyrnt7OSAjxZ0=;\n\tb=PSJNMHrV/VZZAbK908IzQ83dlDEKp2DDUbv9ELjKS6lCVb9Gk3dZKDfHbE9DaTwEUq\n\topSH/p1HD2Q8Ju25QOD8f046UZ6tUsIJFUh+v3eTlsUhKv+aCz8I+2RMcHkzEOsAIH6P\n\tpEOiqLTdWv0PeRBxJvX2nOpCHLOXpzsVcXVfrVMkUn2RuhjEHOmhME7/a7cR2FWodhMp\n\t8C6JRMT0c+hwokqlbajqHemgDSGez7ztDpPoJeRfQUNY5heNzQxrnbDzxY8cuVkhd+uP\n\tWoivYqxJfWA+dn/sXQXHtK2NM9flZms3VyN2r3hNZnOqpxrQaf2zTFMzuxkKDeYt8Eq/\n\t8NoA==",
        "X-Gm-Message-State": "AHPjjUhuUILFm3fV3QmXHqCrLiZXkgW7cH+1NuLfBQxsYEi8n6W78I9Z\n\tVFnhKg4Q/ZzwouA72UA=",
        "X-Google-Smtp-Source": "ADKCNb5gWa9W8myE33MmmuNsOu6wRp9gpO2Ze0vVaYtfGkqGZr2G+pB24QDRMaklKwam8QQ1WFPNlw==",
        "X-Received": "by 10.223.138.239 with SMTP id z44mr611175wrz.85.1504253262714; \n\tFri, 01 Sep 2017 01:07:42 -0700 (PDT)",
        "From": "Adrien Mazarguil <adrien.mazarguil@6wind.com>",
        "To": "dev@dpdk.org",
        "Date": "Fri,  1 Sep 2017 10:06:30 +0200",
        "Message-Id": "<2e35fbe91b57ab2755f0a5b10664691eadc79a93.1504252977.git.adrien.mazarguil@6wind.com>",
        "X-Mailer": "git-send-email 2.1.4",
        "In-Reply-To": "<cover.1504252977.git.adrien.mazarguil@6wind.com>",
        "References": "<cover.1501598383.git.adrien.mazarguil@6wind.com>\n\t<cover.1504252977.git.adrien.mazarguil@6wind.com>",
        "Subject": "[dpdk-dev] [PATCH v2 15/51] net/mlx4: revert RSS parent queue\n\trefactoring",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <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": "This reverts commit ff00a0dc5600dbb0a29e4aa7fa4b078f98c7a360.\n\nSupport for several RSS parent queues was necessary to implement the RSS\nflow rule action, dropped in a prior commit.\n\nSigned-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>\n---\n drivers/net/mlx4/mlx4.c      | 332 +++++++++++---------------------------\n drivers/net/mlx4/mlx4.h      |  17 +-\n drivers/net/mlx4/mlx4_flow.c |  15 --\n 3 files changed, 97 insertions(+), 267 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c\nindex 02605c9..44a2093 100644\n--- a/drivers/net/mlx4/mlx4.c\n+++ b/drivers/net/mlx4/mlx4.c\n@@ -507,10 +507,8 @@ txq_cleanup(struct txq *txq);\n \n static int\n rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,\n-\t  unsigned int socket, int inactive,\n-\t  const struct rte_eth_rxconf *conf,\n-\t  struct rte_mempool *mp, int children_n,\n-\t  struct rxq *rxq_parent);\n+\t  unsigned int socket, int inactive, const struct rte_eth_rxconf *conf,\n+\t  struct rte_mempool *mp);\n \n static void\n rxq_cleanup(struct rxq *rxq);\n@@ -519,84 +517,6 @@ static void\n priv_mac_addr_del(struct priv *priv);\n \n /**\n- * Create RSS parent queue.\n- *\n- * The new parent is inserted in front of the list in the private structure.\n- *\n- * @param priv\n- *   Pointer to private structure.\n- * @param queues\n- *   Queues indices array, if NULL use all Rx queues.\n- * @param children_n\n- *   The number of entries in queues[].\n- *\n- * @return\n- *   Pointer to a parent rxq structure, NULL on failure.\n- */\n-static struct rxq *\n-priv_parent_create(struct priv *priv,\n-\t\t   uint16_t queues[],\n-\t\t   uint16_t children_n)\n-{\n-\tint ret;\n-\tuint16_t i;\n-\tstruct rxq *parent;\n-\n-\tparent = rte_zmalloc(\"parent queue\",\n-\t\t\t     sizeof(*parent),\n-\t\t\t     RTE_CACHE_LINE_SIZE);\n-\tif (!parent) {\n-\t\tERROR(\"cannot allocate memory for RSS parent queue\");\n-\t\treturn NULL;\n-\t}\n-\tret = rxq_setup(priv->dev, parent, 0, 0, 0,\n-\t\t\tNULL, NULL, children_n, NULL);\n-\tif (ret) {\n-\t\trte_free(parent);\n-\t\treturn NULL;\n-\t}\n-\tparent->rss.queues_n = children_n;\n-\tif (queues) {\n-\t\tfor (i = 0; i < children_n; ++i)\n-\t\t\tparent->rss.queues[i] = queues[i];\n-\t} else {\n-\t\t/* the default RSS ring case */\n-\t\tassert(priv->rxqs_n == children_n);\n-\t\tfor (i = 0; i < priv->rxqs_n; ++i)\n-\t\t\tparent->rss.queues[i] = i;\n-\t}\n-\tLIST_INSERT_HEAD(&priv->parents, parent, next);\n-\treturn parent;\n-}\n-\n-/**\n- * Clean up RX queue parent structure.\n- *\n- * @param parent\n- *   RX queue parent structure.\n- */\n-void\n-rxq_parent_cleanup(struct rxq *parent)\n-{\n-\tLIST_REMOVE(parent, next);\n-\trxq_cleanup(parent);\n-\trte_free(parent);\n-}\n-\n-/**\n- * Clean up parent structures from the parent list.\n- *\n- * @param priv\n- *   Pointer to private structure.\n- */\n-static void\n-priv_parent_list_cleanup(struct priv *priv)\n-{\n-\twhile (!LIST_EMPTY(&priv->parents))\n-\t\trxq_parent_cleanup(LIST_FIRST(&priv->parents));\n-}\n-\n-/**\n  * Ethernet device configuration.\n  *\n  * Prepare the driver for a given number of TX and RX queues.\n@@ -615,6 +535,7 @@ dev_configure(struct rte_eth_dev *dev)\n \tunsigned int rxqs_n = dev->data->nb_rx_queues;\n \tunsigned int txqs_n = dev->data->nb_tx_queues;\n \tunsigned int tmp;\n+\tint ret;\n \n \tpriv->rxqs = (void *)dev->data->rx_queues;\n \tpriv->txqs = (void *)dev->data->tx_queues;\n@@ -645,7 +566,7 @@ dev_configure(struct rte_eth_dev *dev)\n \t\t\tif ((*priv->rxqs)[i] != NULL)\n \t\t\t\treturn EINVAL;\n \t\tpriv_mac_addr_del(priv);\n-\t\tpriv_parent_list_cleanup(priv);\n+\t\trxq_cleanup(&priv->rxq_parent);\n \t\tpriv->rss = 0;\n \t\tpriv->rxqs_n = 0;\n \t}\n@@ -670,16 +591,14 @@ dev_configure(struct rte_eth_dev *dev)\n \tpriv->rss = 1;\n \ttmp = priv->rxqs_n;\n \tpriv->rxqs_n = rxqs_n;\n-\tif (priv->isolated) {\n-\t\tpriv->rss = 0;\n-\t\treturn 0;\n-\t}\n-\tif (priv_parent_create(priv, NULL, priv->rxqs_n))\n+\tret = rxq_setup(dev, &priv->rxq_parent, 0, 0, 0, NULL, NULL);\n+\tif (!ret)\n \t\treturn 0;\n \t/* Failure, rollback. */\n \tpriv->rss = 0;\n \tpriv->rxqs_n = tmp;\n-\treturn ENOMEM;\n+\tassert(ret > 0);\n+\treturn ret;\n }\n \n /**\n@@ -2117,7 +2036,7 @@ priv_mac_addr_add(struct priv *priv)\n \tif (priv->isolated)\n \t\treturn 0;\n \tif (priv->rss)\n-\t\trxq = LIST_FIRST(&priv->parents);\n+\t\trxq = &priv->rxq_parent;\n \telse if (*priv->rxqs && (*priv->rxqs)[0])\n \t\trxq = (*priv->rxqs)[0];\n \telse\n@@ -2743,18 +2662,15 @@ rxq_setup_qp(struct priv *priv, struct ibv_cq *cq, uint16_t desc,\n  *   Completion queue to associate with QP.\n  * @param desc\n  *   Number of descriptors in QP (hint only).\n- * @param children_n\n- *   If nonzero, a number of children for parent QP and zero for a child.\n- * @param rxq_parent\n- *   Pointer for a parent in a child case, NULL otherwise.\n+ * @param parent\n+ *   If nonzero, create a parent QP, otherwise a child.\n  *\n  * @return\n  *   QP pointer or NULL in case of error.\n  */\n static struct ibv_qp *\n rxq_setup_qp_rss(struct priv *priv, struct ibv_cq *cq, uint16_t desc,\n-\t\t int children_n, struct ibv_exp_res_domain *rd,\n-\t\t struct rxq *rxq_parent)\n+\t\t int parent, struct ibv_exp_res_domain *rd)\n {\n \tstruct ibv_exp_qp_init_attr attr = {\n \t\t/* CQ to be associated with the send queue. */\n@@ -2782,16 +2698,16 @@ rxq_setup_qp_rss(struct priv *priv, struct ibv_cq *cq, uint16_t desc,\n \n \tattr.max_inl_recv = priv->inl_recv_size,\n \tattr.comp_mask |= IBV_EXP_QP_INIT_ATTR_INL_RECV;\n-\tif (children_n > 0) {\n+\tif (parent) {\n \t\tattr.qpg.qpg_type = IBV_EXP_QPG_PARENT;\n \t\t/* TSS isn't necessary. */\n \t\tattr.qpg.parent_attrib.tss_child_count = 0;\n \t\tattr.qpg.parent_attrib.rss_child_count =\n-\t\t\trte_align32pow2(children_n + 1) >> 1;\n+\t\t\trte_align32pow2(priv->rxqs_n + 1) >> 1;\n \t\tDEBUG(\"initializing parent RSS queue\");\n \t} else {\n \t\tattr.qpg.qpg_type = IBV_EXP_QPG_CHILD_RX;\n-\t\tattr.qpg.qpg_parent = rxq_parent->qp;\n+\t\tattr.qpg.qpg_parent = priv->rxq_parent.qp;\n \t\tDEBUG(\"initializing child RSS queue\");\n \t}\n \treturn ibv_exp_create_qp(priv->ctx, &attr);\n@@ -2825,7 +2741,13 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)\n \tstruct ibv_recv_wr *bad_wr;\n \tunsigned int mb_len;\n \tint err;\n+\tint parent = (rxq == &priv->rxq_parent);\n \n+\tif (parent) {\n+\t\tERROR(\"%p: cannot rehash parent queue %p\",\n+\t\t      (void *)dev, (void *)rxq);\n+\t\treturn EINVAL;\n+\t}\n \tmb_len = rte_pktmbuf_data_room_size(rxq->mp);\n \tDEBUG(\"%p: rehashing queue %p\", (void *)dev, (void *)rxq);\n \t/* Number of descriptors and mbufs currently allocated. */\n@@ -2858,8 +2780,6 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)\n \t}\n \t/* From now on, any failure will render the queue unusable.\n \t * Reinitialize QP. */\n-\tif (!tmpl.qp)\n-\t\tgoto skip_init;\n \tmod = (struct ibv_exp_qp_attr){ .qp_state = IBV_QPS_RESET };\n \terr = ibv_exp_modify_qp(tmpl.qp, &mod, IBV_EXP_QP_STATE);\n \tif (err) {\n@@ -2867,6 +2787,12 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)\n \t\tassert(err > 0);\n \t\treturn err;\n \t}\n+\terr = ibv_resize_cq(tmpl.cq, desc_n);\n+\tif (err) {\n+\t\tERROR(\"%p: cannot resize CQ: %s\", (void *)dev, strerror(err));\n+\t\tassert(err > 0);\n+\t\treturn err;\n+\t}\n \tmod = (struct ibv_exp_qp_attr){\n \t\t/* Move the QP to this state. */\n \t\t.qp_state = IBV_QPS_INIT,\n@@ -2875,6 +2801,7 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)\n \t};\n \terr = ibv_exp_modify_qp(tmpl.qp, &mod,\n \t\t\t\t(IBV_EXP_QP_STATE |\n+\t\t\t\t (parent ? IBV_EXP_QP_GROUP_RSS : 0) |\n \t\t\t\t IBV_EXP_QP_PORT));\n \tif (err) {\n \t\tERROR(\"%p: QP state to IBV_QPS_INIT failed: %s\",\n@@ -2882,13 +2809,6 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)\n \t\tassert(err > 0);\n \t\treturn err;\n \t};\n-skip_init:\n-\terr = ibv_resize_cq(tmpl.cq, desc_n);\n-\tif (err) {\n-\t\tERROR(\"%p: cannot resize CQ: %s\", (void *)dev, strerror(err));\n-\t\tassert(err > 0);\n-\t\treturn err;\n-\t}\n \t/* Allocate pool. */\n \tpool = rte_malloc(__func__, (mbuf_n * sizeof(*pool)), 0);\n \tif (pool == NULL) {\n@@ -2942,8 +2862,6 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)\n \trxq->elts_n = 0;\n \trte_free(rxq->elts.sp);\n \trxq->elts.sp = NULL;\n-\tif (!tmpl.qp)\n-\t\tgoto skip_rtr;\n \t/* Post WRs. */\n \terr = ibv_post_recv(tmpl.qp,\n \t\t\t    (tmpl.sp ?\n@@ -2971,103 +2889,6 @@ rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)\n }\n \n /**\n- * Create verbs QP resources associated with a rxq.\n- *\n- * @param rxq\n- *   Pointer to RX queue structure.\n- * @param desc\n- *   Number of descriptors to configure in queue.\n- * @param inactive\n- *   If true, the queue is disabled because its index is higher or\n- *   equal to the real number of queues, which must be a power of 2.\n- * @param children_n\n- *   The number of children in a parent case, zero for a child.\n- * @param rxq_parent\n- *   The pointer to a parent RX structure for a child in RSS case,\n- *   NULL for parent.\n- *\n- * @return\n- *   0 on success, errno value on failure.\n- */\n-int\n-rxq_create_qp(struct rxq *rxq,\n-\t      uint16_t desc,\n-\t      int inactive,\n-\t      int children_n,\n-\t      struct rxq *rxq_parent)\n-{\n-\tint ret;\n-\tstruct ibv_exp_qp_attr mod;\n-\tstruct ibv_exp_query_intf_params params;\n-\tenum ibv_exp_query_intf_status status;\n-\tstruct ibv_recv_wr *bad_wr;\n-\tint parent = (children_n > 0);\n-\tstruct priv *priv = rxq->priv;\n-\n-\tif (priv->rss && !inactive && (rxq_parent || parent))\n-\t\trxq->qp = rxq_setup_qp_rss(priv, rxq->cq, desc,\n-\t\t\t\t\t   children_n, rxq->rd,\n-\t\t\t\t\t   rxq_parent);\n-\telse\n-\t\trxq->qp = rxq_setup_qp(priv, rxq->cq, desc, rxq->rd);\n-\tif (rxq->qp == NULL) {\n-\t\tret = (errno ? errno : EINVAL);\n-\t\tERROR(\"QP creation failure: %s\",\n-\t\t      strerror(ret));\n-\t\treturn ret;\n-\t}\n-\tmod = (struct ibv_exp_qp_attr){\n-\t\t/* Move the QP to this state. */\n-\t\t.qp_state = IBV_QPS_INIT,\n-\t\t/* Primary port number. */\n-\t\t.port_num = priv->port\n-\t};\n-\tret = ibv_exp_modify_qp(rxq->qp, &mod,\n-\t\t\t\t(IBV_EXP_QP_STATE |\n-\t\t\t\t (parent ? IBV_EXP_QP_GROUP_RSS : 0) |\n-\t\t\t\t IBV_EXP_QP_PORT));\n-\tif (ret) {\n-\t\tERROR(\"QP state to IBV_QPS_INIT failed: %s\",\n-\t\t      strerror(ret));\n-\t\treturn ret;\n-\t}\n-\tif (!parent) {\n-\t\tret = ibv_post_recv(rxq->qp,\n-\t\t\t\t    (rxq->sp ?\n-\t\t\t\t     &(*rxq->elts.sp)[0].wr :\n-\t\t\t\t     &(*rxq->elts.no_sp)[0].wr),\n-\t\t\t\t    &bad_wr);\n-\t\tif (ret) {\n-\t\t\tERROR(\"ibv_post_recv() failed for WR %p: %s\",\n-\t\t\t      (void *)bad_wr,\n-\t\t\t      strerror(ret));\n-\t\t\treturn ret;\n-\t\t}\n-\t}\n-\tmod = (struct ibv_exp_qp_attr){\n-\t\t.qp_state = IBV_QPS_RTR\n-\t};\n-\tret = ibv_exp_modify_qp(rxq->qp, &mod, IBV_EXP_QP_STATE);\n-\tif (ret) {\n-\t\tERROR(\"QP state to IBV_QPS_RTR failed: %s\",\n-\t\t      strerror(ret));\n-\t\treturn ret;\n-\t}\n-\tparams = (struct ibv_exp_query_intf_params){\n-\t\t.intf_scope = IBV_EXP_INTF_GLOBAL,\n-\t\t.intf = IBV_EXP_INTF_QP_BURST,\n-\t\t.obj = rxq->qp,\n-\t};\n-\trxq->if_qp = ibv_exp_query_intf(priv->ctx, &params, &status);\n-\tif (rxq->if_qp == NULL) {\n-\t\tERROR(\"QP interface family query failed with status %d\",\n-\t\t      status);\n-\t\treturn errno;\n-\t}\n-\treturn 0;\n-}\n-\n-/**\n  * Configure a RX queue.\n  *\n  * @param dev\n@@ -3085,21 +2906,14 @@ rxq_create_qp(struct rxq *rxq,\n  *   Thresholds parameters.\n  * @param mp\n  *   Memory pool for buffer allocations.\n- * @param children_n\n- *   The number of children in a parent case, zero for a child.\n- * @param rxq_parent\n- *   The pointer to a parent RX structure (or NULL) in a child case,\n- *   NULL for parent.\n  *\n  * @return\n  *   0 on success, errno value on failure.\n  */\n static int\n rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,\n-\t  unsigned int socket, int inactive,\n-\t  const struct rte_eth_rxconf *conf,\n-\t  struct rte_mempool *mp, int children_n,\n-\t  struct rxq *rxq_parent)\n+\t  unsigned int socket, int inactive, const struct rte_eth_rxconf *conf,\n+\t  struct rte_mempool *mp)\n {\n \tstruct priv *priv = dev->data->dev_private;\n \tstruct rxq tmpl = {\n@@ -3107,15 +2921,17 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,\n \t\t.mp = mp,\n \t\t.socket = socket\n \t};\n+\tstruct ibv_exp_qp_attr mod;\n \tunion {\n \t\tstruct ibv_exp_query_intf_params params;\n \t\tstruct ibv_exp_cq_init_attr cq;\n \t\tstruct ibv_exp_res_domain_init_attr rd;\n \t} attr;\n \tenum ibv_exp_query_intf_status status;\n+\tstruct ibv_recv_wr *bad_wr;\n \tunsigned int mb_len;\n \tint ret = 0;\n-\tint parent = (children_n > 0);\n+\tint parent = (rxq == &priv->rxq_parent);\n \n \t(void)conf; /* Thresholds configuration (ignored). */\n \t/*\n@@ -3206,6 +3022,32 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,\n \t      priv->device_attr.max_qp_wr);\n \tDEBUG(\"priv->device_attr.max_sge is %d\",\n \t      priv->device_attr.max_sge);\n+\tif (priv->rss && !inactive)\n+\t\ttmpl.qp = rxq_setup_qp_rss(priv, tmpl.cq, desc, parent,\n+\t\t\t\t\t   tmpl.rd);\n+\telse\n+\t\ttmpl.qp = rxq_setup_qp(priv, tmpl.cq, desc, tmpl.rd);\n+\tif (tmpl.qp == NULL) {\n+\t\tret = (errno ? errno : EINVAL);\n+\t\tERROR(\"%p: QP creation failure: %s\",\n+\t\t      (void *)dev, strerror(ret));\n+\t\tgoto error;\n+\t}\n+\tmod = (struct ibv_exp_qp_attr){\n+\t\t/* Move the QP to this state. */\n+\t\t.qp_state = IBV_QPS_INIT,\n+\t\t/* Primary port number. */\n+\t\t.port_num = priv->port\n+\t};\n+\tret = ibv_exp_modify_qp(tmpl.qp, &mod,\n+\t\t\t\t(IBV_EXP_QP_STATE |\n+\t\t\t\t (parent ? IBV_EXP_QP_GROUP_RSS : 0) |\n+\t\t\t\t IBV_EXP_QP_PORT));\n+\tif (ret) {\n+\t\tERROR(\"%p: QP state to IBV_QPS_INIT failed: %s\",\n+\t\t      (void *)dev, strerror(ret));\n+\t\tgoto error;\n+\t}\n \t/* Allocate descriptors for RX queues, except for the RSS parent. */\n \tif (parent)\n \t\tgoto skip_alloc;\n@@ -3216,14 +3058,29 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,\n \tif (ret) {\n \t\tERROR(\"%p: RXQ allocation failed: %s\",\n \t\t      (void *)dev, strerror(ret));\n-\t\treturn ret;\n+\t\tgoto error;\n+\t}\n+\tret = ibv_post_recv(tmpl.qp,\n+\t\t\t    (tmpl.sp ?\n+\t\t\t     &(*tmpl.elts.sp)[0].wr :\n+\t\t\t     &(*tmpl.elts.no_sp)[0].wr),\n+\t\t\t    &bad_wr);\n+\tif (ret) {\n+\t\tERROR(\"%p: ibv_post_recv() failed for WR %p: %s\",\n+\t\t      (void *)dev,\n+\t\t      (void *)bad_wr,\n+\t\t      strerror(ret));\n+\t\tgoto error;\n \t}\n skip_alloc:\n-\tif (parent || rxq_parent || !priv->rss) {\n-\t\tret = rxq_create_qp(&tmpl, desc, inactive,\n-\t\t\t\t    children_n, rxq_parent);\n-\t\tif (ret)\n-\t\t\tgoto error;\n+\tmod = (struct ibv_exp_qp_attr){\n+\t\t.qp_state = IBV_QPS_RTR\n+\t};\n+\tret = ibv_exp_modify_qp(tmpl.qp, &mod, IBV_EXP_QP_STATE);\n+\tif (ret) {\n+\t\tERROR(\"%p: QP state to IBV_QPS_RTR failed: %s\",\n+\t\t      (void *)dev, strerror(ret));\n+\t\tgoto error;\n \t}\n \t/* Save port ID. */\n \ttmpl.port_id = dev->data->port_id;\n@@ -3235,11 +3092,21 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,\n \t};\n \ttmpl.if_cq = ibv_exp_query_intf(priv->ctx, &attr.params, &status);\n \tif (tmpl.if_cq == NULL) {\n-\t\tret = EINVAL;\n \t\tERROR(\"%p: CQ interface family query failed with status %d\",\n \t\t      (void *)dev, status);\n \t\tgoto error;\n \t}\n+\tattr.params = (struct ibv_exp_query_intf_params){\n+\t\t.intf_scope = IBV_EXP_INTF_GLOBAL,\n+\t\t.intf = IBV_EXP_INTF_QP_BURST,\n+\t\t.obj = tmpl.qp,\n+\t};\n+\ttmpl.if_qp = ibv_exp_query_intf(priv->ctx, &attr.params, &status);\n+\tif (tmpl.if_qp == NULL) {\n+\t\tERROR(\"%p: QP interface family query failed with status %d\",\n+\t\t      (void *)dev, status);\n+\t\tgoto error;\n+\t}\n \t/* Clean up rxq in case we're reinitializing it. */\n \tDEBUG(\"%p: cleaning-up old rxq just in case\", (void *)rxq);\n \trxq_cleanup(rxq);\n@@ -3277,7 +3144,6 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,\n \t\t    unsigned int socket, const struct rte_eth_rxconf *conf,\n \t\t    struct rte_mempool *mp)\n {\n-\tstruct rxq *parent;\n \tstruct priv *priv = dev->data->dev_private;\n \tstruct rxq *rxq = (*priv->rxqs)[idx];\n \tint inactive = 0;\n@@ -3312,16 +3178,9 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,\n \t\t\treturn -ENOMEM;\n \t\t}\n \t}\n-\tif (priv->rss && !priv->isolated) {\n-\t\t/* The list consists of the single default one. */\n-\t\tparent = LIST_FIRST(&priv->parents);\n-\t\tif (idx >= rte_align32pow2(priv->rxqs_n + 1) >> 1)\n-\t\t\tinactive = 1;\n-\t} else {\n-\t\tparent = NULL;\n-\t}\n-\tret = rxq_setup(dev, rxq, desc, socket,\n-\t\t\tinactive, conf, mp, 0, parent);\n+\tif (idx >= rte_align32pow2(priv->rxqs_n + 1) >> 1)\n+\t\tinactive = 1;\n+\tret = rxq_setup(dev, rxq, desc, socket, inactive, conf, mp);\n \tif (ret)\n \t\trte_free(rxq);\n \telse {\n@@ -3356,6 +3215,7 @@ mlx4_rx_queue_release(void *dpdk_rxq)\n \t\treturn;\n \tpriv = rxq->priv;\n \tpriv_lock(priv);\n+\tassert(rxq != &priv->rxq_parent);\n \tfor (i = 0; (i != priv->rxqs_n); ++i)\n \t\tif ((*priv->rxqs)[i] == rxq) {\n \t\t\tDEBUG(\"%p: removing RX queue %p from list\",\n@@ -3581,7 +3441,7 @@ mlx4_dev_close(struct rte_eth_dev *dev)\n \t\tpriv->txqs = NULL;\n \t}\n \tif (priv->rss)\n-\t\tpriv_parent_list_cleanup(priv);\n+\t\trxq_cleanup(&priv->rxq_parent);\n \tif (priv->pd != NULL) {\n \t\tassert(priv->ctx != NULL);\n \t\tclaim_zero(ibv_dealloc_pd(priv->pd));\ndiff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h\nindex b76bf48..b7177d4 100644\n--- a/drivers/net/mlx4/mlx4.h\n+++ b/drivers/net/mlx4/mlx4.h\n@@ -163,7 +163,6 @@ struct rxq_elt {\n \n /* RX queue descriptor. */\n struct rxq {\n-\tLIST_ENTRY(rxq) next; /* Used by parent queue only */\n \tstruct priv *priv; /* Back pointer to private data. */\n \tstruct rte_mempool *mp; /* Memory Pool for allocations. */\n \tstruct ibv_mr *mr; /* Memory Region (for mp). */\n@@ -185,10 +184,6 @@ struct rxq {\n \tstruct mlx4_rxq_stats stats; /* RX queue counters. */\n \tunsigned int socket; /* CPU socket ID for allocations. */\n \tstruct ibv_exp_res_domain *rd; /* Resource Domain. */\n-\tstruct {\n-\t\tuint16_t queues_n;\n-\t\tuint16_t queues[RTE_MAX_QUEUES_PER_PORT];\n-\t} rss;\n };\n \n /* TX element. */\n@@ -265,6 +260,7 @@ struct priv {\n \tunsigned int inl_recv_size; /* Inline recv size */\n \tunsigned int max_rss_tbl_sz; /* Maximum number of RSS queues. */\n \t/* RX/TX queues. */\n+\tstruct rxq rxq_parent; /* Parent queue when RSS is enabled. */\n \tunsigned int rxqs_n; /* RX queues array size. */\n \tunsigned int txqs_n; /* TX queues array size. */\n \tstruct rxq *(*rxqs)[]; /* RX queues. */\n@@ -274,21 +270,10 @@ struct priv {\n \tstruct rte_flow_drop *flow_drop_queue; /* Flow drop queue. */\n \tLIST_HEAD(mlx4_flows, rte_flow) flows;\n \tstruct rte_intr_conf intr_conf; /* Active interrupt configuration. */\n-\tLIST_HEAD(mlx4_parents, rxq) parents;\n \trte_spinlock_t lock; /* Lock for control functions. */\n };\n \n void priv_lock(struct priv *priv);\n void priv_unlock(struct priv *priv);\n \n-int\n-rxq_create_qp(struct rxq *rxq,\n-\t      uint16_t desc,\n-\t      int inactive,\n-\t      int children_n,\n-\t      struct rxq *rxq_parent);\n-\n-void\n-rxq_parent_cleanup(struct rxq *parent);\n-\n #endif /* RTE_PMD_MLX4_H_ */\ndiff --git a/drivers/net/mlx4/mlx4_flow.c b/drivers/net/mlx4/mlx4_flow.c\nindex 827115e..2c5dc3c 100644\n--- a/drivers/net/mlx4/mlx4_flow.c\n+++ b/drivers/net/mlx4/mlx4_flow.c\n@@ -828,23 +828,8 @@ priv_flow_create_action_queue(struct priv *priv,\n \tif (action->drop) {\n \t\tqp = priv->flow_drop_queue ? priv->flow_drop_queue->qp : NULL;\n \t} else {\n-\t\tint ret;\n \t\tstruct rxq *rxq = (*priv->rxqs)[action->queue_id];\n \n-\t\tif (!rxq->qp) {\n-\t\t\tassert(priv->isolated);\n-\t\t\tret = rxq_create_qp(rxq, rxq->elts_n,\n-\t\t\t\t\t    0, 0, NULL);\n-\t\t\tif (ret) {\n-\t\t\t\trte_flow_error_set(\n-\t\t\t\t\terror,\n-\t\t\t\t\tENOMEM,\n-\t\t\t\t\tRTE_FLOW_ERROR_TYPE_HANDLE,\n-\t\t\t\t\tNULL,\n-\t\t\t\t\t\"flow rule creation failure\");\n-\t\t\t\tgoto error;\n-\t\t\t}\n-\t\t}\n \t\tqp = rxq->qp;\n \t\trte_flow->qp = qp;\n \t}\n",
    "prefixes": [
        "dpdk-dev",
        "v2",
        "15/51"
    ]
}