From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <adrien.mazarguil@6wind.com>
Received: from mail-wm0-f41.google.com (mail-wm0-f41.google.com [74.125.82.41])
 by dpdk.org (Postfix) with ESMTP id D991C8E94
 for <dev@dpdk.org>; Mon, 23 Nov 2015 15:45:51 +0100 (CET)
Received: by wmvv187 with SMTP id v187so164327773wmv.1
 for <dev@dpdk.org>; Mon, 23 Nov 2015 06:45:51 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=6wind-com.20150623.gappssmtp.com; s=20150623;
 h=from:to:cc:subject:date:message-id:in-reply-to:references;
 bh=aVHFIbqD479FQY3dsu1l9LLtpQE+4ZJJ/fyVUJe23dk=;
 b=SfxTSAPA4R6zS0wpq9kjrzTB2RvJz1BS6OimZy5Obj3jX2bB/iVrHS1o/MEkHBQxEn
 ZwrVTCmWDUuW5LBNIM9Dja0/OBnG5jqTxuqFNuNPx/3W6z4q4rQ4M3PDTlr0Orjv5A2K
 eOs2A9ZPEGU+p1cGvIWVELRZdPYCd9qhmtk/nRJA15iQiwJQ0MOIwqPvTFWnhjbCupos
 /WpfHlBKm7CF3Ce/Isf9VDYih38PCQ1pLjVBBW2BiF3qcLZDVRYScNkGX6Ctp6Q1uY6C
 bGHiFKnD+YOCj5DNPnF7Fminf7mJvIIyExf8X7nT+JIS8UhAeZDHmRnHXjMY6/AVkUxF
 zISw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20130820;
 h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to
 :references;
 bh=aVHFIbqD479FQY3dsu1l9LLtpQE+4ZJJ/fyVUJe23dk=;
 b=i0YTAodl/6Ido2gQQb6/DUfyaz0bxHNIPJo6V2f0neyKc/4tQjgOtIHduI43t7BBOk
 su+LNTKvTlEmd/gARm/q2OPPighUisIjNdQWj5wYlLJoMCTnYYltVawtEdhiS0gZm41c
 26OP7HH4faKKnHIW0aqpvobddVeECNVlEdPh9aWy3lGU3B1D/TDyN8sFfXJFaeSzZIsV
 T3/oZRnojZYnRpsjxhQW+p7yiMVts0a4J+64+kUIQpoB6yGHa75c4kRbEHibNLZj9keC
 DscdzkiIHwGj4Z9QJ+gp7B4FoBy3bcLKvOLqb0AwsRnDgj+a2oALPZ/4t7oQaPQaIL3z
 YKKw==
X-Gm-Message-State: ALoCoQnNaciW0D4mtiWuXeNrH8/Be9GxSlVCcDxkX719/zkF8h8GHupcGNqo7aKIc6eCi1dLqUtU
X-Received: by 10.194.87.39 with SMTP id u7mr31289504wjz.11.1448289947871;
 Mon, 23 Nov 2015 06:45:47 -0800 (PST)
Received: from 6wind.com (guy78-3-82-239-227-177.fbx.proxad.net.
 [82.239.227.177])
 by smtp.gmail.com with ESMTPSA id s9sm13564360wmf.2.2015.11.23.06.45.46
 (version=TLSv1/SSLv3 cipher=OTHER);
 Mon, 23 Nov 2015 06:45:47 -0800 (PST)
From: Adrien Mazarguil <adrien.mazarguil@6wind.com>
To: dev@dpdk.org
Date: Mon, 23 Nov 2015 15:44:46 +0100
Message-Id: <1448289889-9590-12-git-send-email-adrien.mazarguil@6wind.com>
X-Mailer: git-send-email 2.1.0
In-Reply-To: <1448289889-9590-1-git-send-email-adrien.mazarguil@6wind.com>
References: <1448289889-9590-1-git-send-email-adrien.mazarguil@6wind.com>
Subject: [dpdk-dev] [PATCH 11/14] mlx5: fix TX packet loss after
	initialization
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>,
 <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>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
X-List-Received-Date: Mon, 23 Nov 2015 14:45:52 -0000

From: Olga Shern <olgas@mellanox.com>

Pre-registering mbuf memory pools when creating TX queues avoids costly
registrations later in the data path.

Fixes: 2e22920b85d9 ("mlx5: support non-scattered Tx and Rx")

Signed-off-by: Olga Shern <olgas@mellanox.com>
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/mlx5/mlx5_rxtx.c | 85 +++++++++++++++++++++++++++++++++++++++++---
 drivers/net/mlx5/mlx5_rxtx.h |  3 +-
 drivers/net/mlx5/mlx5_txq.c  |  2 ++
 3 files changed, 85 insertions(+), 5 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c
index 80d0c97..c6c167c 100644
--- a/drivers/net/mlx5/mlx5_rxtx.c
+++ b/drivers/net/mlx5/mlx5_rxtx.c
@@ -146,7 +146,7 @@ txq_mb2mp(struct rte_mbuf *buf)
  *   mr->lkey on success, (uint32_t)-1 on failure.
  */
 static uint32_t
-txq_mp2mr(struct txq *txq, struct rte_mempool *mp)
+txq_mp2mr(struct txq *txq, const struct rte_mempool *mp)
 {
 	unsigned int i;
 	struct ibv_mr *mr;
@@ -163,7 +163,8 @@ txq_mp2mr(struct txq *txq, struct rte_mempool *mp)
 		}
 	}
 	/* Add a new entry, register MR first. */
