get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 27332,
    "url": "http://patches.dpdk.org/api/patches/27332/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/e51f19191dd4ef65d46aabbb8ee0ecb1ef6eac39.1501598384.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": "<e51f19191dd4ef65d46aabbb8ee0ecb1ef6eac39.1501598384.git.adrien.mazarguil@6wind.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/e51f19191dd4ef65d46aabbb8ee0ecb1ef6eac39.1501598384.git.adrien.mazarguil@6wind.com",
    "date": "2017-08-01T16:54:06",
    "name": "[dpdk-dev,v1,19/48] net/mlx4: drop scatter/gather support",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "3bc94d6fb86b0552ed6576065c62a345574683de",
    "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/e51f19191dd4ef65d46aabbb8ee0ecb1ef6eac39.1501598384.git.adrien.mazarguil@6wind.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/27332/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/27332/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 B41DEA1AA;\n\tTue,  1 Aug 2017 18:55:45 +0200 (CEST)",
            "from mail-wm0-f50.google.com (mail-wm0-f50.google.com\n\t[74.125.82.50]) by dpdk.org (Postfix) with ESMTP id A507CA0F4\n\tfor <dev@dpdk.org>; Tue,  1 Aug 2017 18:55:19 +0200 (CEST)",
            "by mail-wm0-f50.google.com with SMTP id t201so20377755wmt.0\n\tfor <dev@dpdk.org>; Tue, 01 Aug 2017 09:55:19 -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\tw20sm16503809wra.27.2017.08.01.09.55.16\n\tfor <dev@dpdk.org> (version=TLS1_2 cipher=AES128-SHA bits=128/128);\n\tTue, 01 Aug 2017 09:55:16 -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=JcWGuq6nGXeOOJNkjFixqSICOth+EIxwYN+ZPBZQ4lQ=;\n\tb=tM4we0bL7m1zg1FHdD8Yrv0oT1uSphgtYYdi3QNzP3jiKWg+3tEAcu+0R5dZxASMPk\n\t+TTS0Tk29EwXz8wr1GaVAHTaeuw1IxBhDo+2LIyPMLQ9M6zQE7hFOoPfuOIrtGhoWIp5\n\tYkXc3D79rdC1qDCHCiQR5a5CGo65nk3db0QDo+8IYV6/cL0JFGtahUg+AI6Pq8U0RLXc\n\t1ucCz/EfylZcb1Gxwoxg1U+XyJqcL+WmnyevteWEVimTmtgGfdnmsFLPVlZ9u1EbE1oZ\n\tRsNsMUS1x9SYQ5yutdPIxfFDz7Xx4aqrLBIHiMIjr7dQka+DtxbtsZEmQkZ9SmR2WTt9\n\twGeA==",
        "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=JcWGuq6nGXeOOJNkjFixqSICOth+EIxwYN+ZPBZQ4lQ=;\n\tb=exyw/AcoD9ikejpJiBjUgFOJAlxGFVuDZALbd6ohUnjbtSsl+M3RXr9TndXwI7u15Q\n\t3hn2MbOQG03+HNZA2qO6xJQ0q9bnAAvWBX3oHHydriBCTqlEJ+EIh1o47oFOH3Wuq5l8\n\t4me18oDe7dt1+8lFeoMn2tTnWg7dQX5SsO4NsMGQaScexHXIydYlfJB6RDSAjqQhroWb\n\tL3qinf2/Y2T8V2THjCoXZTgebP5HbBlxT4jBInHf0ZNp5pYEi+0b3PQj3Sc/ZSQEwnZ9\n\twElCE4iQ655+Yd/xnAzs6fbcwFEEwucPR+/oIgufTw0QkKiHgZ3QOUMIyb2PzzaxWfp4\n\tCT9g==",
        "X-Gm-Message-State": "AIVw1111wKEtE9HHZPEidM1XE06Rwf2583kWFQDYzAcNboTMPlUzpCaR\n\tRLd/cA9j79529yyf68g=",
        "X-Received": "by 10.28.32.208 with SMTP id g199mr1717155wmg.180.1501606517638; \n\tTue, 01 Aug 2017 09:55:17 -0700 (PDT)",
        "From": "Adrien Mazarguil <adrien.mazarguil@6wind.com>",
        "To": "dev@dpdk.org",
        "Date": "Tue,  1 Aug 2017 18:54:06 +0200",
        "Message-Id": "<e51f19191dd4ef65d46aabbb8ee0ecb1ef6eac39.1501598384.git.adrien.mazarguil@6wind.com>",
        "X-Mailer": "git-send-email 2.1.4",
        "In-Reply-To": "<cover.1501598383.git.adrien.mazarguil@6wind.com>",
        "References": "<cover.1501598383.git.adrien.mazarguil@6wind.com>",
        "Subject": "[dpdk-dev] [PATCH v1 19/48] net/mlx4: drop scatter/gather support",
        "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": "The Verbs API used to implement Tx and Rx burst functions is deprecated.\nDrop scatter/gather support to ease refactoring while maintaining basic\nsingle-segment Rx/Tx functionality in the meantime.\n\nSigned-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>\n---\n doc/guides/nics/features/mlx4.ini |   1 -\n doc/guides/nics/mlx4.rst          |   1 -\n drivers/net/mlx4/mlx4.c           | 845 +--------------------------------\n drivers/net/mlx4/mlx4.h           |  28 +-\n 4 files changed, 24 insertions(+), 851 deletions(-)",
    "diff": "diff --git a/doc/guides/nics/features/mlx4.ini b/doc/guides/nics/features/mlx4.ini\nindex 27c7ae3..0812a30 100644\n--- a/doc/guides/nics/features/mlx4.ini\n+++ b/doc/guides/nics/features/mlx4.ini\n@@ -12,7 +12,6 @@ Rx interrupt         = Y\n Queue start/stop     = Y\n MTU update           = Y\n Jumbo frame          = Y\n-Scattered Rx         = Y\n SR-IOV               = Y\n Basic stats          = Y\n Stats per queue      = Y\ndiff --git a/doc/guides/nics/mlx4.rst b/doc/guides/nics/mlx4.rst\nindex 3f54343..8503804 100644\n--- a/doc/guides/nics/mlx4.rst\n+++ b/doc/guides/nics/mlx4.rst\n@@ -79,7 +79,6 @@ Features\n \n - Multi arch support: x86_64 and POWER8.\n - Link state information is provided.\n-- Scattered packets are supported for TX and RX.\n - RX interrupts.\n \n Configuration\ndiff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c\nindex e0e5d1f..5546c0a 100644\n--- a/drivers/net/mlx4/mlx4.c\n+++ b/drivers/net/mlx4/mlx4.c\n@@ -60,7 +60,6 @@\n #include <rte_prefetch.h>\n #include <rte_malloc.h>\n #include <rte_spinlock.h>\n-#include <rte_atomic.h>\n #include <rte_log.h>\n #include <rte_alarm.h>\n #include <rte_memory.h>\n@@ -582,26 +581,13 @@ txq_alloc_elts(struct txq *txq, unsigned int elts_n)\n \tunsigned int i;\n \tstruct txq_elt (*elts)[elts_n] =\n \t\trte_calloc_socket(\"TXQ\", 1, sizeof(*elts), 0, txq->socket);\n-\tlinear_t (*elts_linear)[elts_n] =\n-\t\trte_calloc_socket(\"TXQ\", 1, sizeof(*elts_linear), 0,\n-\t\t\t\t  txq->socket);\n-\tstruct ibv_mr *mr_linear = NULL;\n \tint ret = 0;\n \n-\tif ((elts == NULL) || (elts_linear == NULL)) {\n+\tif (elts == NULL) {\n \t\tERROR(\"%p: can't allocate packets array\", (void *)txq);\n \t\tret = ENOMEM;\n \t\tgoto error;\n \t}\n-\tmr_linear =\n-\t\tibv_reg_mr(txq->priv->pd, elts_linear, sizeof(*elts_linear),\n-\t\t\t   IBV_ACCESS_LOCAL_WRITE);\n-\tif (mr_linear == NULL) {\n-\t\tERROR(\"%p: unable to configure MR, ibv_reg_mr() failed\",\n-\t\t      (void *)txq);\n-\t\tret = EINVAL;\n-\t\tgoto error;\n-\t}\n \tfor (i = 0; (i != elts_n); ++i) {\n \t\tstruct txq_elt *elt = &(*elts)[i];\n \n@@ -619,15 +605,9 @@ txq_alloc_elts(struct txq *txq, unsigned int elts_n)\n \t\t((MLX4_PMD_TX_PER_COMP_REQ < (elts_n / 4)) ?\n \t\t MLX4_PMD_TX_PER_COMP_REQ : (elts_n / 4));\n \ttxq->elts_comp_cd = txq->elts_comp_cd_init;\n-\ttxq->elts_linear = elts_linear;\n-\ttxq->mr_linear = mr_linear;\n \tassert(ret == 0);\n \treturn 0;\n error:\n-\tif (mr_linear != NULL)\n-\t\tclaim_zero(ibv_dereg_mr(mr_linear));\n-\n-\trte_free(elts_linear);\n \trte_free(elts);\n \n \tDEBUG(\"%p: failed, freed everything\", (void *)txq);\n@@ -648,8 +628,6 @@ txq_free_elts(struct txq *txq)\n \tunsigned int elts_head = txq->elts_head;\n \tunsigned int elts_tail = txq->elts_tail;\n \tstruct txq_elt (*elts)[elts_n] = txq->elts;\n-\tlinear_t (*elts_linear)[elts_n] = txq->elts_linear;\n-\tstruct ibv_mr *mr_linear = txq->mr_linear;\n \n \tDEBUG(\"%p: freeing WRs\", (void *)txq);\n \ttxq->elts_n = 0;\n@@ -659,12 +637,6 @@ txq_free_elts(struct txq *txq)\n \ttxq->elts_comp_cd = 0;\n \ttxq->elts_comp_cd_init = 0;\n \ttxq->elts = NULL;\n-\ttxq->elts_linear = NULL;\n-\ttxq->mr_linear = NULL;\n-\tif (mr_linear != NULL)\n-\t\tclaim_zero(ibv_dereg_mr(mr_linear));\n-\n-\trte_free(elts_linear);\n \tif (elts == NULL)\n \t\treturn;\n \twhile (elts_tail != elts_head) {\n@@ -1037,152 +1009,6 @@ txq_mp2mr_iter(struct rte_mempool *mp, void *arg)\n }\n \n /**\n- * Copy scattered mbuf contents to a single linear buffer.\n- *\n- * @param[out] linear\n- *   Linear output buffer.\n- * @param[in] buf\n- *   Scattered input buffer.\n- *\n- * @return\n- *   Number of bytes copied to the output buffer or 0 if not large enough.\n- */\n-static unsigned int\n-linearize_mbuf(linear_t *linear, struct rte_mbuf *buf)\n-{\n-\tunsigned int size = 0;\n-\tunsigned int offset;\n-\n-\tdo {\n-\t\tunsigned int len = DATA_LEN(buf);\n-\n-\t\toffset = size;\n-\t\tsize += len;\n-\t\tif (unlikely(size > sizeof(*linear)))\n-\t\t\treturn 0;\n-\t\tmemcpy(&(*linear)[offset],\n-\t\t       rte_pktmbuf_mtod(buf, uint8_t *),\n-\t\t       len);\n-\t\tbuf = NEXT(buf);\n-\t} while (buf != NULL);\n-\treturn size;\n-}\n-\n-/**\n- * Handle scattered buffers for mlx4_tx_burst().\n- *\n- * @param txq\n- *   TX queue structure.\n- * @param segs\n- *   Number of segments in buf.\n- * @param elt\n- *   TX queue element to fill.\n- * @param[in] buf\n- *   Buffer to process.\n- * @param elts_head\n- *   Index of the linear buffer to use if necessary (normally txq->elts_head).\n- * @param[out] sges\n- *   Array filled with SGEs on success.\n- *\n- * @return\n- *   A structure containing the processed packet size in bytes and the\n- *   number of SGEs. Both fields are set to (unsigned int)-1 in case of\n- *   failure.\n- */\n-static struct tx_burst_sg_ret {\n-\tunsigned int length;\n-\tunsigned int num;\n-}\n-tx_burst_sg(struct txq *txq, unsigned int segs, struct txq_elt *elt,\n-\t    struct rte_mbuf *buf, unsigned int elts_head,\n-\t    struct ibv_sge (*sges)[MLX4_PMD_SGE_WR_N])\n-{\n-\tunsigned int sent_size = 0;\n-\tunsigned int j;\n-\tint linearize = 0;\n-\n-\t/* When there are too many segments, extra segments are\n-\t * linearized in the last SGE. */\n-\tif (unlikely(segs > elemof(*sges))) {\n-\t\tsegs = (elemof(*sges) - 1);\n-\t\tlinearize = 1;\n-\t}\n-\t/* Update element. */\n-\telt->buf = buf;\n-\t/* Register segments as SGEs. */\n-\tfor (j = 0; (j != segs); ++j) {\n-\t\tstruct ibv_sge *sge = &(*sges)[j];\n-\t\tuint32_t lkey;\n-\n-\t\t/* Retrieve Memory Region key for this memory pool. */\n-\t\tlkey = txq_mp2mr(txq, txq_mb2mp(buf));\n-\t\tif (unlikely(lkey == (uint32_t)-1)) {\n-\t\t\t/* MR does not exist. */\n-\t\t\tDEBUG(\"%p: unable to get MP <-> MR association\",\n-\t\t\t      (void *)txq);\n-\t\t\t/* Clean up TX element. */\n-\t\t\telt->buf = NULL;\n-\t\t\tgoto stop;\n-\t\t}\n-\t\t/* Update SGE. */\n-\t\tsge->addr = rte_pktmbuf_mtod(buf, uintptr_t);\n-\t\tif (txq->priv->vf)\n-\t\t\trte_prefetch0((volatile void *)\n-\t\t\t\t      (uintptr_t)sge->addr);\n-\t\tsge->length = DATA_LEN(buf);\n-\t\tsge->lkey = lkey;\n-\t\tsent_size += sge->length;\n-\t\tbuf = NEXT(buf);\n-\t}\n-\t/* If buf is not NULL here and is not going to be linearized,\n-\t * nb_segs is not valid. */\n-\tassert(j == segs);\n-\tassert((buf == NULL) || (linearize));\n-\t/* Linearize extra segments. */\n-\tif (linearize) {\n-\t\tstruct ibv_sge *sge = &(*sges)[segs];\n-\t\tlinear_t *linear = &(*txq->elts_linear)[elts_head];\n-\t\tunsigned int size = linearize_mbuf(linear, buf);\n-\n-\t\tassert(segs == (elemof(*sges) - 1));\n-\t\tif (size == 0) {\n-\t\t\t/* Invalid packet. */\n-\t\t\tDEBUG(\"%p: packet too large to be linearized.\",\n-\t\t\t      (void *)txq);\n-\t\t\t/* Clean up TX element. */\n-\t\t\telt->buf = NULL;\n-\t\t\tgoto stop;\n-\t\t}\n-\t\t/* If MLX4_PMD_SGE_WR_N is 1, free mbuf immediately. */\n-\t\tif (elemof(*sges) == 1) {\n-\t\t\tdo {\n-\t\t\t\tstruct rte_mbuf *next = NEXT(buf);\n-\n-\t\t\t\trte_pktmbuf_free_seg(buf);\n-\t\t\t\tbuf = next;\n-\t\t\t} while (buf != NULL);\n-\t\t\telt->buf = NULL;\n-\t\t}\n-\t\t/* Update SGE. */\n-\t\tsge->addr = (uintptr_t)&(*linear)[0];\n-\t\tsge->length = size;\n-\t\tsge->lkey = txq->mr_linear->lkey;\n-\t\tsent_size += size;\n-\t\t/* Include last segment. */\n-\t\tsegs++;\n-\t}\n-\treturn (struct tx_burst_sg_ret){\n-\t\t.length = sent_size,\n-\t\t.num = segs,\n-\t};\n-stop:\n-\treturn (struct tx_burst_sg_ret){\n-\t\t.length = -1,\n-\t\t.num = -1,\n-\t};\n-}\n-\n-/**\n  * DPDK callback for TX.\n  *\n  * @param dpdk_txq\n@@ -1294,23 +1120,8 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)\n \t\t\t\tgoto stop;\n \t\t\tsent_size += length;\n \t\t} else {\n-\t\t\tstruct ibv_sge sges[MLX4_PMD_SGE_WR_N];\n-\t\t\tstruct tx_burst_sg_ret ret;\n-\n-\t\t\tret = tx_burst_sg(txq, segs, elt, buf, elts_head,\n-\t\t\t\t\t  &sges);\n-\t\t\tif (ret.length == (unsigned int)-1)\n-\t\t\t\tgoto stop;\n-\t\t\tRTE_MBUF_PREFETCH_TO_FREE(elt_next->buf);\n-\t\t\t/* Put SG list into send queue. */\n-\t\t\terr = txq->if_qp->send_pending_sg_list\n-\t\t\t\t(txq->qp,\n-\t\t\t\t sges,\n-\t\t\t\t ret.num,\n-\t\t\t\t send_flags);\n-\t\t\tif (unlikely(err))\n-\t\t\t\tgoto stop;\n-\t\t\tsent_size += ret.length;\n+\t\t\terr = -1;\n+\t\t\tgoto stop;\n \t\t}\n \t\telts_head = elts_head_next;\n \t\t/* Increment sent bytes counter. */\n@@ -1375,12 +1186,10 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,\n \t(void)conf; /* Thresholds configuration (ignored). */\n \tif (priv == NULL)\n \t\treturn EINVAL;\n-\tif ((desc == 0) || (desc % MLX4_PMD_SGE_WR_N)) {\n-\t\tERROR(\"%p: invalid number of TX descriptors (must be a\"\n-\t\t      \" multiple of %d)\", (void *)dev, MLX4_PMD_SGE_WR_N);\n+\tif (desc == 0) {\n+\t\tERROR(\"%p: invalid number of TX descriptors\", (void *)dev);\n \t\treturn EINVAL;\n \t}\n-\tdesc /= MLX4_PMD_SGE_WR_N;\n \t/* MRs will be registered in mp2mr[] later. */\n \tattr.rd = (struct ibv_exp_res_domain_init_attr){\n \t\t.comp_mask = (IBV_EXP_RES_DOMAIN_THREAD_MODEL |\n@@ -1421,10 +1230,7 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,\n \t\t\t\t\tpriv->device_attr.max_qp_wr :\n \t\t\t\t\tdesc),\n \t\t\t/* Max number of scatter/gather elements in a WR. */\n-\t\t\t.max_send_sge = ((priv->device_attr.max_sge <\n-\t\t\t\t\t  MLX4_PMD_SGE_WR_N) ?\n-\t\t\t\t\t priv->device_attr.max_sge :\n-\t\t\t\t\t MLX4_PMD_SGE_WR_N),\n+\t\t\t.max_send_sge = 1,\n \t\t\t.max_inline_data = MLX4_PMD_MAX_INLINE,\n \t\t},\n \t\t.qp_type = IBV_QPT_RAW_PACKET,\n@@ -1623,153 +1429,6 @@ mlx4_tx_queue_release(void *dpdk_txq)\n /* RX queues handling. */\n \n /**\n- * Allocate RX queue elements with scattered packets support.\n- *\n- * @param rxq\n- *   Pointer to RX queue structure.\n- * @param elts_n\n- *   Number of elements to allocate.\n- * @param[in] pool\n- *   If not NULL, fetch buffers from this array instead of allocating them\n- *   with rte_pktmbuf_alloc().\n- *\n- * @return\n- *   0 on success, errno value on failure.\n- */\n-static int\n-rxq_alloc_elts_sp(struct rxq *rxq, unsigned int elts_n,\n-\t\t  struct rte_mbuf **pool)\n-{\n-\tunsigned int i;\n-\tstruct rxq_elt_sp (*elts)[elts_n] =\n-\t\trte_calloc_socket(\"RXQ elements\", 1, sizeof(*elts), 0,\n-\t\t\t\t  rxq->socket);\n-\tint ret = 0;\n-\n-\tif (elts == NULL) {\n-\t\tERROR(\"%p: can't allocate packets array\", (void *)rxq);\n-\t\tret = ENOMEM;\n-\t\tgoto error;\n-\t}\n-\t/* For each WR (packet). */\n-\tfor (i = 0; (i != elts_n); ++i) {\n-\t\tunsigned int j;\n-\t\tstruct rxq_elt_sp *elt = &(*elts)[i];\n-\t\tstruct ibv_recv_wr *wr = &elt->wr;\n-\t\tstruct ibv_sge (*sges)[(elemof(elt->sges))] = &elt->sges;\n-\n-\t\t/* These two arrays must have the same size. */\n-\t\tassert(elemof(elt->sges) == elemof(elt->bufs));\n-\t\t/* Configure WR. */\n-\t\twr->wr_id = i;\n-\t\twr->next = &(*elts)[(i + 1)].wr;\n-\t\twr->sg_list = &(*sges)[0];\n-\t\twr->num_sge = elemof(*sges);\n-\t\t/* For each SGE (segment). */\n-\t\tfor (j = 0; (j != elemof(elt->bufs)); ++j) {\n-\t\t\tstruct ibv_sge *sge = &(*sges)[j];\n-\t\t\tstruct rte_mbuf *buf;\n-\n-\t\t\tif (pool != NULL) {\n-\t\t\t\tbuf = *(pool++);\n-\t\t\t\tassert(buf != NULL);\n-\t\t\t\trte_pktmbuf_reset(buf);\n-\t\t\t} else\n-\t\t\t\tbuf = rte_pktmbuf_alloc(rxq->mp);\n-\t\t\tif (buf == NULL) {\n-\t\t\t\tassert(pool == NULL);\n-\t\t\t\tERROR(\"%p: empty mbuf pool\", (void *)rxq);\n-\t\t\t\tret = ENOMEM;\n-\t\t\t\tgoto error;\n-\t\t\t}\n-\t\t\telt->bufs[j] = buf;\n-\t\t\t/* Headroom is reserved by rte_pktmbuf_alloc(). */\n-\t\t\tassert(DATA_OFF(buf) == RTE_PKTMBUF_HEADROOM);\n-\t\t\t/* Buffer is supposed to be empty. */\n-\t\t\tassert(rte_pktmbuf_data_len(buf) == 0);\n-\t\t\tassert(rte_pktmbuf_pkt_len(buf) == 0);\n-\t\t\t/* sge->addr must be able to store a pointer. */\n-\t\t\tassert(sizeof(sge->addr) >= sizeof(uintptr_t));\n-\t\t\tif (j == 0) {\n-\t\t\t\t/* The first SGE keeps its headroom. */\n-\t\t\t\tsge->addr = rte_pktmbuf_mtod(buf, uintptr_t);\n-\t\t\t\tsge->length = (buf->buf_len -\n-\t\t\t\t\t       RTE_PKTMBUF_HEADROOM);\n-\t\t\t} else {\n-\t\t\t\t/* Subsequent SGEs lose theirs. */\n-\t\t\t\tassert(DATA_OFF(buf) == RTE_PKTMBUF_HEADROOM);\n-\t\t\t\tSET_DATA_OFF(buf, 0);\n-\t\t\t\tsge->addr = (uintptr_t)buf->buf_addr;\n-\t\t\t\tsge->length = buf->buf_len;\n-\t\t\t}\n-\t\t\tsge->lkey = rxq->mr->lkey;\n-\t\t\t/* Redundant check for tailroom. */\n-\t\t\tassert(sge->length == rte_pktmbuf_tailroom(buf));\n-\t\t}\n-\t}\n-\t/* The last WR pointer must be NULL. */\n-\t(*elts)[(i - 1)].wr.next = NULL;\n-\tDEBUG(\"%p: allocated and configured %u WRs (%zu segments)\",\n-\t      (void *)rxq, elts_n, (elts_n * elemof((*elts)[0].sges)));\n-\trxq->elts_n = elts_n;\n-\trxq->elts_head = 0;\n-\trxq->elts.sp = elts;\n-\tassert(ret == 0);\n-\treturn 0;\n-error:\n-\tif (elts != NULL) {\n-\t\tassert(pool == NULL);\n-\t\tfor (i = 0; (i != elemof(*elts)); ++i) {\n-\t\t\tunsigned int j;\n-\t\t\tstruct rxq_elt_sp *elt = &(*elts)[i];\n-\n-\t\t\tfor (j = 0; (j != elemof(elt->bufs)); ++j) {\n-\t\t\t\tstruct rte_mbuf *buf = elt->bufs[j];\n-\n-\t\t\t\tif (buf != NULL)\n-\t\t\t\t\trte_pktmbuf_free_seg(buf);\n-\t\t\t}\n-\t\t}\n-\t\trte_free(elts);\n-\t}\n-\tDEBUG(\"%p: failed, freed everything\", (void *)rxq);\n-\tassert(ret > 0);\n-\treturn ret;\n-}\n-\n-/**\n- * Free RX queue elements with scattered packets support.\n- *\n- * @param rxq\n- *   Pointer to RX queue structure.\n- */\n-static void\n-rxq_free_elts_sp(struct rxq *rxq)\n-{\n-\tunsigned int i;\n-\tunsigned int elts_n = rxq->elts_n;\n-\tstruct rxq_elt_sp (*elts)[elts_n] = rxq->elts.sp;\n-\n-\tDEBUG(\"%p: freeing WRs\", (void *)rxq);\n-\trxq->elts_n = 0;\n-\trxq->elts.sp = NULL;\n-\tif (elts == NULL)\n-\t\treturn;\n-\tfor (i = 0; (i != elemof(*elts)); ++i) {\n-\t\tunsigned int j;\n-\t\tstruct rxq_elt_sp *elt = &(*elts)[i];\n-\n-\t\tfor (j = 0; (j != elemof(elt->bufs)); ++j) {\n-\t\t\tstruct rte_mbuf *buf = elt->bufs[j];\n-\n-\t\t\tif (buf != NULL)\n-\t\t\t\trte_pktmbuf_free_seg(buf);\n-\t\t}\n-\t}\n-\trte_free(elts);\n-}\n-\n-/**\n  * Allocate RX queue elements.\n  *\n  * @param rxq\n@@ -1859,7 +1518,7 @@ rxq_alloc_elts(struct rxq *rxq, unsigned int elts_n, struct rte_mbuf **pool)\n \t      (void *)rxq, elts_n);\n \trxq->elts_n = elts_n;\n \trxq->elts_head = 0;\n-\trxq->elts.no_sp = elts;\n+\trxq->elts = elts;\n \tassert(ret == 0);\n \treturn 0;\n error:\n@@ -1894,11 +1553,11 @@ rxq_free_elts(struct rxq *rxq)\n {\n \tunsigned int i;\n \tunsigned int elts_n = rxq->elts_n;\n-\tstruct rxq_elt (*elts)[elts_n] = rxq->elts.no_sp;\n+\tstruct rxq_elt (*elts)[elts_n] = rxq->elts;\n \n \tDEBUG(\"%p: freeing WRs\", (void *)rxq);\n \trxq->elts_n = 0;\n-\trxq->elts.no_sp = NULL;\n+\trxq->elts = NULL;\n \tif (elts == NULL)\n \t\treturn;\n \tfor (i = 0; (i != elemof(*elts)); ++i) {\n@@ -2034,10 +1693,7 @@ rxq_cleanup(struct rxq *rxq)\n \tstruct ibv_exp_release_intf_params params;\n \n \tDEBUG(\"cleaning up %p\", (void *)rxq);\n-\tif (rxq->sp)\n-\t\trxq_free_elts_sp(rxq);\n-\telse\n-\t\trxq_free_elts(rxq);\n+\trxq_free_elts(rxq);\n \tif (rxq->if_qp != NULL) {\n \t\tassert(rxq->priv != NULL);\n \t\tassert(rxq->priv->ctx != NULL);\n@@ -2082,230 +1738,10 @@ rxq_cleanup(struct rxq *rxq)\n \tmemset(rxq, 0, sizeof(*rxq));\n }\n \n-static uint16_t\n-mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n);\n-\n-/**\n- * DPDK callback for RX with scattered packets support.\n- *\n- * @param dpdk_rxq\n- *   Generic pointer to RX queue structure.\n- * @param[out] pkts\n- *   Array to store received packets.\n- * @param pkts_n\n- *   Maximum number of packets in array.\n- *\n- * @return\n- *   Number of packets successfully received (<= pkts_n).\n- */\n-static uint16_t\n-mlx4_rx_burst_sp(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)\n-{\n-\tstruct rxq *rxq = (struct rxq *)dpdk_rxq;\n-\tstruct rxq_elt_sp (*elts)[rxq->elts_n] = rxq->elts.sp;\n-\tconst unsigned int elts_n = rxq->elts_n;\n-\tunsigned int elts_head = rxq->elts_head;\n-\tstruct ibv_recv_wr head;\n-\tstruct ibv_recv_wr **next = &head.next;\n-\tstruct ibv_recv_wr *bad_wr;\n-\tunsigned int i;\n-\tunsigned int pkts_ret = 0;\n-\tint ret;\n-\n-\tif (unlikely(!rxq->sp))\n-\t\treturn mlx4_rx_burst(dpdk_rxq, pkts, pkts_n);\n-\tif (unlikely(elts == NULL)) /* See RTE_DEV_CMD_SET_MTU. */\n-\t\treturn 0;\n-\tfor (i = 0; (i != pkts_n); ++i) {\n-\t\tstruct rxq_elt_sp *elt = &(*elts)[elts_head];\n-\t\tstruct ibv_recv_wr *wr = &elt->wr;\n-\t\tuint64_t wr_id = wr->wr_id;\n-\t\tunsigned int len;\n-\t\tunsigned int pkt_buf_len;\n-\t\tstruct rte_mbuf *pkt_buf = NULL; /* Buffer returned in pkts. */\n-\t\tstruct rte_mbuf **pkt_buf_next = &pkt_buf;\n-\t\tunsigned int seg_headroom = RTE_PKTMBUF_HEADROOM;\n-\t\tunsigned int j = 0;\n-\t\tuint32_t flags;\n-\n-\t\t/* Sanity checks. */\n-#ifdef NDEBUG\n-\t\t(void)wr_id;\n-#endif\n-\t\tassert(wr_id < rxq->elts_n);\n-\t\tassert(wr->sg_list == elt->sges);\n-\t\tassert(wr->num_sge == elemof(elt->sges));\n-\t\tassert(elts_head < rxq->elts_n);\n-\t\tassert(rxq->elts_head < rxq->elts_n);\n-\t\tret = rxq->if_cq->poll_length_flags(rxq->cq, NULL, NULL,\n-\t\t\t\t\t\t    &flags);\n-\t\tif (unlikely(ret < 0)) {\n-\t\t\tstruct ibv_wc wc;\n-\t\t\tint wcs_n;\n-\n-\t\t\tDEBUG(\"rxq=%p, poll_length() failed (ret=%d)\",\n-\t\t\t      (void *)rxq, ret);\n-\t\t\t/* ibv_poll_cq() must be used in case of failure. */\n-\t\t\twcs_n = ibv_poll_cq(rxq->cq, 1, &wc);\n-\t\t\tif (unlikely(wcs_n == 0))\n-\t\t\t\tbreak;\n-\t\t\tif (unlikely(wcs_n < 0)) {\n-\t\t\t\tDEBUG(\"rxq=%p, ibv_poll_cq() failed (wcs_n=%d)\",\n-\t\t\t\t      (void *)rxq, wcs_n);\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t\tassert(wcs_n == 1);\n-\t\t\tif (unlikely(wc.status != IBV_WC_SUCCESS)) {\n-\t\t\t\t/* Whatever, just repost the offending WR. */\n-\t\t\t\tDEBUG(\"rxq=%p, wr_id=%\" PRIu64 \": bad work\"\n-\t\t\t\t      \" completion status (%d): %s\",\n-\t\t\t\t      (void *)rxq, wc.wr_id, wc.status,\n-\t\t\t\t      ibv_wc_status_str(wc.status));\n-\t\t\t\t/* Increment dropped packets counter. */\n-\t\t\t\t++rxq->stats.idropped;\n-\t\t\t\t/* Link completed WRs together for repost. */\n-\t\t\t\t*next = wr;\n-\t\t\t\tnext = &wr->next;\n-\t\t\t\tgoto repost;\n-\t\t\t}\n-\t\t\tret = wc.byte_len;\n-\t\t}\n-\t\tif (ret == 0)\n-\t\t\tbreak;\n-\t\tlen = ret;\n-\t\tpkt_buf_len = len;\n-\t\t/* Link completed WRs together for repost. */\n-\t\t*next = wr;\n-\t\tnext = &wr->next;\n-\t\t/*\n-\t\t * Replace spent segments with new ones, concatenate and\n-\t\t * return them as pkt_buf.\n-\t\t */\n-\t\twhile (1) {\n-\t\t\tstruct ibv_sge *sge = &elt->sges[j];\n-\t\t\tstruct rte_mbuf *seg = elt->bufs[j];\n-\t\t\tstruct rte_mbuf *rep;\n-\t\t\tunsigned int seg_tailroom;\n-\n-\t\t\t/*\n-\t\t\t * Fetch initial bytes of packet descriptor into a\n-\t\t\t * cacheline while allocating rep.\n-\t\t\t */\n-\t\t\trte_prefetch0(seg);\n-\t\t\trep = rte_mbuf_raw_alloc(rxq->mp);\n-\t\t\tif (unlikely(rep == NULL)) {\n-\t\t\t\t/*\n-\t\t\t\t * Unable to allocate a replacement mbuf,\n-\t\t\t\t * repost WR.\n-\t\t\t\t */\n-\t\t\t\tDEBUG(\"rxq=%p, wr_id=%\" PRIu64 \":\"\n-\t\t\t\t      \" can't allocate a new mbuf\",\n-\t\t\t\t      (void *)rxq, wr_id);\n-\t\t\t\tif (pkt_buf != NULL) {\n-\t\t\t\t\t*pkt_buf_next = NULL;\n-\t\t\t\t\trte_pktmbuf_free(pkt_buf);\n-\t\t\t\t}\n-\t\t\t\t/* Increase out of memory counters. */\n-\t\t\t\t++rxq->stats.rx_nombuf;\n-\t\t\t\t++rxq->priv->dev->data->rx_mbuf_alloc_failed;\n-\t\t\t\tgoto repost;\n-\t\t\t}\n-#ifndef NDEBUG\n-\t\t\t/* Poison user-modifiable fields in rep. */\n-\t\t\tNEXT(rep) = (void *)((uintptr_t)-1);\n-\t\t\tSET_DATA_OFF(rep, 0xdead);\n-\t\t\tDATA_LEN(rep) = 0xd00d;\n-\t\t\tPKT_LEN(rep) = 0xdeadd00d;\n-\t\t\tNB_SEGS(rep) = 0x2a;\n-\t\t\tPORT(rep) = 0x2a;\n-\t\t\trep->ol_flags = -1;\n-\t\t\t/*\n-\t\t\t * Clear special flags in mbuf to avoid\n-\t\t\t * crashing while freeing.\n-\t\t\t */\n-\t\t\trep->ol_flags &=\n-\t\t\t\t~(uint64_t)(IND_ATTACHED_MBUF |\n-\t\t\t\t\t    CTRL_MBUF_FLAG);\n-#endif\n-\t\t\tassert(rep->buf_len == seg->buf_len);\n-\t\t\t/* Reconfigure sge to use rep instead of seg. */\n-\t\t\tassert(sge->lkey == rxq->mr->lkey);\n-\t\t\tsge->addr = ((uintptr_t)rep->buf_addr + seg_headroom);\n-\t\t\telt->bufs[j] = rep;\n-\t\t\t++j;\n-\t\t\t/* Update pkt_buf if it's the first segment, or link\n-\t\t\t * seg to the previous one and update pkt_buf_next. */\n-\t\t\t*pkt_buf_next = seg;\n-\t\t\tpkt_buf_next = &NEXT(seg);\n-\t\t\t/* Update seg information. */\n-\t\t\tseg_tailroom = (seg->buf_len - seg_headroom);\n-\t\t\tassert(sge->length == seg_tailroom);\n-\t\t\tSET_DATA_OFF(seg, seg_headroom);\n-\t\t\tif (likely(len <= seg_tailroom)) {\n-\t\t\t\t/* Last segment. */\n-\t\t\t\tDATA_LEN(seg) = len;\n-\t\t\t\tPKT_LEN(seg) = len;\n-\t\t\t\t/* Sanity check. */\n-\t\t\t\tassert(rte_pktmbuf_headroom(seg) ==\n-\t\t\t\t       seg_headroom);\n-\t\t\t\tassert(rte_pktmbuf_tailroom(seg) ==\n-\t\t\t\t       (seg_tailroom - len));\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t\tDATA_LEN(seg) = seg_tailroom;\n-\t\t\tPKT_LEN(seg) = seg_tailroom;\n-\t\t\t/* Sanity check. */\n-\t\t\tassert(rte_pktmbuf_headroom(seg) == seg_headroom);\n-\t\t\tassert(rte_pktmbuf_tailroom(seg) == 0);\n-\t\t\t/* Fix len and clear headroom for next segments. */\n-\t\t\tlen -= seg_tailroom;\n-\t\t\tseg_headroom = 0;\n-\t\t}\n-\t\t/* Update head and tail segments. */\n-\t\t*pkt_buf_next = NULL;\n-\t\tassert(pkt_buf != NULL);\n-\t\tassert(j != 0);\n-\t\tNB_SEGS(pkt_buf) = j;\n-\t\tPORT(pkt_buf) = rxq->port_id;\n-\t\tPKT_LEN(pkt_buf) = pkt_buf_len;\n-\t\tpkt_buf->packet_type = 0;\n-\t\tpkt_buf->ol_flags = 0;\n-\n-\t\t/* Return packet. */\n-\t\t*(pkts++) = pkt_buf;\n-\t\t++pkts_ret;\n-\t\t/* Increase bytes counter. */\n-\t\trxq->stats.ibytes += pkt_buf_len;\n-repost:\n-\t\tif (++elts_head >= elts_n)\n-\t\t\telts_head = 0;\n-\t\tcontinue;\n-\t}\n-\tif (unlikely(i == 0))\n-\t\treturn 0;\n-\t*next = NULL;\n-\t/* Repost WRs. */\n-\tret = ibv_post_recv(rxq->qp, head.next, &bad_wr);\n-\tif (unlikely(ret)) {\n-\t\t/* Inability to repost WRs is fatal. */\n-\t\tDEBUG(\"%p: ibv_post_recv(): failed for WR %p: %s\",\n-\t\t      (void *)rxq->priv,\n-\t\t      (void *)bad_wr,\n-\t\t      strerror(ret));\n-\t\tabort();\n-\t}\n-\trxq->elts_head = elts_head;\n-\t/* Increase packets counter. */\n-\trxq->stats.ipackets += pkts_ret;\n-\treturn pkts_ret;\n-}\n-\n /**\n  * DPDK callback for RX.\n  *\n- * The following function is the same as mlx4_rx_burst_sp(), except it doesn't\n- * manage scattered packets. Improves performance when MRU is lower than the\n- * size of the first segment.\n+ * The following function doesn't manage scattered packets.\n  *\n  * @param dpdk_rxq\n  *   Generic pointer to RX queue structure.\n@@ -2321,7 +1757,7 @@ static uint16_t\n mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)\n {\n \tstruct rxq *rxq = (struct rxq *)dpdk_rxq;\n-\tstruct rxq_elt (*elts)[rxq->elts_n] = rxq->elts.no_sp;\n+\tstruct rxq_elt (*elts)[rxq->elts_n] = rxq->elts;\n \tconst unsigned int elts_n = rxq->elts_n;\n \tunsigned int elts_head = rxq->elts_head;\n \tstruct ibv_sge sges[pkts_n];\n@@ -2329,8 +1765,6 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)\n \tunsigned int pkts_ret = 0;\n \tint ret;\n \n-\tif (unlikely(rxq->sp))\n-\t\treturn mlx4_rx_burst_sp(dpdk_rxq, pkts, pkts_n);\n \tfor (i = 0; (i != pkts_n); ++i) {\n \t\tstruct rxq_elt *elt = &(*elts)[elts_head];\n \t\tstruct ibv_recv_wr *wr = &elt->wr;\n@@ -2482,10 +1916,7 @@ rxq_setup_qp(struct priv *priv, struct ibv_cq *cq, uint16_t desc,\n \t\t\t\t\tpriv->device_attr.max_qp_wr :\n \t\t\t\t\tdesc),\n \t\t\t/* Max number of scatter/gather elements in a WR. */\n-\t\t\t.max_recv_sge = ((priv->device_attr.max_sge <\n-\t\t\t\t\t  MLX4_PMD_SGE_WR_N) ?\n-\t\t\t\t\t priv->device_attr.max_sge :\n-\t\t\t\t\t MLX4_PMD_SGE_WR_N),\n+\t\t\t.max_recv_sge = 1,\n \t\t},\n \t\t.qp_type = IBV_QPT_RAW_PACKET,\n \t\t.comp_mask = (IBV_EXP_QP_INIT_ATTR_PD |\n@@ -2500,165 +1931,6 @@ rxq_setup_qp(struct priv *priv, struct ibv_cq *cq, uint16_t desc,\n }\n \n /**\n- * Reconfigure a RX queue with new parameters.\n- *\n- * rxq_rehash() does not allocate mbufs, which, if not done from the right\n- * thread (such as a control thread), may corrupt the pool.\n- * In case of failure, the queue is left untouched.\n- *\n- * @param dev\n- *   Pointer to Ethernet device structure.\n- * @param rxq\n- *   RX queue pointer.\n- *\n- * @return\n- *   0 on success, errno value on failure.\n- */\n-static int\n-rxq_rehash(struct rte_eth_dev *dev, struct rxq *rxq)\n-{\n-\tstruct priv *priv = rxq->priv;\n-\tstruct rxq tmpl = *rxq;\n-\tunsigned int mbuf_n;\n-\tunsigned int desc_n;\n-\tstruct rte_mbuf **pool;\n-\tunsigned int i, k;\n-\tstruct ibv_exp_qp_attr mod;\n-\tstruct ibv_recv_wr *bad_wr;\n-\tunsigned int mb_len;\n-\tint err;\n-\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-\tdesc_n = (tmpl.elts_n * (tmpl.sp ? MLX4_PMD_SGE_WR_N : 1));\n-\tmbuf_n = desc_n;\n-\t/* Enable scattered packets support for this queue if necessary. */\n-\tassert(mb_len >= RTE_PKTMBUF_HEADROOM);\n-\tif (dev->data->dev_conf.rxmode.enable_scatter &&\n-\t    (dev->data->dev_conf.rxmode.max_rx_pkt_len >\n-\t     (mb_len - RTE_PKTMBUF_HEADROOM))) {\n-\t\ttmpl.sp = 1;\n-\t\tdesc_n /= MLX4_PMD_SGE_WR_N;\n-\t} else\n-\t\ttmpl.sp = 0;\n-\tDEBUG(\"%p: %s scattered packets support (%u WRs)\",\n-\t      (void *)dev, (tmpl.sp ? \"enabling\" : \"disabling\"), desc_n);\n-\t/* If scatter mode is the same as before, nothing to do. */\n-\tif (tmpl.sp == rxq->sp) {\n-\t\tDEBUG(\"%p: nothing to do\", (void *)dev);\n-\t\treturn 0;\n-\t}\n-\t/* From now on, any failure will render the queue unusable.\n-\t * Reinitialize QP. */\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-\t\tERROR(\"%p: cannot reset QP: %s\", (void *)dev, strerror(err));\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-\t\t/* Primary port number. */\n-\t\t.port_num = priv->port\n-\t};\n-\terr = ibv_exp_modify_qp(tmpl.qp, &mod,\n-\t\t\t\tIBV_EXP_QP_STATE |\n-\t\t\t\tIBV_EXP_QP_PORT);\n-\tif (err) {\n-\t\tERROR(\"%p: QP state to IBV_QPS_INIT failed: %s\",\n-\t\t      (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-\t\tERROR(\"%p: cannot allocate memory\", (void *)dev);\n-\t\treturn ENOBUFS;\n-\t}\n-\t/* Snatch mbufs from original queue. */\n-\tk = 0;\n-\tif (rxq->sp) {\n-\t\tstruct rxq_elt_sp (*elts)[rxq->elts_n] = rxq->elts.sp;\n-\n-\t\tfor (i = 0; (i != elemof(*elts)); ++i) {\n-\t\t\tstruct rxq_elt_sp *elt = &(*elts)[i];\n-\t\t\tunsigned int j;\n-\n-\t\t\tfor (j = 0; (j != elemof(elt->bufs)); ++j) {\n-\t\t\t\tassert(elt->bufs[j] != NULL);\n-\t\t\t\tpool[k++] = elt->bufs[j];\n-\t\t\t}\n-\t\t}\n-\t} else {\n-\t\tstruct rxq_elt (*elts)[rxq->elts_n] = rxq->elts.no_sp;\n-\n-\t\tfor (i = 0; (i != elemof(*elts)); ++i) {\n-\t\t\tstruct rxq_elt *elt = &(*elts)[i];\n-\t\t\tstruct rte_mbuf *buf = (void *)\n-\t\t\t\t((uintptr_t)elt->sge.addr -\n-\t\t\t\t WR_ID(elt->wr.wr_id).offset);\n-\n-\t\t\tassert(WR_ID(elt->wr.wr_id).id == i);\n-\t\t\tpool[k++] = buf;\n-\t\t}\n-\t}\n-\tassert(k == mbuf_n);\n-\ttmpl.elts_n = 0;\n-\ttmpl.elts.sp = NULL;\n-\tassert((void *)&tmpl.elts.sp == (void *)&tmpl.elts.no_sp);\n-\terr = ((tmpl.sp) ?\n-\t       rxq_alloc_elts_sp(&tmpl, desc_n, pool) :\n-\t       rxq_alloc_elts(&tmpl, desc_n, pool));\n-\tif (err) {\n-\t\tERROR(\"%p: cannot reallocate WRs, aborting\", (void *)dev);\n-\t\trte_free(pool);\n-\t\tassert(err > 0);\n-\t\treturn err;\n-\t}\n-\tassert(tmpl.elts_n == desc_n);\n-\tassert(tmpl.elts.sp != NULL);\n-\trte_free(pool);\n-\t/* Clean up original data. */\n-\trxq->elts_n = 0;\n-\trte_free(rxq->elts.sp);\n-\trxq->elts.sp = NULL;\n-\t/* Post WRs. */\n-\terr = 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 (err) {\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(err));\n-\t\tgoto skip_rtr;\n-\t}\n-\tmod = (struct ibv_exp_qp_attr){\n-\t\t.qp_state = IBV_QPS_RTR\n-\t};\n-\terr = ibv_exp_modify_qp(tmpl.qp, &mod, IBV_EXP_QP_STATE);\n-\tif (err)\n-\t\tERROR(\"%p: QP state to IBV_QPS_RTR failed: %s\",\n-\t\t      (void *)dev, strerror(err));\n-skip_rtr:\n-\t*rxq = tmpl;\n-\tassert(err >= 0);\n-\treturn err;\n-}\n-\n-/**\n  * Configure a RX queue.\n  *\n  * @param dev\n@@ -2701,19 +1973,19 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,\n \n \t(void)conf; /* Thresholds configuration (ignored). */\n \tmb_len = rte_pktmbuf_data_room_size(mp);\n-\tif ((desc == 0) || (desc % MLX4_PMD_SGE_WR_N)) {\n-\t\tERROR(\"%p: invalid number of RX descriptors (must be a\"\n-\t\t      \" multiple of %d)\", (void *)dev, MLX4_PMD_SGE_WR_N);\n+\tif (desc == 0) {\n+\t\tERROR(\"%p: invalid number of RX descriptors\", (void *)dev);\n \t\treturn EINVAL;\n \t}\n \t/* Enable scattered packets support for this queue if necessary. */\n \tassert(mb_len >= RTE_PKTMBUF_HEADROOM);\n \tif (dev->data->dev_conf.rxmode.max_rx_pkt_len <=\n \t    (mb_len - RTE_PKTMBUF_HEADROOM)) {\n-\t\ttmpl.sp = 0;\n+\t\t;\n \t} else if (dev->data->dev_conf.rxmode.enable_scatter) {\n-\t\ttmpl.sp = 1;\n-\t\tdesc /= MLX4_PMD_SGE_WR_N;\n+\t\tWARN(\"%p: scattered mode has been requested but is\"\n+\t\t     \" not supported, this may lead to packet loss\",\n+\t\t     (void *)dev);\n \t} else {\n \t\tWARN(\"%p: the requested maximum Rx packet size (%u) is\"\n \t\t     \" larger than a single mbuf (%u) and scattered\"\n@@ -2722,8 +1994,6 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,\n \t\t     dev->data->dev_conf.rxmode.max_rx_pkt_len,\n \t\t     mb_len - RTE_PKTMBUF_HEADROOM);\n \t}\n-\tDEBUG(\"%p: %s scattered packets support (%u WRs)\",\n-\t      (void *)dev, (tmpl.sp ? \"enabling\" : \"disabling\"), desc);\n \t/* Use the entire RX mempool as the memory region. */\n \ttmpl.mr = mlx4_mp2mr(priv->pd, mp);\n \tif (tmpl.mr == NULL) {\n@@ -2792,20 +2062,13 @@ rxq_setup(struct rte_eth_dev *dev, struct rxq *rxq, uint16_t desc,\n \t\t      (void *)dev, strerror(ret));\n \t\tgoto error;\n \t}\n-\tif (tmpl.sp)\n-\t\tret = rxq_alloc_elts_sp(&tmpl, desc, NULL);\n-\telse\n-\t\tret = rxq_alloc_elts(&tmpl, desc, NULL);\n+\tret = rxq_alloc_elts(&tmpl, desc, NULL);\n \tif (ret) {\n \t\tERROR(\"%p: RXQ allocation failed: %s\",\n \t\t      (void *)dev, strerror(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+\tret = ibv_post_recv(tmpl.qp, &(*tmpl.elts)[0].wr, &bad_wr);\n \tif (ret) {\n \t\tERROR(\"%p: ibv_post_recv() failed for WR %p: %s\",\n \t\t      (void *)dev,\n@@ -2926,10 +2189,7 @@ mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,\n \t\t      (void *)dev, (void *)rxq);\n \t\t(*priv->rxqs)[idx] = rxq;\n \t\t/* Update receive callback. */\n-\t\tif (rxq->sp)\n-\t\t\tdev->rx_pkt_burst = mlx4_rx_burst_sp;\n-\t\telse\n-\t\t\tdev->rx_pkt_burst = mlx4_rx_burst;\n+\t\tdev->rx_pkt_burst = mlx4_rx_burst;\n \t}\n \tpriv_unlock(priv);\n \treturn -ret;\n@@ -3205,23 +2465,12 @@ priv_set_link(struct priv *priv, int up)\n {\n \tstruct rte_eth_dev *dev = priv->dev;\n \tint err;\n-\tunsigned int i;\n \n \tif (up) {\n \t\terr = priv_set_flags(priv, ~IFF_UP, IFF_UP);\n \t\tif (err)\n \t\t\treturn err;\n-\t\tfor (i = 0; i < priv->rxqs_n; i++)\n-\t\t\tif ((*priv->rxqs)[i]->sp)\n-\t\t\t\tbreak;\n-\t\t/* Check if an sp queue exists.\n-\t\t * Note: Some old frames might be received.\n-\t\t */\n-\t\tif (i == priv->rxqs_n)\n-\t\t\tdev->rx_pkt_burst = mlx4_rx_burst;\n-\t\telse\n-\t\t\tdev->rx_pkt_burst = mlx4_rx_burst_sp;\n-\t\tdev->tx_pkt_burst = mlx4_tx_burst;\n+\t\tdev->rx_pkt_burst = mlx4_rx_burst;\n \t} else {\n \t\terr = priv_set_flags(priv, ~IFF_UP, ~IFF_UP);\n \t\tif (err)\n@@ -3469,12 +2718,6 @@ mlx4_link_update(struct rte_eth_dev *dev, int wait_to_complete)\n /**\n  * DPDK callback to change the MTU.\n  *\n- * Setting the MTU affects hardware MRU (packets larger than the MTU cannot be\n- * received). Use this as a hint to enable/disable scattered packets support\n- * and improve performance when not needed.\n- * Since failure is not an option, reconfiguring queues on the fly is not\n- * recommended.\n- *\n  * @param dev\n  *   Pointer to Ethernet device structure.\n  * @param in_mtu\n@@ -3488,9 +2731,6 @@ mlx4_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)\n {\n \tstruct priv *priv = dev->data->dev_private;\n \tint ret = 0;\n-\tunsigned int i;\n-\tuint16_t (*rx_func)(void *, struct rte_mbuf **, uint16_t) =\n-\t\tmlx4_rx_burst;\n \n \tpriv_lock(priv);\n \t/* Set kernel interface MTU first. */\n@@ -3502,45 +2742,6 @@ mlx4_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)\n \t} else\n \t\tDEBUG(\"adapter port %u MTU set to %u\", priv->port, mtu);\n \tpriv->mtu = mtu;\n-\t/* Remove MAC flow. */\n-\tpriv_mac_addr_del(priv);\n-\t/* Temporarily replace RX handler with a fake one, assuming it has not\n-\t * been copied elsewhere. */\n-\tdev->rx_pkt_burst = removed_rx_burst;\n-\t/* Make sure everyone has left mlx4_rx_burst() and uses\n-\t * removed_rx_burst() instead. */\n-\trte_wmb();\n-\tusleep(1000);\n-\t/* Reconfigure each RX queue. */\n-\tfor (i = 0; (i != priv->rxqs_n); ++i) {\n-\t\tstruct rxq *rxq = (*priv->rxqs)[i];\n-\t\tunsigned int max_frame_len;\n-\n-\t\tif (rxq == NULL)\n-\t\t\tcontinue;\n-\t\t/* Calculate new maximum frame length according to MTU. */\n-\t\tmax_frame_len = (priv->mtu + ETHER_HDR_LEN +\n-\t\t\t\t (ETHER_MAX_VLAN_FRAME_LEN - ETHER_MAX_LEN));\n-\t\t/* Provide new values to rxq_setup(). */\n-\t\tdev->data->dev_conf.rxmode.jumbo_frame =\n-\t\t\t(max_frame_len > ETHER_MAX_LEN);\n-\t\tdev->data->dev_conf.rxmode.max_rx_pkt_len = max_frame_len;\n-\t\tret = rxq_rehash(dev, rxq);\n-\t\tif (ret) {\n-\t\t\t/* Force SP RX if that queue requires it and abort. */\n-\t\t\tif (rxq->sp)\n-\t\t\t\trx_func = mlx4_rx_burst_sp;\n-\t\t\tbreak;\n-\t\t}\n-\t\t/* Scattered burst function takes priority. */\n-\t\tif (rxq->sp)\n-\t\t\trx_func = mlx4_rx_burst_sp;\n-\t}\n-\t/* Burst functions can now be called again. */\n-\trte_wmb();\n-\tdev->rx_pkt_burst = rx_func;\n-\t/* Restore MAC flow. */\n-\tret = priv_mac_addr_add(priv);\n out:\n \tpriv_unlock(priv);\n \tassert(ret >= 0);\ndiff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h\nindex 5a0a7a1..38c93f1 100644\n--- a/drivers/net/mlx4/mlx4.h\n+++ b/drivers/net/mlx4/mlx4.h\n@@ -66,9 +66,6 @@\n /* Request send completion once in every 64 sends, might be less. */\n #define MLX4_PMD_TX_PER_COMP_REQ 64\n \n-/* Maximum number of Scatter/Gather Elements per Work Request. */\n-#define MLX4_PMD_SGE_WR_N 4\n-\n /* Maximum size for inline data. */\n #define MLX4_PMD_MAX_INLINE 0\n \n@@ -141,13 +138,6 @@ struct mlx4_rxq_stats {\n \tuint64_t rx_nombuf; /**< Total of RX mbuf allocation failures. */\n };\n \n-/* RX element (scattered packets). */\n-struct rxq_elt_sp {\n-\tstruct ibv_recv_wr wr; /* Work Request. */\n-\tstruct ibv_sge sges[MLX4_PMD_SGE_WR_N]; /* Scatter/Gather Elements. */\n-\tstruct rte_mbuf *bufs[MLX4_PMD_SGE_WR_N]; /* SGEs buffers. */\n-};\n-\n /* RX element. */\n struct rxq_elt {\n \tstruct ibv_recv_wr wr; /* Work Request. */\n@@ -168,11 +158,7 @@ struct rxq {\n \tunsigned int port_id; /* Port ID for incoming packets. */\n \tunsigned int elts_n; /* (*elts)[] length. */\n \tunsigned int elts_head; /* Current index in (*elts)[]. */\n-\tunion {\n-\t\tstruct rxq_elt_sp (*sp)[]; /* Scattered RX elements. */\n-\t\tstruct rxq_elt (*no_sp)[]; /* RX elements. */\n-\t} elts;\n-\tunsigned int sp:1; /* Use scattered RX elements. */\n+\tstruct rxq_elt (*elts)[]; /* RX elements. */\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@@ -190,16 +176,6 @@ struct mlx4_txq_stats {\n \tuint64_t odropped; /**< Total of packets not sent when TX ring full. */\n };\n \n-/*\n- * Linear buffer type. It is used when transmitting buffers with too many\n- * segments that do not fit the hardware queue (see max_send_sge).\n- * Extra segments are copied (linearized) in such buffers, replacing the\n- * last SGE during TX.\n- * The size is arbitrary but large enough to hold a jumbo frame with\n- * 8 segments considering mbuf.buf_len is about 2048 bytes.\n- */\n-typedef uint8_t linear_t[16384];\n-\n /* TX queue descriptor. */\n struct txq {\n \tstruct priv *priv; /* Back pointer to private data. */\n@@ -221,8 +197,6 @@ struct txq {\n \tunsigned int elts_comp_cd; /* Countdown for next completion request. */\n \tunsigned int elts_comp_cd_init; /* Initial value for countdown. */\n \tstruct mlx4_txq_stats stats; /* TX queue counters. */\n-\tlinear_t (*elts_linear)[]; /* Linearized buffers. */\n-\tstruct ibv_mr *mr_linear; /* Memory Region for linearized buffers. */\n \tunsigned int socket; /* CPU socket ID for allocations. */\n \tstruct ibv_exp_res_domain *rd; /* Resource Domain. */\n };\n",
    "prefixes": [
        "dpdk-dev",
        "v1",
        "19/48"
    ]
}