DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/6] net/sfc: support more options for a number of Rx/Tx descs
@ 2017-12-26  7:27 Andrew Rybchenko
  2017-12-26  7:27 ` [dpdk-dev] [PATCH 1/6] net/sfc: make refill threshold check Rx datapath specific Andrew Rybchenko
                   ` (7 more replies)
  0 siblings, 8 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-26  7:27 UTC (permalink / raw)
  To: dev

The minimum size of Rx/Tx descriptor rings supported by Solarflare HW is 512.
It adds inconvenience to run DPDK applications which typically use smaller
default values. Also smaller numbers of used descriptors is better for
performance.

The patch series adds possibility to use any number of Rx/Tx descriptors
in the range, for example, from 1 to 2048 for Tx and from 8 to 4096 for Rx.
Maximum value is defined by HW maximum.

The patch series is made independent from [1] submitted a bit earlier
to avoid automatic build failures and to be able to apply this one first.
When one is applied, the second should be rebased.

[1] http://dpdk.org/ml/archives/dev/2017-December/084843.html

Andrew Rybchenko (6):
  net/sfc: make refill threshold check Rx datapath specific
  net/sfc: make Tx free threshold check datapath specific
  net/sfc: use Rx queue max fill level calculated on init
  net/sfc: use Tx queue max fill level calculated on init
  net/sfc: support more options for a number of Rx descriptors
  net/sfc: support more options for a number of Tx descriptors

 drivers/net/sfc/sfc_dp_rx.h   | 27 ++++++++++++++++++++
 drivers/net/sfc/sfc_dp_tx.h   | 27 ++++++++++++++++++++
 drivers/net/sfc/sfc_ef10_rx.c | 44 ++++++++++++++++++++++++++++++--
 drivers/net/sfc/sfc_ef10_tx.c | 58 ++++++++++++++++++++++++++++++++++---------
 drivers/net/sfc/sfc_ethdev.c  |  7 ++++++
 drivers/net/sfc/sfc_rx.c      | 49 ++++++++++++++++++++++++++++--------
 drivers/net/sfc/sfc_rx.h      |  1 +
 drivers/net/sfc/sfc_tx.c      | 48 +++++++++++++++++++++++++++--------
 drivers/net/sfc/sfc_tx.h      |  1 +
 9 files changed, 227 insertions(+), 35 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH 1/6] net/sfc: make refill threshold check Rx datapath specific
  2017-12-26  7:27 [dpdk-dev] [PATCH 0/6] net/sfc: support more options for a number of Rx/Tx descs Andrew Rybchenko
@ 2017-12-26  7:27 ` Andrew Rybchenko
  2017-12-26  7:27 ` [dpdk-dev] [PATCH 2/6] net/sfc: make Tx free threshold check " Andrew Rybchenko
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-26  7:27 UTC (permalink / raw)
  To: dev

EFX_RXQ_LIMIT is libefx-specifics and it should not be used
for other Rx datapaths implementations (e.g. EF10 native).

EF10 native Rx datapath has its own understanding of the maximum
RxQ fill level imposed by EvQ clear strategy and space reserved
for Rx error and flush events.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc_dp_rx.h   | 17 +++++++++++++++++
 drivers/net/sfc/sfc_ef10_rx.c | 15 +++++++++++++++
 drivers/net/sfc/sfc_rx.c      | 40 +++++++++++++++++++++++++++++++---------
 3 files changed, 63 insertions(+), 9 deletions(-)

