Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/14329/?format=api
http://patches.dpdk.org/api/patches/14329/?format=api", "web_url": "http://patches.dpdk.org/project/dpdk/patch/1466758261-25986-18-git-send-email-nelio.laranjeiro@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": "<1466758261-25986-18-git-send-email-nelio.laranjeiro@6wind.com>", "list_archive_url": "https://inbox.dpdk.org/dev/1466758261-25986-18-git-send-email-nelio.laranjeiro@6wind.com", "date": "2016-06-24T08:50:53", "name": "[dpdk-dev,v6,17/25] mlx5: add support for inline send", "commit_ref": null, "pull_url": null, "state": "not-applicable", "archived": true, "hash": "b9667e6947448a2245756949c818e73e2af77669", "submitter": { "id": 243, "url": "http://patches.dpdk.org/api/people/243/?format=api", "name": "Nélio Laranjeiro", "email": "nelio.laranjeiro@6wind.com" }, "delegate": { "id": 10, "url": "http://patches.dpdk.org/api/users/10/?format=api", "username": "bruce", "first_name": "Bruce", "last_name": "Richardson", "email": "bruce.richardson@intel.com" }, "mbox": "http://patches.dpdk.org/project/dpdk/patch/1466758261-25986-18-git-send-email-nelio.laranjeiro@6wind.com/mbox/", "series": [], "comments": "http://patches.dpdk.org/api/patches/14329/comments/", "check": "pending", "checks": "http://patches.dpdk.org/api/patches/14329/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 78977C714;\n\tFri, 24 Jun 2016 10:53:55 +0200 (CEST)", "from mail-wm0-f51.google.com (mail-wm0-f51.google.com\n\t[74.125.82.51]) by dpdk.org (Postfix) with ESMTP id EE406C68E\n\tfor <dev@dpdk.org>; Fri, 24 Jun 2016 10:53:45 +0200 (CEST)", "by mail-wm0-f51.google.com with SMTP id a66so16019414wme.0\n\tfor <dev@dpdk.org>; Fri, 24 Jun 2016 01:53:45 -0700 (PDT)", "from ping.vm.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\tt188sm2060584wma.8.2016.06.24.01.53.44\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);\n\tFri, 24 Jun 2016 01:53:44 -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=6g1UYPO7JYBhkBGsZYCeMpv3qmPV+CYPDtYEPSCjPKM=;\n\tb=JbN5pe5YrpdlKO5jbvFKaS2ijQckk6SPte5xkzsxWTMT+TJ7hDOegSwZiLT2Jq9bhw\n\tqwK7tBtytqQdN0WmXwxOmnGmhd886U8/Yz6/8Q/1u8LIUowuvuNGmz3YxWdAn4gWQPAm\n\tnj68UISq/4wivfk69DjkF47uyzPKLOCSu0ItOJgLibEMhWwtGivnLEwnfHW8J8LGsOzx\n\t/f4o1TwkJv5FgFozyLOsLJwjHMm/Dovx50mBaMW+Gd1xnxiHHwIWAGcfKtX3XDwgbFTV\n\tfIzbrx589LtAzKjO4xJ81VYrXh7HulowH01cOSpiQST53kb6R3ybYsxQYvC3k83YS3vy\n\thYpg==", "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=6g1UYPO7JYBhkBGsZYCeMpv3qmPV+CYPDtYEPSCjPKM=;\n\tb=cCCHS1oJOVhkYKEFX91h/AfZ4Xgb7Z/nPqGvUAMpri7e1NKSJMs/RoojtKtk4si5b2\n\t5lRNSU1aOpG/0IPuM86KZbbot7gBnAFZKcFZZh2IAZ0wHVdA6UIj/tg1kzMz6kbKPtV/\n\tV1dsLsNjrobs8tzi+IJztb82O/XyvQ7EIBHDC5KwQlE6Z2+9isy+pkTI05HYDXON6Cb+\n\tR5D8d+zbMaCtUJuPTSuSudpMTSIlZg5HLCOUaju6m6/EUJKOs9n/knz75ja276gCoPxN\n\tcama2hxMN+hI5uDpUmoDLAVIyEaYmQEgL50/BdZ3J/PME7JW4u2mozYzvb0Qn5BQ6how\n\tahRw==", "X-Gm-Message-State": "ALyK8tKsnhl2sVE1DRGmHlbksk7IfcsE+vCa8pMsRAzs4mo4U4qodhHEeftgfrMyfaTcLyvt", "X-Received": "by 10.28.95.196 with SMTP id t187mr17976209wmb.89.1466758425388; \n\tFri, 24 Jun 2016 01:53:45 -0700 (PDT)", "From": "Nelio Laranjeiro <nelio.laranjeiro@6wind.com>", "To": "dev@dpdk.org", "Cc": "Bruce Richardson <bruce.richardson@intel.com>,\n\tFerruh Yigit <ferruh.yigit@intel.com>,\n\tYaacov Hazan <yaacovh@mellanox.com>, \n\tAdrien Mazarguil <adrien.mazarguil@6wind.com>", "Date": "Fri, 24 Jun 2016 10:50:53 +0200", "Message-Id": "<1466758261-25986-18-git-send-email-nelio.laranjeiro@6wind.com>", "X-Mailer": "git-send-email 2.1.4", "In-Reply-To": "<1466758261-25986-1-git-send-email-nelio.laranjeiro@6wind.com>", "References": "<1466700801-10383-1-git-send-email-nelio.laranjeiro@6wind.com>\n\t<1466758261-25986-1-git-send-email-nelio.laranjeiro@6wind.com>", "Subject": "[dpdk-dev] [PATCH v6 17/25] mlx5: add support for inline send", "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: Yaacov Hazan <yaacovh@mellanox.com>\n\nImplement send inline feature which copies packet data directly into WQEs\nfor improved latency. The maximum packet size and the minimum number of Tx\nqueues to qualify for inline send are user-configurable.\n\nThis feature is effective when HW causes a performance bottleneck.\n\nSigned-off-by: Yaacov Hazan <yaacovh@mellanox.com>\nSigned-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>\nSigned-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>\n---\n doc/guides/nics/mlx5.rst | 17 +++\n drivers/net/mlx5/mlx5.c | 15 +++\n drivers/net/mlx5/mlx5.h | 2 +\n drivers/net/mlx5/mlx5_ethdev.c | 5 +\n drivers/net/mlx5/mlx5_rxtx.c | 273 +++++++++++++++++++++++++++++++++++++++++\n drivers/net/mlx5/mlx5_rxtx.h | 2 +\n drivers/net/mlx5/mlx5_txq.c | 4 +\n 7 files changed, 318 insertions(+)", "diff": "diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst\nindex 756153b..9ada221 100644\n--- a/doc/guides/nics/mlx5.rst\n+++ b/doc/guides/nics/mlx5.rst\n@@ -154,6 +154,23 @@ Run-time configuration\n allows to save PCI bandwidth and improve performance at the cost of a\n slightly higher CPU usage. Enabled by default.\n \n+- ``txq_inline`` parameter [int]\n+\n+ Amount of data to be inlined during TX operations. Improves latency.\n+ Can improve PPS performance when PCI back pressure is detected and may be\n+ useful for scenarios involving heavy traffic on many queues.\n+\n+ It is not enabled by default (set to 0) since the additional software\n+ logic necessary to handle this mode can lower performance when back\n+ pressure is not expected.\n+\n+- ``txqs_min_inline`` parameter [int]\n+\n+ Enable inline send only when the number of TX queues is greater or equal\n+ to this value.\n+\n+ This option should be used in combination with ``txq_inline`` above.\n+\n Prerequisites\n -------------\n \ndiff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c\nindex 0257d34..2d63a48 100644\n--- a/drivers/net/mlx5/mlx5.c\n+++ b/drivers/net/mlx5/mlx5.c\n@@ -72,6 +72,15 @@\n /* Device parameter to enable RX completion queue compression. */\n #define MLX5_RXQ_CQE_COMP_EN \"rxq_cqe_comp_en\"\n \n+/* Device parameter to configure inline send. */\n+#define MLX5_TXQ_INLINE \"txq_inline\"\n+\n+/*\n+ * Device parameter to configure the number of TX queues threshold for\n+ * enabling inline send.\n+ */\n+#define MLX5_TXQS_MIN_INLINE \"txqs_min_inline\"\n+\n /**\n * Retrieve integer value from environment variable.\n *\n@@ -269,6 +278,10 @@ mlx5_args_check(const char *key, const char *val, void *opaque)\n \t}\n \tif (strcmp(MLX5_RXQ_CQE_COMP_EN, key) == 0) {\n \t\tpriv->cqe_comp = !!tmp;\n+\t} else if (strcmp(MLX5_TXQ_INLINE, key) == 0) {\n+\t\tpriv->txq_inline = tmp;\n+\t} else if (strcmp(MLX5_TXQS_MIN_INLINE, key) == 0) {\n+\t\tpriv->txqs_inline = tmp;\n \t} else {\n \t\tWARN(\"%s: unknown parameter\", key);\n \t\treturn -EINVAL;\n@@ -292,6 +305,8 @@ mlx5_args(struct priv *priv, struct rte_devargs *devargs)\n {\n \tconst char **params = (const char *[]){\n \t\tMLX5_RXQ_CQE_COMP_EN,\n+\t\tMLX5_TXQ_INLINE,\n+\t\tMLX5_TXQS_MIN_INLINE,\n \t};\n \tstruct rte_kvargs *kvlist;\n \tint ret = 0;\ndiff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex 8f5a6df..3a86609 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -113,6 +113,8 @@ struct priv {\n \tunsigned int mps:1; /* Whether multi-packet send is supported. */\n \tunsigned int cqe_comp:1; /* Whether CQE compression is enabled. */\n \tunsigned int pending_alarm:1; /* An alarm is pending. */\n+\tunsigned int txq_inline; /* Maximum packet size for inlining. */\n+\tunsigned int txqs_inline; /* Queue number threshold for inlining. */\n \t/* RX/TX queues. */\n \tunsigned int rxqs_n; /* RX queues array size. */\n \tunsigned int txqs_n; /* TX queues array size. */\ndiff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c\nindex 47e64b2..aeea4ff 100644\n--- a/drivers/net/mlx5/mlx5_ethdev.c\n+++ b/drivers/net/mlx5/mlx5_ethdev.c\n@@ -1318,6 +1318,11 @@ void\n priv_select_tx_function(struct priv *priv)\n {\n \tpriv->dev->tx_pkt_burst = mlx5_tx_burst;\n+\tif (priv->txq_inline && (priv->txqs_n >= priv->txqs_inline)) {\n+\t\tpriv->dev->tx_pkt_burst = mlx5_tx_burst_inline;\n+\t\tDEBUG(\"selected inline TX function (%u >= %u queues)\",\n+\t\t priv->txqs_n, priv->txqs_inline);\n+\t}\n }\n \n /**\ndiff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c\nindex 9d992c3..daa22d9 100644\n--- a/drivers/net/mlx5/mlx5_rxtx.c\n+++ b/drivers/net/mlx5/mlx5_rxtx.c\n@@ -376,6 +376,139 @@ mlx5_wqe_write_vlan(struct txq *txq, volatile union mlx5_wqe *wqe,\n }\n \n /**\n+ * Write a inline WQE.\n+ *\n+ * @param txq\n+ * Pointer to TX queue structure.\n+ * @param wqe\n+ * Pointer to the WQE to fill.\n+ * @param addr\n+ * Buffer data address.\n+ * @param length\n+ * Packet length.\n+ * @param lkey\n+ * Memory region lkey.\n+ */\n+static inline void\n+mlx5_wqe_write_inline(struct txq *txq, volatile union mlx5_wqe *wqe,\n+\t\t uintptr_t addr, uint32_t length)\n+{\n+\tuint32_t size;\n+\tuint16_t wqe_cnt = txq->wqe_n - 1;\n+\tuint16_t wqe_ci = txq->wqe_ci + 1;\n+\n+\t/* Copy the first 16 bytes into inline header. */\n+\trte_memcpy((void *)(uintptr_t)wqe->inl.eseg.inline_hdr_start,\n+\t\t (void *)(uintptr_t)addr,\n+\t\t MLX5_ETH_INLINE_HEADER_SIZE);\n+\taddr += MLX5_ETH_INLINE_HEADER_SIZE;\n+\tlength -= MLX5_ETH_INLINE_HEADER_SIZE;\n+\tsize = 3 + ((4 + length + 15) / 16);\n+\twqe->inl.byte_cnt = htonl(length | MLX5_INLINE_SEG);\n+\trte_memcpy((void *)(uintptr_t)&wqe->inl.data[0],\n+\t\t (void *)addr, MLX5_WQE64_INL_DATA);\n+\taddr += MLX5_WQE64_INL_DATA;\n+\tlength -= MLX5_WQE64_INL_DATA;\n+\twhile (length) {\n+\t\tvolatile union mlx5_wqe *wqe_next =\n+\t\t\t&(*txq->wqes)[wqe_ci & wqe_cnt];\n+\t\tuint32_t copy_bytes = (length > sizeof(*wqe)) ?\n+\t\t\t\t sizeof(*wqe) :\n+\t\t\t\t length;\n+\n+\t\trte_mov64((uint8_t *)(uintptr_t)&wqe_next->data[0],\n+\t\t\t (uint8_t *)addr);\n+\t\taddr += copy_bytes;\n+\t\tlength -= copy_bytes;\n+\t\t++wqe_ci;\n+\t}\n+\tassert(size < 64);\n+\twqe->inl.ctrl.data[0] = htonl((txq->wqe_ci << 8) | MLX5_OPCODE_SEND);\n+\twqe->inl.ctrl.data[1] = htonl(txq->qp_num_8s | size);\n+\twqe->inl.ctrl.data[3] = 0;\n+\twqe->inl.eseg.rsvd0 = 0;\n+\twqe->inl.eseg.rsvd1 = 0;\n+\twqe->inl.eseg.mss = 0;\n+\twqe->inl.eseg.rsvd2 = 0;\n+\twqe->inl.eseg.inline_hdr_sz = htons(MLX5_ETH_INLINE_HEADER_SIZE);\n+\t/* Increment consumer index. */\n+\ttxq->wqe_ci = wqe_ci;\n+}\n+\n+/**\n+ * Write a inline WQE with VLAN.\n+ *\n+ * @param txq\n+ * Pointer to TX queue structure.\n+ * @param wqe\n+ * Pointer to the WQE to fill.\n+ * @param addr\n+ * Buffer data address.\n+ * @param length\n+ * Packet length.\n+ * @param lkey\n+ * Memory region lkey.\n+ * @param vlan_tci\n+ * VLAN field to insert in packet.\n+ */\n+static inline void\n+mlx5_wqe_write_inline_vlan(struct txq *txq, volatile union mlx5_wqe *wqe,\n+\t\t\t uintptr_t addr, uint32_t length, uint16_t vlan_tci)\n+{\n+\tuint32_t size;\n+\tuint32_t wqe_cnt = txq->wqe_n - 1;\n+\tuint16_t wqe_ci = txq->wqe_ci + 1;\n+\tuint32_t vlan = htonl(0x81000000 | vlan_tci);\n+\n+\t/*\n+\t * Copy 12 bytes of source & destination MAC address.\n+\t * Copy 4 bytes of VLAN.\n+\t * Copy 2 bytes of Ether type.\n+\t */\n+\trte_memcpy((uint8_t *)(uintptr_t)wqe->inl.eseg.inline_hdr_start,\n+\t\t (uint8_t *)addr, 12);\n+\trte_memcpy((uint8_t *)(uintptr_t)wqe->inl.eseg.inline_hdr_start + 12,\n+\t\t &vlan, sizeof(vlan));\n+\trte_memcpy((uint8_t *)(uintptr_t)wqe->inl.eseg.inline_hdr_start + 16,\n+\t\t ((uint8_t *)addr + 12), 2);\n+\taddr += MLX5_ETH_VLAN_INLINE_HEADER_SIZE - sizeof(vlan);\n+\tlength -= MLX5_ETH_VLAN_INLINE_HEADER_SIZE - sizeof(vlan);\n+\tsize = (sizeof(wqe->inl.ctrl.ctrl) +\n+\t\tsizeof(wqe->inl.eseg) +\n+\t\tsizeof(wqe->inl.byte_cnt) +\n+\t\tlength + 15) / 16;\n+\twqe->inl.byte_cnt = htonl(length | MLX5_INLINE_SEG);\n+\trte_memcpy((void *)(uintptr_t)&wqe->inl.data[0],\n+\t\t (void *)addr, MLX5_WQE64_INL_DATA);\n+\taddr += MLX5_WQE64_INL_DATA;\n+\tlength -= MLX5_WQE64_INL_DATA;\n+\twhile (length) {\n+\t\tvolatile union mlx5_wqe *wqe_next =\n+\t\t\t&(*txq->wqes)[wqe_ci & wqe_cnt];\n+\t\tuint32_t copy_bytes = (length > sizeof(*wqe)) ?\n+\t\t\t\t sizeof(*wqe) :\n+\t\t\t\t length;\n+\n+\t\trte_mov64((uint8_t *)(uintptr_t)&wqe_next->data[0],\n+\t\t\t (uint8_t *)addr);\n+\t\taddr += copy_bytes;\n+\t\tlength -= copy_bytes;\n+\t\t++wqe_ci;\n+\t}\n+\tassert(size < 64);\n+\twqe->inl.ctrl.data[0] = htonl((txq->wqe_ci << 8) | MLX5_OPCODE_SEND);\n+\twqe->inl.ctrl.data[1] = htonl(txq->qp_num_8s | size);\n+\twqe->inl.ctrl.data[3] = 0;\n+\twqe->inl.eseg.rsvd0 = 0;\n+\twqe->inl.eseg.rsvd1 = 0;\n+\twqe->inl.eseg.mss = 0;\n+\twqe->inl.eseg.rsvd2 = 0;\n+\twqe->inl.eseg.inline_hdr_sz = htons(MLX5_ETH_VLAN_INLINE_HEADER_SIZE);\n+\t/* Increment consumer index. */\n+\ttxq->wqe_ci = wqe_ci;\n+}\n+\n+/**\n * Ring TX queue doorbell.\n *\n * @param txq\n@@ -417,6 +550,23 @@ tx_prefetch_cqe(struct txq *txq, uint16_t ci)\n }\n \n /**\n+ * Prefetch a WQE.\n+ *\n+ * @param txq\n+ * Pointer to TX queue structure.\n+ * @param wqe_ci\n+ * WQE consumer index.\n+ */\n+static inline void\n+tx_prefetch_wqe(struct txq *txq, uint16_t ci)\n+{\n+\tvolatile union mlx5_wqe *wqe;\n+\n+\twqe = &(*txq->wqes)[ci & (txq->wqe_n - 1)];\n+\trte_prefetch0(wqe);\n+}\n+\n+/**\n * DPDK callback for TX.\n *\n * @param dpdk_txq\n@@ -529,6 +679,129 @@ mlx5_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)\n }\n \n /**\n+ * DPDK callback for TX with inline support.\n+ *\n+ * @param dpdk_txq\n+ * Generic pointer to TX queue structure.\n+ * @param[in] pkts\n+ * Packets to transmit.\n+ * @param pkts_n\n+ * Number of packets in array.\n+ *\n+ * @return\n+ * Number of packets successfully transmitted (<= pkts_n).\n+ */\n+uint16_t\n+mlx5_tx_burst_inline(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)\n+{\n+\tstruct txq *txq = (struct txq *)dpdk_txq;\n+\tuint16_t elts_head = txq->elts_head;\n+\tconst unsigned int elts_n = txq->elts_n;\n+\tunsigned int i;\n+\tunsigned int max;\n+\tunsigned int comp;\n+\tvolatile union mlx5_wqe *wqe;\n+\tstruct rte_mbuf *buf;\n+\tunsigned int max_inline = txq->max_inline;\n+\n+\tif (unlikely(!pkts_n))\n+\t\treturn 0;\n+\tbuf = pkts[0];\n+\t/* Prefetch first packet cacheline. */\n+\ttx_prefetch_cqe(txq, txq->cq_ci);\n+\ttx_prefetch_cqe(txq, txq->cq_ci + 1);\n+\trte_prefetch0(buf);\n+\t/* Start processing. */\n+\ttxq_complete(txq);\n+\tmax = (elts_n - (elts_head - txq->elts_tail));\n+\tif (max > elts_n)\n+\t\tmax -= elts_n;\n+\tassert(max >= 1);\n+\tassert(max <= elts_n);\n+\t/* Always leave one free entry in the ring. */\n+\t--max;\n+\tif (max == 0)\n+\t\treturn 0;\n+\tif (max > pkts_n)\n+\t\tmax = pkts_n;\n+\tfor (i = 0; (i != max); ++i) {\n+\t\tunsigned int elts_head_next = (elts_head + 1) & (elts_n - 1);\n+\t\tuintptr_t addr;\n+\t\tuint32_t length;\n+\t\tuint32_t lkey;\n+\n+\t\twqe = &(*txq->wqes)[txq->wqe_ci & (txq->wqe_n - 1)];\n+\t\ttx_prefetch_wqe(txq, txq->wqe_ci);\n+\t\ttx_prefetch_wqe(txq, txq->wqe_ci + 1);\n+\t\tif (i + 1 < max)\n+\t\t\trte_prefetch0(pkts[i + 1]);\n+\t\t/* Should we enable HW CKSUM offload */\n+\t\tif (buf->ol_flags &\n+\t\t (PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM)) {\n+\t\t\twqe->inl.eseg.cs_flags =\n+\t\t\t\tMLX5_ETH_WQE_L3_CSUM |\n+\t\t\t\tMLX5_ETH_WQE_L4_CSUM;\n+\t\t} else {\n+\t\t\twqe->inl.eseg.cs_flags = 0;\n+\t\t}\n+\t\t/* Retrieve buffer information. */\n+\t\taddr = rte_pktmbuf_mtod(buf, uintptr_t);\n+\t\tlength = DATA_LEN(buf);\n+\t\t/* Update element. */\n+\t\t(*txq->elts)[elts_head] = buf;\n+\t\t/* Prefetch next buffer data. */\n+\t\tif (i + 1 < max)\n+\t\t\trte_prefetch0(rte_pktmbuf_mtod(pkts[i + 1],\n+\t\t\t\t\t\t volatile void *));\n+\t\tif (length <= max_inline) {\n+\t\t\tif (buf->ol_flags & PKT_TX_VLAN_PKT)\n+\t\t\t\tmlx5_wqe_write_inline_vlan(txq, wqe,\n+\t\t\t\t\t\t\t addr, length,\n+\t\t\t\t\t\t\t buf->vlan_tci);\n+\t\t\telse\n+\t\t\t\tmlx5_wqe_write_inline(txq, wqe, addr, length);\n+\t\t} else {\n+\t\t\t/* Retrieve Memory Region key for this memory pool. */\n+\t\t\tlkey = txq_mp2mr(txq, txq_mb2mp(buf));\n+\t\t\tif (buf->ol_flags & PKT_TX_VLAN_PKT)\n+\t\t\t\tmlx5_wqe_write_vlan(txq, wqe, addr, length,\n+\t\t\t\t\t\t lkey, buf->vlan_tci);\n+\t\t\telse\n+\t\t\t\tmlx5_wqe_write(txq, wqe, addr, length, lkey);\n+\t\t}\n+\t\twqe->inl.ctrl.data[2] = 0;\n+\t\telts_head = elts_head_next;\n+\t\tbuf = pkts[i + 1];\n+#ifdef MLX5_PMD_SOFT_COUNTERS\n+\t\t/* Increment sent bytes counter. */\n+\t\ttxq->stats.obytes += length;\n+#endif\n+\t}\n+\t/* Take a shortcut if nothing must be sent. */\n+\tif (unlikely(i == 0))\n+\t\treturn 0;\n+\t/* Check whether completion threshold has been reached. */\n+\tcomp = txq->elts_comp + i;\n+\tif (comp >= MLX5_TX_COMP_THRESH) {\n+\t\t/* Request completion on last WQE. */\n+\t\twqe->inl.ctrl.data[2] = htonl(8);\n+\t\t/* Save elts_head in unused \"immediate\" field of WQE. */\n+\t\twqe->inl.ctrl.data[3] = elts_head;\n+\t\ttxq->elts_comp = 0;\n+\t} else {\n+\t\ttxq->elts_comp = comp;\n+\t}\n+#ifdef MLX5_PMD_SOFT_COUNTERS\n+\t/* Increment sent packets counter. */\n+\ttxq->stats.opackets += i;\n+#endif\n+\t/* Ring QP doorbell. */\n+\tmlx5_tx_dbrec(txq);\n+\ttxq->elts_head = elts_head;\n+\treturn i;\n+}\n+\n+/**\n * Translate RX completion flags to packet type.\n *\n * @param[in] cqe\ndiff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h\nindex f900e65..3c83148 100644\n--- a/drivers/net/mlx5/mlx5_rxtx.h\n+++ b/drivers/net/mlx5/mlx5_rxtx.h\n@@ -246,6 +246,7 @@ struct txq {\n \tuint16_t wqe_n; /* Number of WQ elements. */\n \tuint16_t bf_offset; /* Blueflame offset. */\n \tuint16_t bf_buf_size; /* Blueflame size. */\n+\tuint16_t max_inline; /* Maximum size to inline in a WQE. */\n \tuint32_t qp_num_8s; /* QP number shifted by 8. */\n \tvolatile struct mlx5_cqe (*cqes)[]; /* Completion queue. */\n \tvolatile union mlx5_wqe (*wqes)[]; /* Work queue. */\n@@ -310,6 +311,7 @@ uint16_t mlx5_tx_burst_secondary_setup(void *, struct rte_mbuf **, uint16_t);\n /* mlx5_rxtx.c */\n \n uint16_t mlx5_tx_burst(void *, struct rte_mbuf **, uint16_t);\n+uint16_t mlx5_tx_burst_inline(void *, struct rte_mbuf **, uint16_t);\n uint16_t mlx5_rx_burst(void *, struct rte_mbuf **, uint16_t);\n uint16_t removed_tx_burst(void *, struct rte_mbuf **, uint16_t);\n uint16_t removed_rx_burst(void *, struct rte_mbuf **, uint16_t);\ndiff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c\nindex 7b2dc7c..6a4a96e 100644\n--- a/drivers/net/mlx5/mlx5_txq.c\n+++ b/drivers/net/mlx5/mlx5_txq.c\n@@ -332,6 +332,10 @@ txq_ctrl_setup(struct rte_eth_dev *dev, struct txq_ctrl *txq_ctrl,\n \t\t.comp_mask = (IBV_EXP_QP_INIT_ATTR_PD |\n \t\t\t IBV_EXP_QP_INIT_ATTR_RES_DOMAIN),\n \t};\n+\tif (priv->txq_inline && priv->txqs_n >= priv->txqs_inline) {\n+\t\ttmpl.txq.max_inline = priv->txq_inline;\n+\t\tattr.init.cap.max_inline_data = tmpl.txq.max_inline;\n+\t}\n \ttmpl.qp = ibv_exp_create_qp(priv->ctx, &attr.init);\n \tif (tmpl.qp == NULL) {\n \t\tret = (errno ? errno : EINVAL);\n", "prefixes": [ "dpdk-dev", "v6", "17/25" ] }{ "id": 14329, "url": "