-	DEBUG("%p: discovered new memory pool %p", (void *)txq, (void *)mp);
+	DEBUG("%p: discovered new memory pool \"%s\" (%p)",
+	      (void *)txq, mp->name, (const void *)mp);
 	mr = ibv_reg_mr(txq->priv->pd,
 			(void *)mp->elt_va_start,
 			(mp->elt_va_end - mp->elt_va_start),
@@ -186,11 +187,87 @@ txq_mp2mr(struct txq *txq, struct rte_mempool *mp)
 	txq->mp2mr[i].mp = mp;
 	txq->mp2mr[i].mr = mr;
 	txq->mp2mr[i].lkey = mr->lkey;
-	DEBUG("%p: new MR lkey for MP %p: 0x%08" PRIu32,
-	      (void *)txq, (void *)mp, txq->mp2mr[i].lkey);
+	DEBUG("%p: new MR lkey for MP \"%s\" (%p): 0x%08" PRIu32,
+	      (void *)txq, mp->name, (const void *)mp, txq->mp2mr[i].lkey);
 	return txq->mp2mr[i].lkey;
 }
 
+struct txq_mp2mr_mbuf_check_data {
+	const struct rte_mempool *mp;
+	int ret;
+};
+
+/**
+ * Callback function for rte_mempool_obj_iter() to check whether a given
+ * mempool object looks like a mbuf.
+ *
+ * @param[in, out] arg
+ *   Context data (struct txq_mp2mr_mbuf_check_data). Contains mempool pointer
+ *   and return value.
+ * @param[in] start
+ *   Object start address.
+ * @param[in] end
+ *   Object end address.
+ * @param index
+ *   Unused.
+ *
+ * @return
+ *   Nonzero value when object is not a mbuf.
+ */
+static void
+txq_mp2mr_mbuf_check(void *arg, void *start, void *end,
+		     uint32_t index __rte_unused)
+{
+	struct txq_mp2mr_mbuf_check_data *data = arg;
+	struct rte_mbuf *buf =
+		(void *)((uintptr_t)start + data->mp->header_size);
+
+	(void)index;
+	/* Check whether mbuf structure fits element size and whether mempool
+	 * pointer is valid. */
+	if (((uintptr_t)end >= (uintptr_t)(buf + 1)) &&
+	    (buf->pool == data->mp))
+		data->ret = 0;
+	else
+		data->ret = -1;
+}
+
+/**
+ * Iterator function for rte_mempool_walk() to register existing mempools and
+ * fill the MP to MR cache of a TX queue.
+ *
+ * @param[in] mp
+ *   Memory Pool to register.
+ * @param *arg
+ *   Pointer to TX queue structure.
+ */
+void
+txq_mp2mr_iter(const struct rte_mempool *mp, void *arg)
+{
+	struct txq *txq = arg;
+	struct txq_mp2mr_mbuf_check_data data = {
+		.mp = mp,
+		.ret = -1,
+	};
+
+	/* Discard empty mempools. */
+	if (mp->size == 0)
+		return;
+	/* Register mempool only if the first element looks like a mbuf. */
+	rte_mempool_obj_iter((void *)mp->elt_va_start,
+			     1,
+			     mp->header_size + mp->elt_size + mp->trailer_size,
+			     1,
+			     mp->elt_pa,
+			     mp->pg_num,
+			     mp->pg_shift,
+			     txq_mp2mr_mbuf_check,
+			     &data);
+	if (data.ret)
+		return;
+	txq_mp2mr(txq, mp);
+}
+
 #if MLX5_PMD_SGE_WR_N > 1
 
 /**
diff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h
index 15c4bc8..e1e1925 100644
--- a/drivers/net/mlx5/mlx5_rxtx.h
+++ b/drivers/net/mlx5/mlx5_rxtx.h
@@ -209,7 +209,7 @@ typedef uint8_t linear_t[16384];
 struct txq {
 	struct priv *priv; /* Back pointer to private data. */
 	struct {
-		struct rte_mempool *mp; /* Cached Memory Pool. */
+		const struct rte_mempool *mp; /* Cached Memory Pool. */
 		struct ibv_mr *mr; /* Memory Region (for mp). */
 		uint32_t lkey; /* mr->lkey */
 	} mp2mr[MLX5_PMD_TX_MP_CACHE]; /* MP to MR translation table. */
@@ -264,6 +264,7 @@ void mlx5_tx_queue_release(void *);
 
 /* mlx5_rxtx.c */
 
+void txq_mp2mr_iter(const struct rte_mempool *, void *);
 uint16_t mlx5_tx_burst(void *, struct rte_mbuf **, uint16_t);
 uint16_t mlx5_rx_burst_sp(void *, struct rte_mbuf **, uint16_t);
 uint16_t mlx5_rx_burst(void *, struct rte_mbuf **, uint16_t);
diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c
index aa7581f..214a7c1 100644
--- a/drivers/net/mlx5/mlx5_txq.c
+++ b/drivers/net/mlx5/mlx5_txq.c
@@ -415,6 +415,8 @@ txq_setup(struct rte_eth_dev *dev, struct txq *txq, uint16_t desc,
 	txq_cleanup(txq);
 	*txq = tmpl;
 	DEBUG("%p: txq updated with %p", (void *)txq, (void *)&tmpl);
+	/* Pre-register known mempools. */
+	rte_mempool_walk(txq_mp2mr_iter, txq);
 	assert(ret == 0);
 	return 0;
 error:
-- 
2.1.0