diff --git a/drivers/net/sfc/sfc_dp_rx.h b/drivers/net/sfc/sfc_dp_rx.h
index 3f6a604..3c29089 100644
--- a/drivers/net/sfc/sfc_dp_rx.h
+++ b/drivers/net/sfc/sfc_dp_rx.h
@@ -101,6 +101,22 @@ struct sfc_dp_rx_qcreate_info {
 };
 
 /**
+ * Get size of receive and event queue rings by the number of Rx
+ * descriptors.
+ *
+ * @param nb_rx_desc		Number of Rx descriptors
+ * @param rxq_entries		Location for number of Rx ring entries
+ * @param evq_entries		Location for number of event ring entries
+ * @param rxq_max_fill_level	Location for maximum Rx ring fill level
+ *
+ * @return 0 or positive errno.
+ */
+typedef int (sfc_dp_rx_qsize_up_rings_t)(uint16_t nb_rx_desc,
+					 unsigned int *rxq_entries,
+					 unsigned int *evq_entries,
+					 unsigned int *rxq_max_fill_level);
+
+/**
  * Allocate and initialize datapath receive queue.
  *
  * @param port_id	The port identifier
@@ -166,6 +182,7 @@ struct sfc_dp_rx {
 	unsigned int				features;
 #define SFC_DP_RX_FEAT_SCATTER			0x1
 #define SFC_DP_RX_FEAT_MULTI_PROCESS		0x2
+	sfc_dp_rx_qsize_up_rings_t		*qsize_up_rings;
 	sfc_dp_rx_qcreate_t			*qcreate;
 	sfc_dp_rx_qdestroy_t			*qdestroy;
 	sfc_dp_rx_qstart_t			*qstart;
diff --git a/drivers/net/sfc/sfc_ef10_rx.c b/drivers/net/sfc/sfc_ef10_rx.c
index 18d60c6..29524ce 100644
--- a/drivers/net/sfc/sfc_ef10_rx.c
+++ b/drivers/net/sfc/sfc_ef10_rx.c
@@ -553,6 +553,20 @@ sfc_ef10_rx_qdesc_status(__rte_unused struct sfc_dp_rxq *dp_rxq,
 }
 
 
+static sfc_dp_rx_qsize_up_rings_t sfc_ef10_rx_qsize_up_rings;
+static int
+sfc_ef10_rx_qsize_up_rings(uint16_t nb_rx_desc,
+			   unsigned int *rxq_entries,
+			   unsigned int *evq_entries,
+			   unsigned int *rxq_max_fill_level)
+{
+	*rxq_entries = nb_rx_desc;
+	*evq_entries = nb_rx_desc;
+	*rxq_max_fill_level = SFC_EF10_RXQ_LIMIT(*rxq_entries);
+	return 0;
+}
+
+
 static uint64_t
 sfc_ef10_mk_mbuf_rearm_data(uint16_t port_id, uint16_t prefix_size)
 {
@@ -708,6 +722,7 @@ struct sfc_dp_rx sfc_ef10_rx = {
 		.hw_fw_caps	= SFC_DP_HW_FW_CAP_EF10,
 	},
 	.features		= SFC_DP_RX_FEAT_MULTI_PROCESS,
+	.qsize_up_rings		= sfc_ef10_rx_qsize_up_rings,
 	.qcreate		= sfc_ef10_rx_qcreate,
 	.qdestroy		= sfc_ef10_rx_qdestroy,
 	.qstart			= sfc_ef10_rx_qstart,
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 7816393..43d51c4 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -413,6 +413,19 @@ sfc_rxq_by_dp_rxq(const struct sfc_dp_rxq *dp_rxq)
 	return rxq;
 }
 
+static sfc_dp_rx_qsize_up_rings_t sfc_efx_rx_qsize_up_rings;
+static int
+sfc_efx_rx_qsize_up_rings(uint16_t nb_rx_desc,
+			  unsigned int *rxq_entries,
+			  unsigned int *evq_entries,
+			  unsigned int *rxq_max_fill_level)
+{
+	*rxq_entries = nb_rx_desc;
+	*evq_entries = nb_rx_desc;
+	*rxq_max_fill_level = EFX_RXQ_LIMIT(*rxq_entries);
+	return 0;
+}
+
 static sfc_dp_rx_qcreate_t sfc_efx_rx_qcreate;
 static int
 sfc_efx_rx_qcreate(uint16_t port_id, uint16_t queue_id,
@@ -535,6 +548,7 @@ struct sfc_dp_rx sfc_efx_rx = {
 		.hw_fw_caps	= 0,
 	},
 	.features		= SFC_DP_RX_FEAT_SCATTER,
+	.qsize_up_rings		= sfc_efx_rx_qsize_up_rings,
 	.qcreate		= sfc_efx_rx_qcreate,
 	.qdestroy		= sfc_efx_rx_qdestroy,
 	.qstart			= sfc_efx_rx_qstart,
@@ -771,10 +785,9 @@ sfc_rx_qstop(struct sfc_adapter *sa, unsigned int sw_index)
 }
 
 static int
-sfc_rx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_rx_desc,
+sfc_rx_qcheck_conf(struct sfc_adapter *sa, unsigned int rxq_max_fill_level,
 		   const struct rte_eth_rxconf *rx_conf)
 {
-	const uint16_t rx_free_thresh_max = EFX_RXQ_LIMIT(nb_rx_desc);
 	int rc = 0;
 
 	if (rx_conf->rx_thresh.pthresh != 0 ||
@@ -784,10 +797,10 @@ sfc_rx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_rx_desc,
 			"RxQ prefetch/host/writeback thresholds are not supported");
 	}
 
-	if (rx_conf->rx_free_thresh > rx_free_thresh_max) {
+	if (rx_conf->rx_free_thresh > rxq_max_fill_level) {
 		sfc_err(sa,
 			"RxQ free threshold too large: %u vs maximum %u",
-			rx_conf->rx_free_thresh, rx_free_thresh_max);
+			rx_conf->rx_free_thresh, rxq_max_fill_level);
 		rc = EINVAL;
 	}
 
@@ -907,13 +920,21 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 {
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
 	int rc;
+	unsigned int rxq_entries;
+	unsigned int evq_entries;
+	unsigned int rxq_max_fill_level;
 	uint16_t buf_size;
 	struct sfc_rxq_info *rxq_info;
 	struct sfc_evq *evq;
 	struct sfc_rxq *rxq;
 	struct sfc_dp_rx_qcreate_info info;
 
-	rc = sfc_rx_qcheck_conf(sa, nb_rx_desc, rx_conf);
+	rc = sa->dp_rx->qsize_up_rings(nb_rx_desc, &rxq_entries, &evq_entries,
+				       &rxq_max_fill_level);
+	if (rc != 0)
+		goto fail_size_up_rings;
+
+	rc = sfc_rx_qcheck_conf(sa, rxq_max_fill_level, rx_conf);
 	if (rc != 0)
 		goto fail_bad_conf;
 
@@ -940,14 +961,14 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	SFC_ASSERT(sw_index < sa->rxq_count);
 	rxq_info = &sa->rxq_info[sw_index];
 
-	SFC_ASSERT(nb_rx_desc <= rxq_info->max_entries);
-	rxq_info->entries = nb_rx_desc;
+	SFC_ASSERT(rxq_entries <= rxq_info->max_entries);
+	rxq_info->entries = rxq_entries;
 	rxq_info->type =
 		sa->eth_dev->data->dev_conf.rxmode.enable_scatter ?
 		EFX_RXQ_TYPE_SCATTER : EFX_RXQ_TYPE_DEFAULT;
 
 	rc = sfc_ev_qinit(sa, SFC_EVQ_TYPE_RX, sw_index,
-			  rxq_info->entries, socket_id, &evq);
+			  evq_entries, socket_id, &evq);
 	if (rc != 0)
 		goto fail_ev_qinit;
 
@@ -984,7 +1005,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 
 	info.rxq_entries = rxq_info->entries;
 	info.rxq_hw_ring = rxq->mem.esm_base;
-	info.evq_entries = rxq_info->entries;
+	info.evq_entries = evq_entries;
 	info.evq_hw_ring = evq->mem.esm_base;
 	info.hw_index = rxq->hw_index;
 	info.mem_bar = sa->mem_bar.esb_base;
@@ -1017,6 +1038,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	rxq_info->entries = 0;
 
 fail_bad_conf:
+fail_size_up_rings:
 	sfc_log_init(sa, "failed %d", rc);
 	return rc;
 }
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH 2/6] net/sfc: make Tx free threshold check datapath specific
  2017-12-26  7:27 [dpdk-dev] [PATCH 0/6] net/sfc: support more options for a number of Rx/Tx descs Andrew Rybchenko
  2017-12-26  7:27 ` [dpdk-dev] [PATCH 1/6] net/sfc: make refill threshold check Rx datapath specific Andrew Rybchenko
@ 2017-12-26  7:27 ` Andrew Rybchenko
  2017-12-26  7:27 ` [dpdk-dev] [PATCH 3/6] net/sfc: use Rx queue max fill level calculated on init Andrew Rybchenko
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-26  7:27 UTC (permalink / raw)
  To: dev

EFX_TXQ_LIMIT is libefx-specifics and it should not be used
for other Tx datapaths implementations (e.g. EF10 native).

EF10 native Tx datapath has its own understanding of the maximum
TxQ fill level imposed by EvQ clear strategy and space reserved
for Tx error and flush events.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc_dp_tx.h   | 17 +++++++++++++++++
 drivers/net/sfc/sfc_ef10_tx.c | 15 +++++++++++++++
 drivers/net/sfc/sfc_tx.c      | 39 +++++++++++++++++++++++++++++++--------
 3 files changed, 63 insertions(+), 8 deletions(-)

diff --git a/drivers/net/sfc/sfc_dp_tx.h b/drivers/net/sfc/sfc_dp_tx.h
index 94d1b10..32d7681 100644
--- a/drivers/net/sfc/sfc_dp_tx.h
+++ b/drivers/net/sfc/sfc_dp_tx.h
@@ -78,6 +78,22 @@ struct sfc_dp_tx_qcreate_info {
 };
 
 /**
+ * Get size of transmit and event queue rings by the number of Tx
+ * descriptors.
+ *
+ * @param nb_tx_desc		Number of Tx descriptors
+ * @param txq_entries		Location for number of Tx ring entries
+ * @param evq_entries		Location for number of event ring entries
+ * @param txq_max_fill_level	Location for maximum Tx ring fill level
+ *
+ * @return 0 or positive errno.
+ */
+typedef int (sfc_dp_tx_qsize_up_rings_t)(uint16_t nb_tx_desc,
+					 unsigned int *txq_entries,
+					 unsigned int *evq_entries,
+					 unsigned int *txq_max_fill_level);
+
+/**
  * Allocate and initialize datapath transmit queue.
  *
  * @param port_id	The port identifier
@@ -144,6 +160,7 @@ struct sfc_dp_tx {
 #define SFC_DP_TX_FEAT_MULTI_PROCESS	0x8
 #define SFC_DP_TX_FEAT_MULTI_POOL	0x10
 #define SFC_DP_TX_FEAT_REFCNT		0x20
+	sfc_dp_tx_qsize_up_rings_t	*qsize_up_rings;
 	sfc_dp_tx_qcreate_t		*qcreate;
 	sfc_dp_tx_qdestroy_t		*qdestroy;
 	sfc_dp_tx_qstart_t		*qstart;
diff --git a/drivers/net/sfc/sfc_ef10_tx.c b/drivers/net/sfc/sfc_ef10_tx.c
index 0454e79..ab3334a 100644
--- a/drivers/net/sfc/sfc_ef10_tx.c
+++ b/drivers/net/sfc/sfc_ef10_tx.c
@@ -487,6 +487,19 @@ sfc_ef10_simple_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 }
 
 
+static sfc_dp_tx_qsize_up_rings_t sfc_ef10_tx_qsize_up_rings;
+static int
+sfc_ef10_tx_qsize_up_rings(uint16_t nb_tx_desc,
+			   unsigned int *txq_entries,
+			   unsigned int *evq_entries,
+			   unsigned int *txq_max_fill_level)
+{
+	*txq_entries = nb_tx_desc;
+	*evq_entries = nb_tx_desc;
+	*txq_max_fill_level = SFC_EF10_TXQ_LIMIT(*txq_entries);
+	return 0;
+}
+
 static sfc_dp_tx_qcreate_t sfc_ef10_tx_qcreate;
 static int
 sfc_ef10_tx_qcreate(uint16_t port_id, uint16_t queue_id,
@@ -628,6 +641,7 @@ struct sfc_dp_tx sfc_ef10_tx = {
 				  SFC_DP_TX_FEAT_MULTI_POOL |
 				  SFC_DP_TX_FEAT_REFCNT |
 				  SFC_DP_TX_FEAT_MULTI_PROCESS,
+	.qsize_up_rings		= sfc_ef10_tx_qsize_up_rings,
 	.qcreate		= sfc_ef10_tx_qcreate,
 	.qdestroy		= sfc_ef10_tx_qdestroy,
 	.qstart			= sfc_ef10_tx_qstart,
@@ -644,6 +658,7 @@ struct sfc_dp_tx sfc_ef10_simple_tx = {
 		.type		= SFC_DP_TX,
 	},
 	.features		= SFC_DP_TX_FEAT_MULTI_PROCESS,
+	.qsize_up_rings		= sfc_ef10_tx_qsize_up_rings,
 	.qcreate		= sfc_ef10_tx_qcreate,
 	.qdestroy		= sfc_ef10_tx_qdestroy,
 	.qstart			= sfc_ef10_tx_qstart,
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index d1320f4..3c9a6e9 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -57,7 +57,7 @@
 #define SFC_TX_QFLUSH_POLL_ATTEMPTS	(2000)
 
 static int
-sfc_tx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_tx_desc,
+sfc_tx_qcheck_conf(struct sfc_adapter *sa, unsigned int txq_max_fill_level,
 		   const struct rte_eth_txconf *tx_conf)
 {
 	unsigned int flags = tx_conf->txq_flags;
@@ -69,10 +69,10 @@ sfc_tx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_tx_desc,
 		rc = EINVAL;
 	}
 
-	if (tx_conf->tx_free_thresh > EFX_TXQ_LIMIT(nb_tx_desc)) {
+	if (tx_conf->tx_free_thresh > txq_max_fill_level) {
 		sfc_err(sa,
 			"TxQ free threshold too large: %u vs maximum %u",
-			tx_conf->tx_free_thresh, EFX_TXQ_LIMIT(nb_tx_desc));
+			tx_conf->tx_free_thresh, txq_max_fill_level);
 		rc = EINVAL;
 	}
 
@@ -145,6 +145,9 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	     const struct rte_eth_txconf *tx_conf)
 {
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
+	unsigned int txq_entries;
+	unsigned int evq_entries;
+	unsigned int txq_max_fill_level;
 	struct sfc_txq_info *txq_info;
 	struct sfc_evq *evq;
 	struct sfc_txq *txq;
@@ -153,18 +156,23 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 
 	sfc_log_init(sa, "TxQ = %u", sw_index);
 
-	rc = sfc_tx_qcheck_conf(sa, nb_tx_desc, tx_conf);
+	rc = sa->dp_tx->qsize_up_rings(nb_tx_desc, &txq_entries, &evq_entries,
+				       &txq_max_fill_level);
+	if (rc != 0)
+		goto fail_size_up_rings;
+
+	rc = sfc_tx_qcheck_conf(sa, txq_max_fill_level, tx_conf);
 	if (rc != 0)
 		goto fail_bad_conf;
 
 	SFC_ASSERT(sw_index < sa->txq_count);
 	txq_info = &sa->txq_info[sw_index];
 
-	SFC_ASSERT(nb_tx_desc <= sa->txq_max_entries);
-	txq_info->entries = nb_tx_desc;
+	SFC_ASSERT(txq_entries <= sa->txq_max_entries);
+	txq_info->entries = txq_entries;
 
 	rc = sfc_ev_qinit(sa, SFC_EVQ_TYPE_TX, sw_index,
-			  txq_info->entries, socket_id, &evq);
+			  evq_entries, socket_id, &evq);
 	if (rc != 0)
 		goto fail_ev_qinit;
 
@@ -193,7 +201,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	info.txq_entries = txq_info->entries;
 	info.dma_desc_size_max = encp->enc_tx_dma_desc_size_max;
 	info.txq_hw_ring = txq->mem.esm_base;
-	info.evq_entries = txq_info->entries;
+	info.evq_entries = evq_entries;
 	info.evq_hw_ring = evq->mem.esm_base;
 	info.hw_index = txq->hw_index;
 	info.mem_bar = sa->mem_bar.esb_base;
@@ -226,6 +234,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	txq_info->entries = 0;
 
 fail_bad_conf:
+fail_size_up_rings:
 	sfc_log_init(sa, "failed (TxQ = %u, rc = %d)", sw_index, rc);
 	return rc;
 }
@@ -865,6 +874,19 @@ sfc_txq_by_dp_txq(const struct sfc_dp_txq *dp_txq)
 	return txq;
 }
 
+static sfc_dp_tx_qsize_up_rings_t sfc_efx_tx_qsize_up_rings;
+static int
+sfc_efx_tx_qsize_up_rings(uint16_t nb_tx_desc,
+			  unsigned int *txq_entries,
+			  unsigned int *evq_entries,
+			  unsigned int *txq_max_fill_level)
+{
+	*txq_entries = nb_tx_desc;
+	*evq_entries = nb_tx_desc;
+	*txq_max_fill_level = EFX_TXQ_LIMIT(*txq_entries);
+	return 0;
+}
+
 static sfc_dp_tx_qcreate_t sfc_efx_tx_qcreate;
 static int
 sfc_efx_tx_qcreate(uint16_t port_id, uint16_t queue_id,
@@ -1040,6 +1062,7 @@ struct sfc_dp_tx sfc_efx_tx = {
 				  SFC_DP_TX_FEAT_MULTI_POOL |
 				  SFC_DP_TX_FEAT_REFCNT |
 				  SFC_DP_TX_FEAT_MULTI_SEG,
+	.qsize_up_rings		= sfc_efx_tx_qsize_up_rings,
 	.qcreate		= sfc_efx_tx_qcreate,
 	.qdestroy		= sfc_efx_tx_qdestroy,
 	.qstart			= sfc_efx_tx_qstart,
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH 3/6] net/sfc: use Rx queue max fill level calculated on init
  2017-12-26  7:27 [dpdk-dev] [PATCH 0/6] net/sfc: support more options for a number of Rx/Tx descs Andrew Rybchenko
  2017-12-26  7:27 ` [dpdk-dev] [PATCH 1/6] net/sfc: make refill threshold check Rx datapath specific Andrew Rybchenko
  2017-12-26  7:27 ` [dpdk-dev] [PATCH 2/6] net/sfc: make Tx free threshold check " Andrew Rybchenko
@ 2017-12-26  7:27 ` Andrew Rybchenko
  2017-12-26  7:27 ` [dpdk-dev] [PATCH 4/6] net/sfc: use Tx " Andrew Rybchenko
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-26  7:27 UTC (permalink / raw)
  To: dev

Prepare to support more options for number of Rx descriptors.

libefx-based datapath is updated just for completeness to
make code more readable and less error-prone.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc_dp_rx.h   | 2 ++
 drivers/net/sfc/sfc_ef10_rx.c | 5 +++--
 drivers/net/sfc/sfc_rx.c      | 5 +++--
 drivers/net/sfc/sfc_rx.h      | 1 +
 4 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/sfc/sfc_dp_rx.h b/drivers/net/sfc/sfc_dp_rx.h
index 3c29089..f62d79a 100644
--- a/drivers/net/sfc/sfc_dp_rx.h
+++ b/drivers/net/sfc/sfc_dp_rx.h
@@ -60,6 +60,8 @@ struct sfc_dp_rxq {
 struct sfc_dp_rx_qcreate_info {
 	/** Memory pool to allocate Rx buffer from */
 	struct rte_mempool	*refill_mb_pool;
+	/** Maximum number of pushed Rx descriptors in the queue */
+	unsigned int		max_fill_level;
 	/** Minimum number of unused Rx descriptors to do refill */
 	unsigned int		refill_threshold;
 	/**
diff --git a/drivers/net/sfc/sfc_ef10_rx.c b/drivers/net/sfc/sfc_ef10_rx.c
index 29524ce..fc89078 100644
--- a/drivers/net/sfc/sfc_ef10_rx.c
+++ b/drivers/net/sfc/sfc_ef10_rx.c
@@ -93,6 +93,7 @@ struct sfc_ef10_rxq {
 	/* Used on refill */
 	uint16_t			buf_size;
 	unsigned int			added;
+	unsigned int			max_fill_level;
 	unsigned int			refill_threshold;
 	struct rte_mempool		*refill_mb_pool;
 	efx_qword_t			*rxq_hw_ring;
@@ -141,8 +142,7 @@ sfc_ef10_rx_qrefill(struct sfc_ef10_rxq *rxq)
 	void *objs[SFC_RX_REFILL_BULK];
 	unsigned int added = rxq->added;
 
-	free_space = SFC_EF10_RXQ_LIMIT(ptr_mask + 1) -
-		(added - rxq->completed);
+	free_space = rxq->max_fill_level - (added - rxq->completed);
 
 	if (free_space < rxq->refill_threshold)
 		return;
@@ -620,6 +620,7 @@ sfc_ef10_rx_qcreate(uint16_t port_id, uint16_t queue_id,
 		rxq->flags |= SFC_EF10_RXQ_RSS_HASH;
 	rxq->ptr_mask = info->rxq_entries - 1;
 	rxq->evq_hw_ring = info->evq_hw_ring;
+	rxq->max_fill_level = info->max_fill_level;
 	rxq->refill_threshold = info->refill_threshold;
 	rxq->rearm_data =
 		sfc_ef10_mk_mbuf_rearm_data(port_id, info->prefix_size);
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 43d51c4..ecf8e99 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -88,8 +88,7 @@ sfc_efx_rx_qrefill(struct sfc_efx_rxq *rxq)
 	struct rte_mbuf *m;
 	uint16_t port_id = rxq->dp.dpq.port_id;
 
-	free_space = EFX_RXQ_LIMIT(rxq->ptr_mask + 1) -
-		(added - rxq->completed);
+	free_space = rxq->max_fill_level - (added - rxq->completed);
 
 	if (free_space < rxq->refill_threshold)
 		return;
@@ -459,6 +458,7 @@ sfc_efx_rx_qcreate(uint16_t port_id, uint16_t queue_id,
 	rxq->ptr_mask = info->rxq_entries - 1;
 	rxq->batch_max = info->batch_max;
 	rxq->prefix_size = info->prefix_size;
+	rxq->max_fill_level = info->max_fill_level;
 	rxq->refill_threshold = info->refill_threshold;
 	rxq->buf_size = info->buf_size;
 	rxq->refill_mb_pool = info->refill_mb_pool;
@@ -993,6 +993,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 
 	memset(&info, 0, sizeof(info));
 	info.refill_mb_pool = rxq->refill_mb_pool;
+	info.max_fill_level = rxq_max_fill_level;
 	info.refill_threshold = rxq->refill_threshold;
 	info.buf_size = buf_size;
 	info.batch_max = encp->enc_rx_batch_max;
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index 9e6282e..d2f4471 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -121,6 +121,7 @@ struct sfc_efx_rxq {
 	/* Used on refill */
 	unsigned int			added;
 	unsigned int			pushed;
+	unsigned int			max_fill_level;
 	unsigned int			refill_threshold;
 	uint16_t			buf_size;
 	struct rte_mempool		*refill_mb_pool;
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH 4/6] net/sfc: use Tx queue max fill level calculated on init
  2017-12-26  7:27 [dpdk-dev] [PATCH 0/6] net/sfc: support more options for a number of Rx/Tx descs Andrew Rybchenko
                   ` (2 preceding siblings ...)
  2017-12-26  7:27 ` [dpdk-dev] [PATCH 3/6] net/sfc: use Rx queue max fill level calculated on init Andrew Rybchenko
@ 2017-12-26  7:27 ` Andrew Rybchenko
  2017-12-26  7:27 ` [dpdk-dev] [PATCH 5/6] net/sfc: support more options for a number of Rx descriptors Andrew Rybchenko
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-26  7:27 UTC (permalink / raw)
  To: dev

Prepare to support more options for number of Tx descriptors.

libefx-based datapath is updated just for completeness to
make code more readable and less error-prone.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc_dp_tx.h   |  2 ++
 drivers/net/sfc/sfc_ef10_tx.c | 20 ++++++++------------
 drivers/net/sfc/sfc_tx.c      |  6 ++++--
 drivers/net/sfc/sfc_tx.h      |  1 +
 4 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/net/sfc/sfc_dp_tx.h b/drivers/net/sfc/sfc_dp_tx.h
index 32d7681..4485b2f 100644
--- a/drivers/net/sfc/sfc_dp_tx.h
+++ b/drivers/net/sfc/sfc_dp_tx.h
@@ -57,6 +57,8 @@ struct sfc_dp_txq {
  * readable.
  */
 struct sfc_dp_tx_qcreate_info {
+	/** Maximum number of pushed Tx descriptors */
+	unsigned int		max_fill_level;
 	/** Minimum number of unused Tx descriptors to do reap */
 	unsigned int		free_thresh;
 	/** Transmit queue configuration flags */
diff --git a/drivers/net/sfc/sfc_ef10_tx.c b/drivers/net/sfc/sfc_ef10_tx.c
index ab3334a..99fe87e 100644
--- a/drivers/net/sfc/sfc_ef10_tx.c
+++ b/drivers/net/sfc/sfc_ef10_tx.c
@@ -77,6 +77,7 @@ struct sfc_ef10_txq {
 	unsigned int			ptr_mask;
 	unsigned int			added;
 	unsigned int			completed;
+	unsigned int			max_fill_level;
 	unsigned int			free_thresh;
 	unsigned int			evq_read_ptr;
 	struct sfc_ef10_tx_sw_desc	*sw_ring;
@@ -288,7 +289,6 @@ static uint16_t
 sfc_ef10_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 {
 	struct sfc_ef10_txq * const txq = sfc_ef10_txq_by_dp_txq(tx_queue);
-	unsigned int ptr_mask;
 	unsigned int added;
 	unsigned int dma_desc_space;
 	bool reap_done;
@@ -299,16 +299,13 @@ sfc_ef10_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 		     (SFC_EF10_TXQ_NOT_RUNNING | SFC_EF10_TXQ_EXCEPTION)))
 		return 0;
 
-	ptr_mask = txq->ptr_mask;
 	added = txq->added;
-	dma_desc_space = SFC_EF10_TXQ_LIMIT(ptr_mask + 1) -
-			 (added - txq->completed);
+	dma_desc_space = txq->max_fill_level - (added - txq->completed);
 
 	reap_done = (dma_desc_space < txq->free_thresh);
 	if (reap_done) {
 		sfc_ef10_tx_reap(txq);
-		dma_desc_space = SFC_EF10_TXQ_LIMIT(ptr_mask + 1) -
-				 (added - txq->completed);
+		dma_desc_space = txq->max_fill_level - (added - txq->completed);
 	}
 
 	for (pktp = &tx_pkts[0], pktp_end = &tx_pkts[nb_pkts];
@@ -333,7 +330,7 @@ sfc_ef10_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 
 			sfc_ef10_tx_reap(txq);
 			reap_done = true;
-			dma_desc_space = SFC_EF10_TXQ_LIMIT(ptr_mask + 1) -
+			dma_desc_space = txq->max_fill_level -
 				(added - txq->completed);
 			if (sfc_ef10_tx_pkt_descs_max(m_seg) > dma_desc_space)
 				break;
@@ -343,7 +340,7 @@ sfc_ef10_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 		do {
 			rte_iova_t seg_addr = rte_mbuf_data_iova(m_seg);
 			unsigned int seg_len = rte_pktmbuf_data_len(m_seg);
-			unsigned int id = added & ptr_mask;
+			unsigned int id = added & txq->ptr_mask;
 
 			SFC_ASSERT(seg_len <= SFC_EF10_TX_DMA_DESC_LEN_MAX);
 
@@ -446,14 +443,12 @@ sfc_ef10_simple_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 
 	ptr_mask = txq->ptr_mask;
 	added = txq->added;
-	dma_desc_space = SFC_EF10_TXQ_LIMIT(ptr_mask + 1) -
-			 (added - txq->completed);
+	dma_desc_space = txq->max_fill_level - (added - txq->completed);
 
 	reap_done = (dma_desc_space < RTE_MAX(txq->free_thresh, nb_pkts));
 	if (reap_done) {
 		sfc_ef10_simple_tx_reap(txq);
-		dma_desc_space = SFC_EF10_TXQ_LIMIT(ptr_mask + 1) -
-				 (added - txq->completed);
+		dma_desc_space = txq->max_fill_level - (added - txq->completed);
 	}
 
 	pktp_end = &tx_pkts[MIN(nb_pkts, dma_desc_space)];
@@ -532,6 +527,7 @@ sfc_ef10_tx_qcreate(uint16_t port_id, uint16_t queue_id,
 
 	txq->flags = SFC_EF10_TXQ_NOT_RUNNING;
 	txq->ptr_mask = info->txq_entries - 1;
+	txq->max_fill_level = info->max_fill_level;
 	txq->free_thresh = info->free_thresh;
 	txq->txq_hw_ring = info->txq_hw_ring;
 	txq->doorbell = (volatile uint8_t *)info->mem_bar +
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 3c9a6e9..f8ee976 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -196,6 +196,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		goto fail_dma_alloc;
 
 	memset(&info, 0, sizeof(info));
+	info.max_fill_level = txq_max_fill_level;
 	info.free_thresh = txq->free_thresh;
 	info.flags = tx_conf->txq_flags;
 	info.txq_entries = txq_info->entries;
@@ -687,7 +688,7 @@ sfc_efx_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 	unsigned int pushed = added;
 	unsigned int pkts_sent = 0;
 	efx_desc_t *pend = &txq->pend_desc[0];
-	const unsigned int hard_max_fill = EFX_TXQ_LIMIT(txq->ptr_mask + 1);
+	const unsigned int hard_max_fill = txq->max_fill_level;
 	const unsigned int soft_max_fill = hard_max_fill - txq->free_thresh;
 	unsigned int fill_level = added - txq->completed;
 	boolean_t reap_done;
@@ -933,6 +934,7 @@ sfc_efx_tx_qcreate(uint16_t port_id, uint16_t queue_id,
 
 	txq->evq = ctrl_txq->evq;
 	txq->ptr_mask = info->txq_entries - 1;
+	txq->max_fill_level = info->max_fill_level;
 	txq->free_thresh = info->free_thresh;
 	txq->dma_desc_size_max = info->dma_desc_size_max;
 
@@ -1022,7 +1024,7 @@ sfc_efx_tx_qdesc_status(struct sfc_dp_txq *dp_txq, uint16_t offset)
 	if (unlikely(offset > txq->ptr_mask))
 		return -EINVAL;
 
-	if (unlikely(offset >= EFX_TXQ_LIMIT(txq->ptr_mask + 1)))
+	if (unlikely(offset >= txq->max_fill_level))
 		return RTE_ETH_TX_DESC_UNAVAIL;
 
 	/*
diff --git a/drivers/net/sfc/sfc_tx.h b/drivers/net/sfc/sfc_tx.h
index 0c1c708..2318f31 100644
--- a/drivers/net/sfc/sfc_tx.h
+++ b/drivers/net/sfc/sfc_tx.h
@@ -110,6 +110,7 @@ struct sfc_efx_txq {
 	unsigned int			added;
 	unsigned int			pending;
 	unsigned int			completed;
+	unsigned int			max_fill_level;
 	unsigned int			free_thresh;
 	uint16_t			hw_vlan_tci;
 	uint16_t			dma_desc_size_max;
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH 5/6] net/sfc: support more options for a number of Rx descriptors
  2017-12-26  7:27 [dpdk-dev] [PATCH 0/6] net/sfc: support more options for a number of Rx/Tx descs Andrew Rybchenko
                   ` (3 preceding siblings ...)
  2017-12-26  7:27 ` [dpdk-dev] [PATCH 4/6] net/sfc: use Tx " Andrew Rybchenko
@ 2017-12-26  7:27 ` Andrew Rybchenko
  2017-12-26  7:27 ` [dpdk-dev] [PATCH 6/6] net/sfc: support more options for a number of Tx descriptors Andrew Rybchenko
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-26  7:27 UTC (permalink / raw)
  To: dev

The number of Rx descriptors is not used as HW Rx ring size any more.
It simply defines maximum fill level.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc_dp_rx.h   |  8 ++++++++
 drivers/net/sfc/sfc_ef10_rx.c | 30 +++++++++++++++++++++++++++---
 drivers/net/sfc/sfc_ethdev.c  |  4 ++++
 drivers/net/sfc/sfc_rx.c      |  4 ++++
 4 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/drivers/net/sfc/sfc_dp_rx.h b/drivers/net/sfc/sfc_dp_rx.h
index f62d79a..367477a 100644
--- a/drivers/net/sfc/sfc_dp_rx.h
+++ b/drivers/net/sfc/sfc_dp_rx.h
@@ -103,6 +103,13 @@ struct sfc_dp_rx_qcreate_info {
 };
 
 /**
+ * Get Rx datapath specific device info.
+ *
+ * @param dev_info		Device info to be adjusted
+ */
+typedef void (sfc_dp_rx_get_dev_info_t)(struct rte_eth_dev_info *dev_info);
+
+/**
  * Get size of receive and event queue rings by the number of Rx
  * descriptors.
  *
@@ -184,6 +191,7 @@ struct sfc_dp_rx {
 	unsigned int				features;
 #define SFC_DP_RX_FEAT_SCATTER			0x1
 #define SFC_DP_RX_FEAT_MULTI_PROCESS		0x2
+	sfc_dp_rx_get_dev_info_t		*get_dev_info;
 	sfc_dp_rx_qsize_up_rings_t		*qsize_up_rings;
 	sfc_dp_rx_qcreate_t			*qcreate;
 	sfc_dp_rx_qdestroy_t			*qdestroy;
diff --git a/drivers/net/sfc/sfc_ef10_rx.c b/drivers/net/sfc/sfc_ef10_rx.c
index fc89078..8516e25 100644
--- a/drivers/net/sfc/sfc_ef10_rx.c
+++ b/drivers/net/sfc/sfc_ef10_rx.c
@@ -553,6 +553,19 @@ sfc_ef10_rx_qdesc_status(__rte_unused struct sfc_dp_rxq *dp_rxq,
 }
 
 
+static sfc_dp_rx_get_dev_info_t sfc_ef10_rx_get_dev_info;
+static void
+sfc_ef10_rx_get_dev_info(struct rte_eth_dev_info *dev_info)
+{
+	/*
+	 * Number of descriptors just defines maximum number of pushed
+	 * descriptors (fill level).
+	 */
+	dev_info->rx_desc_lim.nb_min = SFC_RX_REFILL_BULK;
+	dev_info->rx_desc_lim.nb_align = SFC_RX_REFILL_BULK;
+}
+
+
 static sfc_dp_rx_qsize_up_rings_t sfc_ef10_rx_qsize_up_rings;
 static int
 sfc_ef10_rx_qsize_up_rings(uint16_t nb_rx_desc,
@@ -560,9 +573,19 @@ sfc_ef10_rx_qsize_up_rings(uint16_t nb_rx_desc,
 			   unsigned int *evq_entries,
 			   unsigned int *rxq_max_fill_level)
 {
-	*rxq_entries = nb_rx_desc;
-	*evq_entries = nb_rx_desc;
-	*rxq_max_fill_level = SFC_EF10_RXQ_LIMIT(*rxq_entries);
+	/*
+	 * rte_ethdev API guarantees that the number meets min, max and
+	 * alignment requirements.
+	 */
+	if (nb_rx_desc <= EFX_RXQ_MINNDESCS)
+		*rxq_entries = EFX_RXQ_MINNDESCS;
+	else
+		*rxq_entries = rte_align32pow2(nb_rx_desc);
+
+	*evq_entries = *rxq_entries;
+
+	*rxq_max_fill_level = RTE_MIN(nb_rx_desc,
+				      SFC_EF10_RXQ_LIMIT(*evq_entries));
 	return 0;
 }
 
@@ -723,6 +746,7 @@ struct sfc_dp_rx sfc_ef10_rx = {
 		.hw_fw_caps	= SFC_DP_HW_FW_CAP_EF10,
 	},
 	.features		= SFC_DP_RX_FEAT_MULTI_PROCESS,
+	.get_dev_info		= sfc_ef10_rx_get_dev_info,
 	.qsize_up_rings		= sfc_ef10_rx_qsize_up_rings,
 	.qcreate		= sfc_ef10_rx_qcreate,
 	.qdestroy		= sfc_ef10_rx_qdestroy,
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index fabcc32..6ff4595 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -163,6 +163,7 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	if (sa->tso)
 		dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_TCP_TSO;
 
+	/* Initialize to hardware limits */
 	dev_info->rx_desc_lim.nb_max = EFX_RXQ_MAXNDESCS;
 	dev_info->rx_desc_lim.nb_min = EFX_RXQ_MINNDESCS;
 	/* The RXQ hardware requires that the descriptor count is a power
@@ -177,6 +178,9 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	 * of 2, but tx_desc_lim cannot properly describe that constraint
 	 */
 	dev_info->tx_desc_lim.nb_align = EFX_TXQ_MINNDESCS;
+
+	if (sa->dp_rx->get_dev_info != NULL)
+		sa->dp_rx->get_dev_info(dev_info);
 }
 
 static const uint32_t *
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index ecf8e99..6b31e56 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -933,6 +933,10 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 				       &rxq_max_fill_level);
 	if (rc != 0)
 		goto fail_size_up_rings;
+	SFC_ASSERT(rxq_entries >= EFX_RXQ_MINNDESCS);
+	SFC_ASSERT(rxq_entries <= EFX_RXQ_MAXNDESCS);
+	SFC_ASSERT(rxq_entries >= nb_rx_desc);
+	SFC_ASSERT(rxq_max_fill_level <= nb_rx_desc);
 
 	rc = sfc_rx_qcheck_conf(sa, rxq_max_fill_level, rx_conf);
 	if (rc != 0)
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH 6/6] net/sfc: support more options for a number of Tx descriptors
  2017-12-26  7:27 [dpdk-dev] [PATCH 0/6] net/sfc: support more options for a number of Rx/Tx descs Andrew Rybchenko
                   ` (4 preceding siblings ...)
  2017-12-26  7:27 ` [dpdk-dev] [PATCH 5/6] net/sfc: support more options for a number of Rx descriptors Andrew Rybchenko
@ 2017-12-26  7:27 ` Andrew Rybchenko
  2018-01-09 19:31 ` [dpdk-dev] [PATCH 0/6] net/sfc: support more options for a number of Rx/Tx descs Ferruh Yigit
  2018-01-09 20:24 ` [dpdk-dev] [PATCH v2 " Andrew Rybchenko
  7 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-26  7:27 UTC (permalink / raw)
  To: dev

The number of Tx descriptors is not used as HW Tx ring size any more.
It simply defines maximum fill level.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc_dp_tx.h   |  8 ++++++++
 drivers/net/sfc/sfc_ef10_tx.c | 29 ++++++++++++++++++++++++++---
 drivers/net/sfc/sfc_ethdev.c  |  3 +++
 drivers/net/sfc/sfc_tx.c      |  5 ++++-
 4 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/drivers/net/sfc/sfc_dp_tx.h b/drivers/net/sfc/sfc_dp_tx.h
index 4485b2f..a384a53 100644
--- a/drivers/net/sfc/sfc_dp_tx.h
+++ b/drivers/net/sfc/sfc_dp_tx.h
@@ -80,6 +80,13 @@ struct sfc_dp_tx_qcreate_info {
 };
 
 /**
+ * Get Tx datapath specific device info.
+ *
+ * @param dev_info		Device info to be adjusted
+ */
+typedef void (sfc_dp_tx_get_dev_info_t)(struct rte_eth_dev_info *dev_info);
+
+/**
  * Get size of transmit and event queue rings by the number of Tx
  * descriptors.
  *
@@ -162,6 +169,7 @@ struct sfc_dp_tx {
 #define SFC_DP_TX_FEAT_MULTI_PROCESS	0x8
 #define SFC_DP_TX_FEAT_MULTI_POOL	0x10
 #define SFC_DP_TX_FEAT_REFCNT		0x20
+	sfc_dp_tx_get_dev_info_t	*get_dev_info;
 	sfc_dp_tx_qsize_up_rings_t	*qsize_up_rings;
 	sfc_dp_tx_qcreate_t		*qcreate;
 	sfc_dp_tx_qdestroy_t		*qdestroy;
diff --git a/drivers/net/sfc/sfc_ef10_tx.c b/drivers/net/sfc/sfc_ef10_tx.c
index 99fe87e..02df39c 100644
--- a/drivers/net/sfc/sfc_ef10_tx.c
+++ b/drivers/net/sfc/sfc_ef10_tx.c
@@ -481,6 +481,17 @@ sfc_ef10_simple_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 	return pktp - &tx_pkts[0];
 }
 
+static sfc_dp_tx_get_dev_info_t sfc_ef10_get_dev_info;
+static void
+sfc_ef10_get_dev_info(struct rte_eth_dev_info *dev_info)
+{
+	/*
+	 * Number of descriptors just defines maximum number of pushed
+	 * descriptors (fill level).
+	 */
+	dev_info->tx_desc_lim.nb_min = 1;
+	dev_info->tx_desc_lim.nb_align = 1;
+}
 
 static sfc_dp_tx_qsize_up_rings_t sfc_ef10_tx_qsize_up_rings;
 static int
@@ -489,9 +500,19 @@ sfc_ef10_tx_qsize_up_rings(uint16_t nb_tx_desc,
 			   unsigned int *evq_entries,
 			   unsigned int *txq_max_fill_level)
 {
-	*txq_entries = nb_tx_desc;
-	*evq_entries = nb_tx_desc;
-	*txq_max_fill_level = SFC_EF10_TXQ_LIMIT(*txq_entries);
+	/*
+	 * rte_ethdev API guarantees that the number meets min, max and
+	 * alignment requirements.
+	 */
+	if (nb_tx_desc <= EFX_TXQ_MINNDESCS)
+		*txq_entries = EFX_TXQ_MINNDESCS;
+	else
+		*txq_entries = rte_align32pow2(nb_tx_desc);
+
+	*evq_entries = *txq_entries;
+
+	*txq_max_fill_level = RTE_MIN(nb_tx_desc,
+				      SFC_EF10_TXQ_LIMIT(*evq_entries));
 	return 0;
 }
 
@@ -637,6 +658,7 @@ struct sfc_dp_tx sfc_ef10_tx = {
 				  SFC_DP_TX_FEAT_MULTI_POOL |
 				  SFC_DP_TX_FEAT_REFCNT |
 				  SFC_DP_TX_FEAT_MULTI_PROCESS,
+	.get_dev_info		= sfc_ef10_get_dev_info,
 	.qsize_up_rings		= sfc_ef10_tx_qsize_up_rings,
 	.qcreate		= sfc_ef10_tx_qcreate,
 	.qdestroy		= sfc_ef10_tx_qdestroy,
@@ -654,6 +676,7 @@ struct sfc_dp_tx sfc_ef10_simple_tx = {
 		.type		= SFC_DP_TX,
 	},
 	.features		= SFC_DP_TX_FEAT_MULTI_PROCESS,
+	.get_dev_info		= sfc_ef10_get_dev_info,
 	.qsize_up_rings		= sfc_ef10_tx_qsize_up_rings,
 	.qcreate		= sfc_ef10_tx_qcreate,
 	.qdestroy		= sfc_ef10_tx_qdestroy,
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 6ff4595..7d75f55 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -171,6 +171,7 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	 */
 	dev_info->rx_desc_lim.nb_align = EFX_RXQ_MINNDESCS;
 
+	/* Initialize to hardware limits */
 	dev_info->tx_desc_lim.nb_max = sa->txq_max_entries;
 	dev_info->tx_desc_lim.nb_min = EFX_TXQ_MINNDESCS;
 	/*
@@ -181,6 +182,8 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	if (sa->dp_rx->get_dev_info != NULL)
 		sa->dp_rx->get_dev_info(dev_info);
+	if (sa->dp_tx->get_dev_info != NULL)
+		sa->dp_tx->get_dev_info(dev_info);
 }
 
 static const uint32_t *
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index f8ee976..f3f447b 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -160,6 +160,10 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 				       &txq_max_fill_level);
 	if (rc != 0)
 		goto fail_size_up_rings;
+	SFC_ASSERT(txq_entries >= EFX_TXQ_MINNDESCS);
+	SFC_ASSERT(txq_entries <= sa->txq_max_entries);
+	SFC_ASSERT(txq_entries >= nb_tx_desc);
+	SFC_ASSERT(txq_max_fill_level <= nb_tx_desc);
 
 	rc = sfc_tx_qcheck_conf(sa, txq_max_fill_level, tx_conf);
 	if (rc != 0)
@@ -168,7 +172,6 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	SFC_ASSERT(sw_index < sa->txq_count);
 	txq_info = &sa->txq_info[sw_index];
 
-	SFC_ASSERT(txq_entries <= sa->txq_max_entries);
 	txq_info->entries = txq_entries;
 
 	rc = sfc_ev_qinit(sa, SFC_EVQ_TYPE_TX, sw_index,
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [dpdk-dev] [PATCH 0/6] net/sfc: support more options for a number of Rx/Tx descs
  2017-12-26  7:27 [dpdk-dev] [PATCH 0/6] net/sfc: support more options for a number of Rx/Tx descs Andrew Rybchenko
                   ` (5 preceding siblings ...)
  2017-12-26  7:27 ` [dpdk-dev] [PATCH 6/6] net/sfc: support more options for a number of Tx descriptors Andrew Rybchenko
@ 2018-01-09 19:31 ` Ferruh Yigit
  2018-01-09 20:24 ` [dpdk-dev] [PATCH v2 " Andrew Rybchenko
  7 siblings, 0 replies; 16+ messages in thread
From: Ferruh Yigit @ 2018-01-09 19:31 UTC (permalink / raw)
  To: Andrew Rybchenko, dev

On 12/26/2017 7:27 AM, Andrew Rybchenko wrote:

> The patch series is made independent from [1] submitted a bit earlier
> to avoid automatic build failures and to be able to apply this one first.
> When one is applied, the second should be rebased.
> 
> [1] http://dpdk.org/ml/archives/dev/2017-December/084843.html

I just discover what you have already said :) Can you please rebase the set on
top of latest next-net?

Thanks,
ferruh

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH v2 0/6] net/sfc: support more options for a number of Rx/Tx descs
  2017-12-26  7:27 [dpdk-dev] [PATCH 0/6] net/sfc: support more options for a number of Rx/Tx descs Andrew Rybchenko
                   ` (6 preceding siblings ...)
  2018-01-09 19:31 ` [dpdk-dev] [PATCH 0/6] net/sfc: support more options for a number of Rx/Tx descs Ferruh Yigit
@ 2018-01-09 20:24 ` Andrew Rybchenko
  2018-01-09 20:24   ` [dpdk-dev] [PATCH v2 1/6] net/sfc: make refill threshold check Rx datapath specific Andrew Rybchenko
                     ` (6 more replies)
  7 siblings, 7 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2018-01-09 20:24 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit

The minimum size of Rx/Tx descriptor rings supported by Solarflare HW is 512.
It adds inconvenience to run DPDK applications which typically use smaller
default values. Also smaller numbers of used descriptors is better for
performance.

The patch series adds possibility to use any number of Rx/Tx descriptors
in the range, for example, from 1 to 2048 for Tx and from 8 to 4096 for Rx.
Maximum value is defined by HW maximum.

v2:
 - rebased

Andrew Rybchenko (6):
  net/sfc: make refill threshold check Rx datapath specific
  net/sfc: make Tx free threshold check datapath specific
  net/sfc: use Rx queue max fill level calculated on init
  net/sfc: use Tx queue max fill level calculated on init
  net/sfc: support more options for a number of Rx descriptors
  net/sfc: support more options for a number of Tx descriptors

 drivers/net/sfc/sfc_dp_rx.h   | 27 ++++++++++++++++++++
 drivers/net/sfc/sfc_dp_tx.h   | 27 ++++++++++++++++++++
 drivers/net/sfc/sfc_ef10_rx.c | 44 ++++++++++++++++++++++++++++++--
 drivers/net/sfc/sfc_ef10_tx.c | 58 ++++++++++++++++++++++++++++++++++---------
 drivers/net/sfc/sfc_ethdev.c  |  7 ++++++
 drivers/net/sfc/sfc_rx.c      | 49 ++++++++++++++++++++++++++++--------
 drivers/net/sfc/sfc_rx.h      |  1 +
 drivers/net/sfc/sfc_tx.c      | 48 +++++++++++++++++++++++++++--------
 drivers/net/sfc/sfc_tx.h      |  1 +
 9 files changed, 227 insertions(+), 35 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH v2 1/6] net/sfc: make refill threshold check Rx datapath specific
  2018-01-09 20:24 ` [dpdk-dev] [PATCH v2 " Andrew Rybchenko
@ 2018-01-09 20:24   ` Andrew Rybchenko
  2018-01-09 20:24   ` [dpdk-dev] [PATCH v2 2/6] net/sfc: make Tx free threshold check " Andrew Rybchenko
                     ` (5 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2018-01-09 20:24 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit

EFX_RXQ_LIMIT is libefx-specifics and it should not be used
for other Rx datapaths implementations (e.g. EF10 native).

EF10 native Rx datapath has its own understanding of the maximum
RxQ fill level imposed by EvQ clear strategy and space reserved
for Rx error and flush events.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc_dp_rx.h   | 17 +++++++++++++++++
 drivers/net/sfc/sfc_ef10_rx.c | 15 +++++++++++++++
 drivers/net/sfc/sfc_rx.c      | 40 +++++++++++++++++++++++++++++++---------
 3 files changed, 63 insertions(+), 9 deletions(-)

diff --git a/drivers/net/sfc/sfc_dp_rx.h b/drivers/net/sfc/sfc_dp_rx.h
index 33e06ac..d2e3106 100644
--- a/drivers/net/sfc/sfc_dp_rx.h
+++ b/drivers/net/sfc/sfc_dp_rx.h
@@ -101,6 +101,22 @@ struct sfc_dp_rx_qcreate_info {
 };
 
 /**
+ * Get size of receive and event queue rings by the number of Rx
+ * descriptors.
+ *
+ * @param nb_rx_desc		Number of Rx descriptors
+ * @param rxq_entries		Location for number of Rx ring entries
+ * @param evq_entries		Location for number of event ring entries
+ * @param rxq_max_fill_level	Location for maximum Rx ring fill level
+ *
+ * @return 0 or positive errno.
+ */
+typedef int (sfc_dp_rx_qsize_up_rings_t)(uint16_t nb_rx_desc,
+					 unsigned int *rxq_entries,
+					 unsigned int *evq_entries,
+					 unsigned int *rxq_max_fill_level);
+
+/**
  * Allocate and initialize datapath receive queue.
  *
  * @param port_id	The port identifier
@@ -168,6 +184,7 @@ struct sfc_dp_rx {
 #define SFC_DP_RX_FEAT_SCATTER			0x1
 #define SFC_DP_RX_FEAT_MULTI_PROCESS		0x2
 #define SFC_DP_RX_FEAT_TUNNELS			0x4
+	sfc_dp_rx_qsize_up_rings_t		*qsize_up_rings;
 	sfc_dp_rx_qcreate_t			*qcreate;
 	sfc_dp_rx_qdestroy_t			*qdestroy;
 	sfc_dp_rx_qstart_t			*qstart;
diff --git a/drivers/net/sfc/sfc_ef10_rx.c b/drivers/net/sfc/sfc_ef10_rx.c
index e860a39..192cfb4 100644
--- a/drivers/net/sfc/sfc_ef10_rx.c
+++ b/drivers/net/sfc/sfc_ef10_rx.c
@@ -638,6 +638,20 @@ sfc_ef10_rx_qdesc_status(__rte_unused struct sfc_dp_rxq *dp_rxq,
 }
 
 
+static sfc_dp_rx_qsize_up_rings_t sfc_ef10_rx_qsize_up_rings;
+static int
+sfc_ef10_rx_qsize_up_rings(uint16_t nb_rx_desc,
+			   unsigned int *rxq_entries,
+			   unsigned int *evq_entries,
+			   unsigned int *rxq_max_fill_level)
+{
+	*rxq_entries = nb_rx_desc;
+	*evq_entries = nb_rx_desc;
+	*rxq_max_fill_level = SFC_EF10_RXQ_LIMIT(*rxq_entries);
+	return 0;
+}
+
+
 static uint64_t
 sfc_ef10_mk_mbuf_rearm_data(uint16_t port_id, uint16_t prefix_size)
 {
@@ -794,6 +808,7 @@ struct sfc_dp_rx sfc_ef10_rx = {
 	},
 	.features		= SFC_DP_RX_FEAT_MULTI_PROCESS |
 				  SFC_DP_RX_FEAT_TUNNELS,
+	.qsize_up_rings		= sfc_ef10_rx_qsize_up_rings,
 	.qcreate		= sfc_ef10_rx_qcreate,
 	.qdestroy		= sfc_ef10_rx_qdestroy,
 	.qstart			= sfc_ef10_rx_qstart,
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 70a72b3..f9da984 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -413,6 +413,19 @@ sfc_rxq_by_dp_rxq(const struct sfc_dp_rxq *dp_rxq)
 	return rxq;
 }
 
+static sfc_dp_rx_qsize_up_rings_t sfc_efx_rx_qsize_up_rings;
+static int
+sfc_efx_rx_qsize_up_rings(uint16_t nb_rx_desc,
+			  unsigned int *rxq_entries,
+			  unsigned int *evq_entries,
+			  unsigned int *rxq_max_fill_level)
+{
+	*rxq_entries = nb_rx_desc;
+	*evq_entries = nb_rx_desc;
+	*rxq_max_fill_level = EFX_RXQ_LIMIT(*rxq_entries);
+	return 0;
+}
+
 static sfc_dp_rx_qcreate_t sfc_efx_rx_qcreate;
 static int
 sfc_efx_rx_qcreate(uint16_t port_id, uint16_t queue_id,
@@ -535,6 +548,7 @@ struct sfc_dp_rx sfc_efx_rx = {
 		.hw_fw_caps	= 0,
 	},
 	.features		= SFC_DP_RX_FEAT_SCATTER,
+	.qsize_up_rings		= sfc_efx_rx_qsize_up_rings,
 	.qcreate		= sfc_efx_rx_qcreate,
 	.qdestroy		= sfc_efx_rx_qdestroy,
 	.qstart			= sfc_efx_rx_qstart,
@@ -771,10 +785,9 @@ sfc_rx_qstop(struct sfc_adapter *sa, unsigned int sw_index)
 }
 
 static int
-sfc_rx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_rx_desc,
+sfc_rx_qcheck_conf(struct sfc_adapter *sa, unsigned int rxq_max_fill_level,
 		   const struct rte_eth_rxconf *rx_conf)
 {
-	const uint16_t rx_free_thresh_max = EFX_RXQ_LIMIT(nb_rx_desc);
 	int rc = 0;
 
 	if (rx_conf->rx_thresh.pthresh != 0 ||
@@ -784,10 +797,10 @@ sfc_rx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_rx_desc,
 			"RxQ prefetch/host/writeback thresholds are not supported");
 	}
 
-	if (rx_conf->rx_free_thresh > rx_free_thresh_max) {
+	if (rx_conf->rx_free_thresh > rxq_max_fill_level) {
 		sfc_err(sa,
 			"RxQ free threshold too large: %u vs maximum %u",
-			rx_conf->rx_free_thresh, rx_free_thresh_max);
+			rx_conf->rx_free_thresh, rxq_max_fill_level);
 		rc = EINVAL;
 	}
 
@@ -907,13 +920,21 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 {
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
 	int rc;
+	unsigned int rxq_entries;
+	unsigned int evq_entries;
+	unsigned int rxq_max_fill_level;
 	uint16_t buf_size;
 	struct sfc_rxq_info *rxq_info;
 	struct sfc_evq *evq;
 	struct sfc_rxq *rxq;
 	struct sfc_dp_rx_qcreate_info info;
 
-	rc = sfc_rx_qcheck_conf(sa, nb_rx_desc, rx_conf);
+	rc = sa->dp_rx->qsize_up_rings(nb_rx_desc, &rxq_entries, &evq_entries,
+				       &rxq_max_fill_level);
+	if (rc != 0)
+		goto fail_size_up_rings;
+
+	rc = sfc_rx_qcheck_conf(sa, rxq_max_fill_level, rx_conf);
 	if (rc != 0)
 		goto fail_bad_conf;
 
@@ -940,8 +961,8 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	SFC_ASSERT(sw_index < sa->rxq_count);
 	rxq_info = &sa->rxq_info[sw_index];
 
-	SFC_ASSERT(nb_rx_desc <= rxq_info->max_entries);
-	rxq_info->entries = nb_rx_desc;
+	SFC_ASSERT(rxq_entries <= rxq_info->max_entries);
+	rxq_info->entries = rxq_entries;
 	rxq_info->type = EFX_RXQ_TYPE_DEFAULT;
 	rxq_info->type_flags =
 		sa->eth_dev->data->dev_conf.rxmode.enable_scatter ?
@@ -952,7 +973,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		rxq_info->type_flags |= EFX_RXQ_FLAG_INNER_CLASSES;
 
 	rc = sfc_ev_qinit(sa, SFC_EVQ_TYPE_RX, sw_index,
-			  rxq_info->entries, socket_id, &evq);
+			  evq_entries, socket_id, &evq);
 	if (rc != 0)
 		goto fail_ev_qinit;
 
@@ -989,7 +1010,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 
 	info.rxq_entries = rxq_info->entries;
 	info.rxq_hw_ring = rxq->mem.esm_base;
-	info.evq_entries = rxq_info->entries;
+	info.evq_entries = evq_entries;
 	info.evq_hw_ring = evq->mem.esm_base;
 	info.hw_index = rxq->hw_index;
 	info.mem_bar = sa->mem_bar.esb_base;
@@ -1022,6 +1043,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	rxq_info->entries = 0;
 
 fail_bad_conf:
+fail_size_up_rings:
 	sfc_log_init(sa, "failed %d", rc);
 	return rc;
 }
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH v2 2/6] net/sfc: make Tx free threshold check datapath specific
  2018-01-09 20:24 ` [dpdk-dev] [PATCH v2 " Andrew Rybchenko
  2018-01-09 20:24   ` [dpdk-dev] [PATCH v2 1/6] net/sfc: make refill threshold check Rx datapath specific Andrew Rybchenko
@ 2018-01-09 20:24   ` Andrew Rybchenko
  2018-01-09 20:24   ` [dpdk-dev] [PATCH v2 3/6] net/sfc: use Rx queue max fill level calculated on init Andrew Rybchenko
                     ` (4 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2018-01-09 20:24 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit

EFX_TXQ_LIMIT is libefx-specifics and it should not be used
for other Tx datapaths implementations (e.g. EF10 native).

EF10 native Tx datapath has its own understanding of the maximum
TxQ fill level imposed by EvQ clear strategy and space reserved
for Tx error and flush events.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc_dp_tx.h   | 17 +++++++++++++++++
 drivers/net/sfc/sfc_ef10_tx.c | 15 +++++++++++++++
 drivers/net/sfc/sfc_tx.c      | 39 +++++++++++++++++++++++++++++++--------
 3 files changed, 63 insertions(+), 8 deletions(-)

diff --git a/drivers/net/sfc/sfc_dp_tx.h b/drivers/net/sfc/sfc_dp_tx.h
index 94d1b10..32d7681 100644
--- a/drivers/net/sfc/sfc_dp_tx.h
+++ b/drivers/net/sfc/sfc_dp_tx.h
@@ -78,6 +78,22 @@ struct sfc_dp_tx_qcreate_info {
 };
 
 /**
+ * Get size of transmit and event queue rings by the number of Tx
+ * descriptors.
+ *
+ * @param nb_tx_desc		Number of Tx descriptors
+ * @param txq_entries		Location for number of Tx ring entries
+ * @param evq_entries		Location for number of event ring entries
+ * @param txq_max_fill_level	Location for maximum Tx ring fill level
+ *
+ * @return 0 or positive errno.
+ */
+typedef int (sfc_dp_tx_qsize_up_rings_t)(uint16_t nb_tx_desc,
+					 unsigned int *txq_entries,
+					 unsigned int *evq_entries,
+					 unsigned int *txq_max_fill_level);
+
+/**
  * Allocate and initialize datapath transmit queue.
  *
  * @param port_id	The port identifier
@@ -144,6 +160,7 @@ struct sfc_dp_tx {
 #define SFC_DP_TX_FEAT_MULTI_PROCESS	0x8
 #define SFC_DP_TX_FEAT_MULTI_POOL	0x10
 #define SFC_DP_TX_FEAT_REFCNT		0x20
+	sfc_dp_tx_qsize_up_rings_t	*qsize_up_rings;
 	sfc_dp_tx_qcreate_t		*qcreate;
 	sfc_dp_tx_qdestroy_t		*qdestroy;
 	sfc_dp_tx_qstart_t		*qstart;
diff --git a/drivers/net/sfc/sfc_ef10_tx.c b/drivers/net/sfc/sfc_ef10_tx.c
index 0454e79..ab3334a 100644
--- a/drivers/net/sfc/sfc_ef10_tx.c
+++ b/drivers/net/sfc/sfc_ef10_tx.c
@@ -487,6 +487,19 @@ sfc_ef10_simple_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 }
 
 
+static sfc_dp_tx_qsize_up_rings_t sfc_ef10_tx_qsize_up_rings;
+static int
+sfc_ef10_tx_qsize_up_rings(uint16_t nb_tx_desc,
+			   unsigned int *txq_entries,
+			   unsigned int *evq_entries,
+			   unsigned int *txq_max_fill_level)
+{
+	*txq_entries = nb_tx_desc;
+	*evq_entries = nb_tx_desc;
+	*txq_max_fill_level = SFC_EF10_TXQ_LIMIT(*txq_entries);
+	return 0;
+}
+
 static sfc_dp_tx_qcreate_t sfc_ef10_tx_qcreate;
 static int
 sfc_ef10_tx_qcreate(uint16_t port_id, uint16_t queue_id,
@@ -628,6 +641,7 @@ struct sfc_dp_tx sfc_ef10_tx = {
 				  SFC_DP_TX_FEAT_MULTI_POOL |
 				  SFC_DP_TX_FEAT_REFCNT |
 				  SFC_DP_TX_FEAT_MULTI_PROCESS,
+	.qsize_up_rings		= sfc_ef10_tx_qsize_up_rings,
 	.qcreate		= sfc_ef10_tx_qcreate,
 	.qdestroy		= sfc_ef10_tx_qdestroy,
 	.qstart			= sfc_ef10_tx_qstart,
@@ -644,6 +658,7 @@ struct sfc_dp_tx sfc_ef10_simple_tx = {
 		.type		= SFC_DP_TX,
 	},
 	.features		= SFC_DP_TX_FEAT_MULTI_PROCESS,
+	.qsize_up_rings		= sfc_ef10_tx_qsize_up_rings,
 	.qcreate		= sfc_ef10_tx_qcreate,
 	.qdestroy		= sfc_ef10_tx_qdestroy,
 	.qstart			= sfc_ef10_tx_qstart,
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index f580fb5..4d2882f 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -57,7 +57,7 @@
 #define SFC_TX_QFLUSH_POLL_ATTEMPTS	(2000)
 
 static int
-sfc_tx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_tx_desc,
+sfc_tx_qcheck_conf(struct sfc_adapter *sa, unsigned int txq_max_fill_level,
 		   const struct rte_eth_txconf *tx_conf)
 {
 	unsigned int flags = tx_conf->txq_flags;
@@ -69,10 +69,10 @@ sfc_tx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_tx_desc,
 		rc = EINVAL;
 	}
 
-	if (tx_conf->tx_free_thresh > EFX_TXQ_LIMIT(nb_tx_desc)) {
+	if (tx_conf->tx_free_thresh > txq_max_fill_level) {
 		sfc_err(sa,
 			"TxQ free threshold too large: %u vs maximum %u",
-			tx_conf->tx_free_thresh, EFX_TXQ_LIMIT(nb_tx_desc));
+			tx_conf->tx_free_thresh, txq_max_fill_level);
 		rc = EINVAL;
 	}
 
@@ -145,6 +145,9 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	     const struct rte_eth_txconf *tx_conf)
 {
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
+	unsigned int txq_entries;
+	unsigned int evq_entries;
+	unsigned int txq_max_fill_level;
 	struct sfc_txq_info *txq_info;
 	struct sfc_evq *evq;
 	struct sfc_txq *txq;
@@ -153,18 +156,23 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 
 	sfc_log_init(sa, "TxQ = %u", sw_index);
 
-	rc = sfc_tx_qcheck_conf(sa, nb_tx_desc, tx_conf);
+	rc = sa->dp_tx->qsize_up_rings(nb_tx_desc, &txq_entries, &evq_entries,
+				       &txq_max_fill_level);
+	if (rc != 0)
+		goto fail_size_up_rings;
+
+	rc = sfc_tx_qcheck_conf(sa, txq_max_fill_level, tx_conf);
 	if (rc != 0)
 		goto fail_bad_conf;
 
 	SFC_ASSERT(sw_index < sa->txq_count);
 	txq_info = &sa->txq_info[sw_index];
 
-	SFC_ASSERT(nb_tx_desc <= sa->txq_max_entries);
-	txq_info->entries = nb_tx_desc;
+	SFC_ASSERT(txq_entries <= sa->txq_max_entries);
+	txq_info->entries = txq_entries;
 
 	rc = sfc_ev_qinit(sa, SFC_EVQ_TYPE_TX, sw_index,
-			  txq_info->entries, socket_id, &evq);
+			  evq_entries, socket_id, &evq);
 	if (rc != 0)
 		goto fail_ev_qinit;
 
@@ -193,7 +201,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	info.txq_entries = txq_info->entries;
 	info.dma_desc_size_max = encp->enc_tx_dma_desc_size_max;
 	info.txq_hw_ring = txq->mem.esm_base;
-	info.evq_entries = txq_info->entries;
+	info.evq_entries = evq_entries;
 	info.evq_hw_ring = evq->mem.esm_base;
 	info.hw_index = txq->hw_index;
 	info.mem_bar = sa->mem_bar.esb_base;
@@ -226,6 +234,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	txq_info->entries = 0;
 
 fail_bad_conf:
+fail_size_up_rings:
 	sfc_log_init(sa, "failed (TxQ = %u, rc = %d)", sw_index, rc);
 	return rc;
 }
@@ -873,6 +882,19 @@ sfc_txq_by_dp_txq(const struct sfc_dp_txq *dp_txq)
 	return txq;
 }
 
+static sfc_dp_tx_qsize_up_rings_t sfc_efx_tx_qsize_up_rings;
+static int
+sfc_efx_tx_qsize_up_rings(uint16_t nb_tx_desc,
+			  unsigned int *txq_entries,
+			  unsigned int *evq_entries,
+			  unsigned int *txq_max_fill_level)
+{
+	*txq_entries = nb_tx_desc;
+	*evq_entries = nb_tx_desc;
+	*txq_max_fill_level = EFX_TXQ_LIMIT(*txq_entries);
+	return 0;
+}
+
 static sfc_dp_tx_qcreate_t sfc_efx_tx_qcreate;
 static int
 sfc_efx_tx_qcreate(uint16_t port_id, uint16_t queue_id,
@@ -1048,6 +1070,7 @@ struct sfc_dp_tx sfc_efx_tx = {
 				  SFC_DP_TX_FEAT_MULTI_POOL |
 				  SFC_DP_TX_FEAT_REFCNT |
 				  SFC_DP_TX_FEAT_MULTI_SEG,
+	.qsize_up_rings		= sfc_efx_tx_qsize_up_rings,
 	.qcreate		= sfc_efx_tx_qcreate,
 	.qdestroy		= sfc_efx_tx_qdestroy,
 	.qstart			= sfc_efx_tx_qstart,
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH v2 3/6] net/sfc: use Rx queue max fill level calculated on init
  2018-01-09 20:24 ` [dpdk-dev] [PATCH v2 " Andrew Rybchenko
  2018-01-09 20:24   ` [dpdk-dev] [PATCH v2 1/6] net/sfc: make refill threshold check Rx datapath specific Andrew Rybchenko
  2018-01-09 20:24   ` [dpdk-dev] [PATCH v2 2/6] net/sfc: make Tx free threshold check " Andrew Rybchenko
@ 2018-01-09 20:24   ` Andrew Rybchenko
  2018-01-09 20:24   ` [dpdk-dev] [PATCH v2 4/6] net/sfc: use Tx " Andrew Rybchenko
                     ` (3 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2018-01-09 20:24 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit

Prepare to support more options for number of Rx descriptors.

libefx-based datapath is updated just for completeness to
make code more readable and less error-prone.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc_dp_rx.h   | 2 ++
 drivers/net/sfc/sfc_ef10_rx.c | 5 +++--
 drivers/net/sfc/sfc_rx.c      | 5 +++--
 drivers/net/sfc/sfc_rx.h      | 1 +
 4 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/sfc/sfc_dp_rx.h b/drivers/net/sfc/sfc_dp_rx.h
index d2e3106..029ebaf 100644
--- a/drivers/net/sfc/sfc_dp_rx.h
+++ b/drivers/net/sfc/sfc_dp_rx.h
@@ -60,6 +60,8 @@ struct sfc_dp_rxq {
 struct sfc_dp_rx_qcreate_info {
 	/** Memory pool to allocate Rx buffer from */
 	struct rte_mempool	*refill_mb_pool;
+	/** Maximum number of pushed Rx descriptors in the queue */
+	unsigned int		max_fill_level;
 	/** Minimum number of unused Rx descriptors to do refill */
 	unsigned int		refill_threshold;
 	/**
diff --git a/drivers/net/sfc/sfc_ef10_rx.c b/drivers/net/sfc/sfc_ef10_rx.c
index 192cfb4..ad84629 100644
--- a/drivers/net/sfc/sfc_ef10_rx.c
+++ b/drivers/net/sfc/sfc_ef10_rx.c
@@ -93,6 +93,7 @@ struct sfc_ef10_rxq {
 	/* Used on refill */
 	uint16_t			buf_size;
 	unsigned int			added;
+	unsigned int			max_fill_level;
 	unsigned int			refill_threshold;
 	struct rte_mempool		*refill_mb_pool;
 	efx_qword_t			*rxq_hw_ring;
@@ -141,8 +142,7 @@ sfc_ef10_rx_qrefill(struct sfc_ef10_rxq *rxq)
 	void *objs[SFC_RX_REFILL_BULK];
 	unsigned int added = rxq->added;
 
-	free_space = SFC_EF10_RXQ_LIMIT(ptr_mask + 1) -
-		(added - rxq->completed);
+	free_space = rxq->max_fill_level - (added - rxq->completed);
 
 	if (free_space < rxq->refill_threshold)
 		return;
@@ -705,6 +705,7 @@ sfc_ef10_rx_qcreate(uint16_t port_id, uint16_t queue_id,
 		rxq->flags |= SFC_EF10_RXQ_RSS_HASH;
 	rxq->ptr_mask = info->rxq_entries - 1;
 	rxq->evq_hw_ring = info->evq_hw_ring;
+	rxq->max_fill_level = info->max_fill_level;
 	rxq->refill_threshold = info->refill_threshold;
 	rxq->rearm_data =
 		sfc_ef10_mk_mbuf_rearm_data(port_id, info->prefix_size);
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index f9da984..387f855 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -88,8 +88,7 @@ sfc_efx_rx_qrefill(struct sfc_efx_rxq *rxq)
 	struct rte_mbuf *m;
 	uint16_t port_id = rxq->dp.dpq.port_id;
 
-	free_space = EFX_RXQ_LIMIT(rxq->ptr_mask + 1) -
-		(added - rxq->completed);
+	free_space = rxq->max_fill_level - (added - rxq->completed);
 
 	if (free_space < rxq->refill_threshold)
 		return;
@@ -459,6 +458,7 @@ sfc_efx_rx_qcreate(uint16_t port_id, uint16_t queue_id,
 	rxq->ptr_mask = info->rxq_entries - 1;
 	rxq->batch_max = info->batch_max;
 	rxq->prefix_size = info->prefix_size;
+	rxq->max_fill_level = info->max_fill_level;
 	rxq->refill_threshold = info->refill_threshold;
 	rxq->buf_size = info->buf_size;
 	rxq->refill_mb_pool = info->refill_mb_pool;
@@ -998,6 +998,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 
 	memset(&info, 0, sizeof(info));
 	info.refill_mb_pool = rxq->refill_mb_pool;
+	info.max_fill_level = rxq_max_fill_level;
 	info.refill_threshold = rxq->refill_threshold;
 	info.buf_size = buf_size;
 	info.batch_max = encp->enc_rx_batch_max;
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index ff72718..956cb3f 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -121,6 +121,7 @@ struct sfc_efx_rxq {
 	/* Used on refill */
 	unsigned int			added;
 	unsigned int			pushed;
+	unsigned int			max_fill_level;
 	unsigned int			refill_threshold;
 	uint16_t			buf_size;
 	struct rte_mempool		*refill_mb_pool;
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH v2 4/6] net/sfc: use Tx queue max fill level calculated on init
  2018-01-09 20:24 ` [dpdk-dev] [PATCH v2 " Andrew Rybchenko
                     ` (2 preceding siblings ...)
  2018-01-09 20:24   ` [dpdk-dev] [PATCH v2 3/6] net/sfc: use Rx queue max fill level calculated on init Andrew Rybchenko
@ 2018-01-09 20:24   ` Andrew Rybchenko
  2018-01-09 20:24   ` [dpdk-dev] [PATCH v2 5/6] net/sfc: support more options for a number of Rx descriptors Andrew Rybchenko
                     ` (2 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2018-01-09 20:24 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit

Prepare to support more options for number of Tx descriptors.

libefx-based datapath is updated just for completeness to
make code more readable and less error-prone.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc_dp_tx.h   |  2 ++
 drivers/net/sfc/sfc_ef10_tx.c | 20 ++++++++------------
 drivers/net/sfc/sfc_tx.c      |  6 ++++--
 drivers/net/sfc/sfc_tx.h      |  1 +
 4 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/net/sfc/sfc_dp_tx.h b/drivers/net/sfc/sfc_dp_tx.h
index 32d7681..4485b2f 100644
--- a/drivers/net/sfc/sfc_dp_tx.h
+++ b/drivers/net/sfc/sfc_dp_tx.h
@@ -57,6 +57,8 @@ struct sfc_dp_txq {
  * readable.
  */
 struct sfc_dp_tx_qcreate_info {
+	/** Maximum number of pushed Tx descriptors */
+	unsigned int		max_fill_level;
 	/** Minimum number of unused Tx descriptors to do reap */
 	unsigned int		free_thresh;
 	/** Transmit queue configuration flags */
diff --git a/drivers/net/sfc/sfc_ef10_tx.c b/drivers/net/sfc/sfc_ef10_tx.c
index ab3334a..99fe87e 100644
--- a/drivers/net/sfc/sfc_ef10_tx.c
+++ b/drivers/net/sfc/sfc_ef10_tx.c
@@ -77,6 +77,7 @@ struct sfc_ef10_txq {
 	unsigned int			ptr_mask;
 	unsigned int			added;
 	unsigned int			completed;
+	unsigned int			max_fill_level;
 	unsigned int			free_thresh;
 	unsigned int			evq_read_ptr;
 	struct sfc_ef10_tx_sw_desc	*sw_ring;
@@ -288,7 +289,6 @@ static uint16_t
 sfc_ef10_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 {
 	struct sfc_ef10_txq * const txq = sfc_ef10_txq_by_dp_txq(tx_queue);
-	unsigned int ptr_mask;
 	unsigned int added;
 	unsigned int dma_desc_space;
 	bool reap_done;
@@ -299,16 +299,13 @@ sfc_ef10_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 		     (SFC_EF10_TXQ_NOT_RUNNING | SFC_EF10_TXQ_EXCEPTION)))
 		return 0;
 
-	ptr_mask = txq->ptr_mask;
 	added = txq->added;
-	dma_desc_space = SFC_EF10_TXQ_LIMIT(ptr_mask + 1) -
-			 (added - txq->completed);
+	dma_desc_space = txq->max_fill_level - (added - txq->completed);
 
 	reap_done = (dma_desc_space < txq->free_thresh);
 	if (reap_done) {
 		sfc_ef10_tx_reap(txq);
-		dma_desc_space = SFC_EF10_TXQ_LIMIT(ptr_mask + 1) -
-				 (added - txq->completed);
+		dma_desc_space = txq->max_fill_level - (added - txq->completed);
 	}
 
 	for (pktp = &tx_pkts[0], pktp_end = &tx_pkts[nb_pkts];
@@ -333,7 +330,7 @@ sfc_ef10_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 
 			sfc_ef10_tx_reap(txq);
 			reap_done = true;
-			dma_desc_space = SFC_EF10_TXQ_LIMIT(ptr_mask + 1) -
+			dma_desc_space = txq->max_fill_level -
 				(added - txq->completed);
 			if (sfc_ef10_tx_pkt_descs_max(m_seg) > dma_desc_space)
 				break;
@@ -343,7 +340,7 @@ sfc_ef10_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 		do {
 			rte_iova_t seg_addr = rte_mbuf_data_iova(m_seg);
 			unsigned int seg_len = rte_pktmbuf_data_len(m_seg);
-			unsigned int id = added & ptr_mask;
+			unsigned int id = added & txq->ptr_mask;
 
 			SFC_ASSERT(seg_len <= SFC_EF10_TX_DMA_DESC_LEN_MAX);
 
@@ -446,14 +443,12 @@ sfc_ef10_simple_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 
 	ptr_mask = txq->ptr_mask;
 	added = txq->added;
-	dma_desc_space = SFC_EF10_TXQ_LIMIT(ptr_mask + 1) -
-			 (added - txq->completed);
+	dma_desc_space = txq->max_fill_level - (added - txq->completed);
 
 	reap_done = (dma_desc_space < RTE_MAX(txq->free_thresh, nb_pkts));
 	if (reap_done) {
 		sfc_ef10_simple_tx_reap(txq);
-		dma_desc_space = SFC_EF10_TXQ_LIMIT(ptr_mask + 1) -
-				 (added - txq->completed);
+		dma_desc_space = txq->max_fill_level - (added - txq->completed);
 	}
 
 	pktp_end = &tx_pkts[MIN(nb_pkts, dma_desc_space)];
@@ -532,6 +527,7 @@ sfc_ef10_tx_qcreate(uint16_t port_id, uint16_t queue_id,
 
 	txq->flags = SFC_EF10_TXQ_NOT_RUNNING;
 	txq->ptr_mask = info->txq_entries - 1;
+	txq->max_fill_level = info->max_fill_level;
 	txq->free_thresh = info->free_thresh;
 	txq->txq_hw_ring = info->txq_hw_ring;
 	txq->doorbell = (volatile uint8_t *)info->mem_bar +
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 4d2882f..8f932b0 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -196,6 +196,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		goto fail_dma_alloc;
 
 	memset(&info, 0, sizeof(info));
+	info.max_fill_level = txq_max_fill_level;
 	info.free_thresh = txq->free_thresh;
 	info.flags = tx_conf->txq_flags;
 	info.txq_entries = txq_info->entries;
@@ -695,7 +696,7 @@ sfc_efx_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 	unsigned int pushed = added;
 	unsigned int pkts_sent = 0;
 	efx_desc_t *pend = &txq->pend_desc[0];
-	const unsigned int hard_max_fill = EFX_TXQ_LIMIT(txq->ptr_mask + 1);
+	const unsigned int hard_max_fill = txq->max_fill_level;
 	const unsigned int soft_max_fill = hard_max_fill - txq->free_thresh;
 	unsigned int fill_level = added - txq->completed;
 	boolean_t reap_done;
@@ -941,6 +942,7 @@ sfc_efx_tx_qcreate(uint16_t port_id, uint16_t queue_id,
 
 	txq->evq = ctrl_txq->evq;
 	txq->ptr_mask = info->txq_entries - 1;
+	txq->max_fill_level = info->max_fill_level;
 	txq->free_thresh = info->free_thresh;
 	txq->dma_desc_size_max = info->dma_desc_size_max;
 
@@ -1030,7 +1032,7 @@ sfc_efx_tx_qdesc_status(struct sfc_dp_txq *dp_txq, uint16_t offset)
 	if (unlikely(offset > txq->ptr_mask))
 		return -EINVAL;
 
-	if (unlikely(offset >= EFX_TXQ_LIMIT(txq->ptr_mask + 1)))
+	if (unlikely(offset >= txq->max_fill_level))
 		return RTE_ETH_TX_DESC_UNAVAIL;
 
 	/*
diff --git a/drivers/net/sfc/sfc_tx.h b/drivers/net/sfc/sfc_tx.h
index 0c1c708..2318f31 100644
--- a/drivers/net/sfc/sfc_tx.h
+++ b/drivers/net/sfc/sfc_tx.h
@@ -110,6 +110,7 @@ struct sfc_efx_txq {
 	unsigned int			added;
 	unsigned int			pending;
 	unsigned int			completed;
+	unsigned int			max_fill_level;
 	unsigned int			free_thresh;
 	uint16_t			hw_vlan_tci;
 	uint16_t			dma_desc_size_max;
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH v2 5/6] net/sfc: support more options for a number of Rx descriptors
  2018-01-09 20:24 ` [dpdk-dev] [PATCH v2 " Andrew Rybchenko
                     ` (3 preceding siblings ...)
  2018-01-09 20:24   ` [dpdk-dev] [PATCH v2 4/6] net/sfc: use Tx " Andrew Rybchenko
@ 2018-01-09 20:24   ` Andrew Rybchenko
  2018-01-09 20:24   ` [dpdk-dev] [PATCH v2 6/6] net/sfc: support more options for a number of Tx descriptors Andrew Rybchenko
  2018-01-10 19:40   ` [dpdk-dev] [PATCH v2 0/6] net/sfc: support more options for a number of Rx/Tx descs Ferruh Yigit
  6 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2018-01-09 20:24 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit

The number of Rx descriptors is not used as HW Rx ring size any more.
It simply defines maximum fill level.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc_dp_rx.h   |  8 ++++++++
 drivers/net/sfc/sfc_ef10_rx.c | 30 +++++++++++++++++++++++++++---
 drivers/net/sfc/sfc_ethdev.c  |  4 ++++
 drivers/net/sfc/sfc_rx.c      |  4 ++++
 4 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/drivers/net/sfc/sfc_dp_rx.h b/drivers/net/sfc/sfc_dp_rx.h
index 029ebaf..b817f34 100644
--- a/drivers/net/sfc/sfc_dp_rx.h
+++ b/drivers/net/sfc/sfc_dp_rx.h
@@ -103,6 +103,13 @@ struct sfc_dp_rx_qcreate_info {
 };
 
 /**
+ * Get Rx datapath specific device info.
+ *
+ * @param dev_info		Device info to be adjusted
+ */
+typedef void (sfc_dp_rx_get_dev_info_t)(struct rte_eth_dev_info *dev_info);
+
+/**
  * Get size of receive and event queue rings by the number of Rx
  * descriptors.
  *
@@ -186,6 +193,7 @@ struct sfc_dp_rx {
 #define SFC_DP_RX_FEAT_SCATTER			0x1
 #define SFC_DP_RX_FEAT_MULTI_PROCESS		0x2
 #define SFC_DP_RX_FEAT_TUNNELS			0x4
+	sfc_dp_rx_get_dev_info_t		*get_dev_info;
 	sfc_dp_rx_qsize_up_rings_t		*qsize_up_rings;
 	sfc_dp_rx_qcreate_t			*qcreate;
 	sfc_dp_rx_qdestroy_t			*qdestroy;
diff --git a/drivers/net/sfc/sfc_ef10_rx.c b/drivers/net/sfc/sfc_ef10_rx.c
index ad84629..b651bd7 100644
--- a/drivers/net/sfc/sfc_ef10_rx.c
+++ b/drivers/net/sfc/sfc_ef10_rx.c
@@ -638,6 +638,19 @@ sfc_ef10_rx_qdesc_status(__rte_unused struct sfc_dp_rxq *dp_rxq,
 }
 
 
+static sfc_dp_rx_get_dev_info_t sfc_ef10_rx_get_dev_info;
+static void
+sfc_ef10_rx_get_dev_info(struct rte_eth_dev_info *dev_info)
+{
+	/*
+	 * Number of descriptors just defines maximum number of pushed
+	 * descriptors (fill level).
+	 */
+	dev_info->rx_desc_lim.nb_min = SFC_RX_REFILL_BULK;
+	dev_info->rx_desc_lim.nb_align = SFC_RX_REFILL_BULK;
+}
+
+
 static sfc_dp_rx_qsize_up_rings_t sfc_ef10_rx_qsize_up_rings;
 static int
 sfc_ef10_rx_qsize_up_rings(uint16_t nb_rx_desc,
@@ -645,9 +658,19 @@ sfc_ef10_rx_qsize_up_rings(uint16_t nb_rx_desc,
 			   unsigned int *evq_entries,
 			   unsigned int *rxq_max_fill_level)
 {
-	*rxq_entries = nb_rx_desc;
-	*evq_entries = nb_rx_desc;
-	*rxq_max_fill_level = SFC_EF10_RXQ_LIMIT(*rxq_entries);
+	/*
+	 * rte_ethdev API guarantees that the number meets min, max and
+	 * alignment requirements.
+	 */
+	if (nb_rx_desc <= EFX_RXQ_MINNDESCS)
+		*rxq_entries = EFX_RXQ_MINNDESCS;
+	else
+		*rxq_entries = rte_align32pow2(nb_rx_desc);
+
+	*evq_entries = *rxq_entries;
+
+	*rxq_max_fill_level = RTE_MIN(nb_rx_desc,
+				      SFC_EF10_RXQ_LIMIT(*evq_entries));
 	return 0;
 }
 
@@ -809,6 +832,7 @@ struct sfc_dp_rx sfc_ef10_rx = {
 	},
 	.features		= SFC_DP_RX_FEAT_MULTI_PROCESS |
 				  SFC_DP_RX_FEAT_TUNNELS,
+	.get_dev_info		= sfc_ef10_rx_get_dev_info,
 	.qsize_up_rings		= sfc_ef10_rx_qsize_up_rings,
 	.qcreate		= sfc_ef10_rx_qcreate,
 	.qdestroy		= sfc_ef10_rx_qdestroy,
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 1b700b1..fec91c3 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -170,6 +170,7 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	if (sa->tso)
 		dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_TCP_TSO;
 
+	/* Initialize to hardware limits */
 	dev_info->rx_desc_lim.nb_max = EFX_RXQ_MAXNDESCS;
 	dev_info->rx_desc_lim.nb_min = EFX_RXQ_MINNDESCS;
 	/* The RXQ hardware requires that the descriptor count is a power
@@ -184,6 +185,9 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	 * of 2, but tx_desc_lim cannot properly describe that constraint
 	 */
 	dev_info->tx_desc_lim.nb_align = EFX_TXQ_MINNDESCS;
+
+	if (sa->dp_rx->get_dev_info != NULL)
+		sa->dp_rx->get_dev_info(dev_info);
 }
 
 static const uint32_t *
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 387f855..b355ea3 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -933,6 +933,10 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 				       &rxq_max_fill_level);
 	if (rc != 0)
 		goto fail_size_up_rings;
+	SFC_ASSERT(rxq_entries >= EFX_RXQ_MINNDESCS);
+	SFC_ASSERT(rxq_entries <= EFX_RXQ_MAXNDESCS);
+	SFC_ASSERT(rxq_entries >= nb_rx_desc);
+	SFC_ASSERT(rxq_max_fill_level <= nb_rx_desc);
 
 	rc = sfc_rx_qcheck_conf(sa, rxq_max_fill_level, rx_conf);
 	if (rc != 0)
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH v2 6/6] net/sfc: support more options for a number of Tx descriptors
  2018-01-09 20:24 ` [dpdk-dev] [PATCH v2 " Andrew Rybchenko
                     ` (4 preceding siblings ...)
  2018-01-09 20:24   ` [dpdk-dev] [PATCH v2 5/6] net/sfc: support more options for a number of Rx descriptors Andrew Rybchenko
@ 2018-01-09 20:24   ` Andrew Rybchenko
  2018-01-10 19:40   ` [dpdk-dev] [PATCH v2 0/6] net/sfc: support more options for a number of Rx/Tx descs Ferruh Yigit
  6 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2018-01-09 20:24 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit

The number of Tx descriptors is not used as HW Tx ring size any more.
It simply defines maximum fill level.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc_dp_tx.h   |  8 ++++++++
 drivers/net/sfc/sfc_ef10_tx.c | 29 ++++++++++++++++++++++++++---
 drivers/net/sfc/sfc_ethdev.c  |  3 +++
 drivers/net/sfc/sfc_tx.c      |  5 ++++-
 4 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/drivers/net/sfc/sfc_dp_tx.h b/drivers/net/sfc/sfc_dp_tx.h
index 4485b2f..a384a53 100644
--- a/drivers/net/sfc/sfc_dp_tx.h
+++ b/drivers/net/sfc/sfc_dp_tx.h
@@ -80,6 +80,13 @@ struct sfc_dp_tx_qcreate_info {
 };
 
 /**
+ * Get Tx datapath specific device info.
+ *
+ * @param dev_info		Device info to be adjusted
+ */
+typedef void (sfc_dp_tx_get_dev_info_t)(struct rte_eth_dev_info *dev_info);
+
+/**
  * Get size of transmit and event queue rings by the number of Tx
  * descriptors.
  *
@@ -162,6 +169,7 @@ struct sfc_dp_tx {
 #define SFC_DP_TX_FEAT_MULTI_PROCESS	0x8
 #define SFC_DP_TX_FEAT_MULTI_POOL	0x10
 #define SFC_DP_TX_FEAT_REFCNT		0x20
+	sfc_dp_tx_get_dev_info_t	*get_dev_info;
 	sfc_dp_tx_qsize_up_rings_t	*qsize_up_rings;
 	sfc_dp_tx_qcreate_t		*qcreate;
 	sfc_dp_tx_qdestroy_t		*qdestroy;
diff --git a/drivers/net/sfc/sfc_ef10_tx.c b/drivers/net/sfc/sfc_ef10_tx.c
index 99fe87e..02df39c 100644
--- a/drivers/net/sfc/sfc_ef10_tx.c
+++ b/drivers/net/sfc/sfc_ef10_tx.c
@@ -481,6 +481,17 @@ sfc_ef10_simple_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 	return pktp - &tx_pkts[0];
 }
 
+static sfc_dp_tx_get_dev_info_t sfc_ef10_get_dev_info;
+static void
+sfc_ef10_get_dev_info(struct rte_eth_dev_info *dev_info)
+{
+	/*
+	 * Number of descriptors just defines maximum number of pushed
+	 * descriptors (fill level).
+	 */
+	dev_info->tx_desc_lim.nb_min = 1;
+	dev_info->tx_desc_lim.nb_align = 1;
+}
 
 static sfc_dp_tx_qsize_up_rings_t sfc_ef10_tx_qsize_up_rings;
 static int
@@ -489,9 +500,19 @@ sfc_ef10_tx_qsize_up_rings(uint16_t nb_tx_desc,
 			   unsigned int *evq_entries,
 			   unsigned int *txq_max_fill_level)
 {
-	*txq_entries = nb_tx_desc;
-	*evq_entries = nb_tx_desc;
-	*txq_max_fill_level = SFC_EF10_TXQ_LIMIT(*txq_entries);
+	/*
+	 * rte_ethdev API guarantees that the number meets min, max and
+	 * alignment requirements.
+	 */
+	if (nb_tx_desc <= EFX_TXQ_MINNDESCS)
+		*txq_entries = EFX_TXQ_MINNDESCS;
+	else
+		*txq_entries = rte_align32pow2(nb_tx_desc);
+
+	*evq_entries = *txq_entries;
+
+	*txq_max_fill_level = RTE_MIN(nb_tx_desc,
+				      SFC_EF10_TXQ_LIMIT(*evq_entries));
 	return 0;
 }
 
@@ -637,6 +658,7 @@ struct sfc_dp_tx sfc_ef10_tx = {
 				  SFC_DP_TX_FEAT_MULTI_POOL |
 				  SFC_DP_TX_FEAT_REFCNT |
 				  SFC_DP_TX_FEAT_MULTI_PROCESS,
+	.get_dev_info		= sfc_ef10_get_dev_info,
 	.qsize_up_rings		= sfc_ef10_tx_qsize_up_rings,
 	.qcreate		= sfc_ef10_tx_qcreate,
 	.qdestroy		= sfc_ef10_tx_qdestroy,
@@ -654,6 +676,7 @@ struct sfc_dp_tx sfc_ef10_simple_tx = {
 		.type		= SFC_DP_TX,
 	},
 	.features		= SFC_DP_TX_FEAT_MULTI_PROCESS,
+	.get_dev_info		= sfc_ef10_get_dev_info,
 	.qsize_up_rings		= sfc_ef10_tx_qsize_up_rings,
 	.qcreate		= sfc_ef10_tx_qcreate,
 	.qdestroy		= sfc_ef10_tx_qdestroy,
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index fec91c3..e677ba5 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -178,6 +178,7 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	 */
 	dev_info->rx_desc_lim.nb_align = EFX_RXQ_MINNDESCS;
 
+	/* Initialize to hardware limits */
 	dev_info->tx_desc_lim.nb_max = sa->txq_max_entries;
 	dev_info->tx_desc_lim.nb_min = EFX_TXQ_MINNDESCS;
 	/*
@@ -188,6 +189,8 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	if (sa->dp_rx->get_dev_info != NULL)
 		sa->dp_rx->get_dev_info(dev_info);
+	if (sa->dp_tx->get_dev_info != NULL)
+		sa->dp_tx->get_dev_info(dev_info);
 }
 
 static const uint32_t *
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 8f932b0..bdf63b7 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -160,6 +160,10 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 				       &txq_max_fill_level);
 	if (rc != 0)
 		goto fail_size_up_rings;
+	SFC_ASSERT(txq_entries >= EFX_TXQ_MINNDESCS);
+	SFC_ASSERT(txq_entries <= sa->txq_max_entries);
+	SFC_ASSERT(txq_entries >= nb_tx_desc);
+	SFC_ASSERT(txq_max_fill_level <= nb_tx_desc);
 
 	rc = sfc_tx_qcheck_conf(sa, txq_max_fill_level, tx_conf);
 	if (rc != 0)
@@ -168,7 +172,6 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	SFC_ASSERT(sw_index < sa->txq_count);
 	txq_info = &sa->txq_info[sw_index];
 
-	SFC_ASSERT(txq_entries <= sa->txq_max_entries);
 	txq_info->entries = txq_entries;
 
 	rc = sfc_ev_qinit(sa, SFC_EVQ_TYPE_TX, sw_index,
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [dpdk-dev] [PATCH v2 0/6] net/sfc: support more options for a number of Rx/Tx descs
  2018-01-09 20:24 ` [dpdk-dev] [PATCH v2 " Andrew Rybchenko
                     ` (5 preceding siblings ...)
  2018-01-09 20:24   ` [dpdk-dev] [PATCH v2 6/6] net/sfc: support more options for a number of Tx descriptors Andrew Rybchenko
@ 2018-01-10 19:40   ` Ferruh Yigit
  6 siblings, 0 replies; 16+ messages in thread
From: Ferruh Yigit @ 2018-01-10 19:40 UTC (permalink / raw)
  To: Andrew Rybchenko, dev

On 1/9/2018 8:24 PM, Andrew Rybchenko wrote:
> The minimum size of Rx/Tx descriptor rings supported by Solarflare HW is 512.
> It adds inconvenience to run DPDK applications which typically use smaller
> default values. Also smaller numbers of used descriptors is better for
> performance.
> 
> The patch series adds possibility to use any number of Rx/Tx descriptors
> in the range, for example, from 1 to 2048 for Tx and from 8 to 4096 for Rx.
> Maximum value is defined by HW maximum.
> 
> v2:
>  - rebased
> 
> Andrew Rybchenko (6):
>   net/sfc: make refill threshold check Rx datapath specific
>   net/sfc: make Tx free threshold check datapath specific
>   net/sfc: use Rx queue max fill level calculated on init
>   net/sfc: use Tx queue max fill level calculated on init
>   net/sfc: support more options for a number of Rx descriptors
>   net/sfc: support more options for a number of Tx descriptors

Series applied to dpdk-next-net/master, thanks.

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2018-01-10 19:40 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-26  7:27 [dpdk-dev] [PATCH 0/6] net/sfc: support more options for a number of Rx/Tx descs Andrew Rybchenko
2017-12-26  7:27 ` [dpdk-dev] [PATCH 1/6] net/sfc: make refill threshold check Rx datapath specific Andrew Rybchenko
2017-12-26  7:27 ` [dpdk-dev] [PATCH 2/6] net/sfc: make Tx free threshold check " Andrew Rybchenko
2017-12-26  7:27 ` [dpdk-dev] [PATCH 3/6] net/sfc: use Rx queue max fill level calculated on init Andrew Rybchenko
2017-12-26  7:27 ` [dpdk-dev] [PATCH 4/6] net/sfc: use Tx " Andrew Rybchenko
2017-12-26  7:27 ` [dpdk-dev] [PATCH 5/6] net/sfc: support more options for a number of Rx descriptors Andrew Rybchenko
2017-12-26  7:27 ` [dpdk-dev] [PATCH 6/6] net/sfc: support more options for a number of Tx descriptors Andrew Rybchenko
2018-01-09 19:31 ` [dpdk-dev] [PATCH 0/6] net/sfc: support more options for a number of Rx/Tx descs Ferruh Yigit
2018-01-09 20:24 ` [dpdk-dev] [PATCH v2 " Andrew Rybchenko
2018-01-09 20:24   ` [dpdk-dev] [PATCH v2 1/6] net/sfc: make refill threshold check Rx datapath specific Andrew Rybchenko
2018-01-09 20:24   ` [dpdk-dev] [PATCH v2 2/6] net/sfc: make Tx free threshold check " Andrew Rybchenko
2018-01-09 20:24   ` [dpdk-dev] [PATCH v2 3/6] net/sfc: use Rx queue max fill level calculated on init Andrew Rybchenko
2018-01-09 20:24   ` [dpdk-dev] [PATCH v2 4/6] net/sfc: use Tx " Andrew Rybchenko
2018-01-09 20:24   ` [dpdk-dev] [PATCH v2 5/6] net/sfc: support more options for a number of Rx descriptors Andrew Rybchenko
2018-01-09 20:24   ` [dpdk-dev] [PATCH v2 6/6] net/sfc: support more options for a number of Tx descriptors Andrew Rybchenko
2018-01-10 19:40   ` [dpdk-dev] [PATCH v2 0/6] net/sfc: support more options for a number of Rx/Tx descs Ferruh Yigit

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).