dev.dpdk.org archive mirror
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 1/2] net/sfc: add Rx interrupts support for efx datapath
@ 2019-06-06 17:33 Andrew Rybchenko
  2019-06-06 17:33 ` [dpdk-dev] [PATCH 2/2] net/sfc: add Rx interrupts support for ef10 datapath Andrew Rybchenko
  2019-06-12  7:56 ` [dpdk-dev] [PATCH 1/2] net/sfc: add Rx interrupts support for efx datapath Ferruh Yigit
  0 siblings, 2 replies; 3+ messages in thread
From: Andrew Rybchenko @ 2019-06-06 17:33 UTC (permalink / raw)
  To: dev; +Cc: Georgiy Levashov

From: Georgiy Levashov <Georgiy.Levashov@oktetlabs.ru>

When Rx interrupts are disabled, we simply disable rearm when
the interrupt fires the next time. So, the next packet will
trigger interrupt (if it is not happened yet after previous Rx
burst processing).

Signed-off-by: Georgiy Levashov <Georgiy.Levashov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 doc/guides/nics/features/sfc_efx.ini   |  1 +
 doc/guides/nics/sfc_efx.rst            |  4 +-
 doc/guides/rel_notes/release_19_08.rst |  6 +++
 drivers/net/sfc/sfc.c                  |  3 +-
 drivers/net/sfc/sfc.h                  |  1 +
 drivers/net/sfc/sfc_dp_rx.h            | 10 +++++
 drivers/net/sfc/sfc_ethdev.c           | 28 ++++++++++++++
 drivers/net/sfc/sfc_ev.c               |  3 +-
 drivers/net/sfc/sfc_ev.h               |  1 +
 drivers/net/sfc/sfc_intr.c             | 37 ++++++++++++++++--
 drivers/net/sfc/sfc_rx.c               | 68 ++++++++++++++++++++++++++++++++--
 drivers/net/sfc/sfc_rx.h               |  1 +
 12 files changed, 153 insertions(+), 10 deletions(-)

diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index d1aa833..eca1427 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -7,6 +7,7 @@
 Speed capabilities   = Y
 Link status          = Y
 Link status event    = Y
+Rx interrupt         = Y
 Fast mbuf free       = Y
 Queue start/stop     = Y
 Runtime Rx queue setup = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 6d01d05..5f35bc5 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -82,6 +82,8 @@ SFC EFX PMD has support for:
 
 - Scattered Rx DMA for packet that are larger that a single Rx descriptor
 
+- Receive queue interrupts
+
 - Deferred receive and transmit queue start
 
 - Transmit VLAN insertion (if running firmware variant supports it)
@@ -96,8 +98,6 @@ Non-supported Features
 
 The features not yet supported include:
 
-- Receive queue interrupts
-
 - Priority-based flow control
 
 - Configurable RX CRC stripping (always stripped)
diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
index 8fcd4a7..72d74c5 100644
--- a/doc/guides/rel_notes/release_19_08.rst
+++ b/doc/guides/rel_notes/release_19_08.rst
@@ -66,6 +66,12 @@ New Features
   Added the new Shared Memory Packet Interface (``memif``) PMD.
   See the :doc:`../nics/memif` guide for more details on this new driver.
 
+* **Updated Solarflare network PMD.**
+
+  Updated the Solarflare ``sfc_efx`` driver with changes including:
+
+  * Added support for Rx interrupts.
+
 
 Removed Items
 -------------
diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index dea57b2..141c767 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -148,7 +148,8 @@
 		rc = EINVAL;
 	}
 
-	if (conf->intr_conf.rxq != 0) {
+	if (conf->intr_conf.rxq != 0 &&
+	    (sa->priv.dp_rx->features & SFC_DP_RX_FEAT_INTR) == 0) {
 		sfc_err(sa, "Receive queue interrupt not supported");
 		rc = EINVAL;
 	}
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index dde25c5..cc52228 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -108,6 +108,7 @@ struct sfc_intr {
 	efx_intr_type_t			type;
 	rte_intr_callback_fn		handler;
 	boolean_t			lsc_intr;
+	boolean_t			rxq_intr;
 };
 
 struct sfc_rxq;
diff --git a/drivers/net/sfc/sfc_dp_rx.h b/drivers/net/sfc/sfc_dp_rx.h
index a374311..73e5857 100644
--- a/drivers/net/sfc/sfc_dp_rx.h
+++ b/drivers/net/sfc/sfc_dp_rx.h
@@ -74,6 +74,8 @@ struct sfc_dp_rx_qcreate_info {
 	/** DMA-mapped Rx descriptors ring */
 	void			*rxq_hw_ring;
 
+	/** Event queue index in hardware */
+	unsigned int		evq_hw_index;
 	/** Associated event queue size */
 	unsigned int		evq_entries;
 	/** Hardware event ring */
@@ -193,6 +195,11 @@ typedef bool (sfc_dp_rx_qrx_ps_ev_t)(struct sfc_dp_rxq *dp_rxq,
 /** Check Rx descriptor status */
 typedef int (sfc_dp_rx_qdesc_status_t)(struct sfc_dp_rxq *dp_rxq,
 				       uint16_t offset);
+/** Enable Rx interrupts */
+typedef int (sfc_dp_rx_intr_enable_t)(struct sfc_dp_rxq *dp_rxq);
+
+/** Disable Rx interrupts */
+typedef int (sfc_dp_rx_intr_disable_t)(struct sfc_dp_rxq *dp_rxq);
 
 /** Receive datapath definition */
 struct sfc_dp_rx {
@@ -202,6 +209,7 @@ struct sfc_dp_rx {
 #define SFC_DP_RX_FEAT_MULTI_PROCESS		0x1
 #define SFC_DP_RX_FEAT_FLOW_FLAG		0x2
 #define SFC_DP_RX_FEAT_FLOW_MARK		0x4
+#define SFC_DP_RX_FEAT_INTR			0x8
 	/**
 	 * Rx offload capabilities supported by the datapath on device
 	 * level only if HW/FW supports it.
@@ -225,6 +233,8 @@ struct sfc_dp_rx {
 	sfc_dp_rx_supported_ptypes_get_t	*supported_ptypes_get;
 	sfc_dp_rx_qdesc_npending_t		*qdesc_npending;
 	sfc_dp_rx_qdesc_status_t		*qdesc_status;
+	sfc_dp_rx_intr_enable_t			*intr_enable;
+	sfc_dp_rx_intr_disable_t		*intr_disable;
 	eth_rx_burst_t				pkt_burst;
 };
 
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 661432e..be185d5 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -1713,6 +1713,32 @@ enum sfc_udp_tunnel_op_e {
 	return sap->dp_rx->pool_ops_supported(pool);
 }
 
+static int
+sfc_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+	const struct sfc_adapter_priv *sap = sfc_adapter_priv_by_eth_dev(dev);
+	struct sfc_adapter_shared *sas = sfc_adapter_shared_by_eth_dev(dev);
+	struct sfc_rxq_info *rxq_info;
+
+	SFC_ASSERT(queue_id < sas->rxq_count);
+	rxq_info = &sas->rxq_info[queue_id];
+
+	return sap->dp_rx->intr_enable(rxq_info->dp);
+}
+
+static int
+sfc_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+	const struct sfc_adapter_priv *sap = sfc_adapter_priv_by_eth_dev(dev);
+	struct sfc_adapter_shared *sas = sfc_adapter_shared_by_eth_dev(dev);
+	struct sfc_rxq_info *rxq_info;
+
+	SFC_ASSERT(queue_id < sas->rxq_count);
+	rxq_info = &sas->rxq_info[queue_id];
+
+	return sap->dp_rx->intr_disable(rxq_info->dp);
+}
+
 static const struct eth_dev_ops sfc_eth_dev_ops = {
 	.dev_configure			= sfc_dev_configure,
 	.dev_start			= sfc_dev_start,
@@ -1743,6 +1769,8 @@ enum sfc_udp_tunnel_op_e {
 	.rx_descriptor_done		= sfc_rx_descriptor_done,
 	.rx_descriptor_status		= sfc_rx_descriptor_status,
 	.tx_descriptor_status		= sfc_tx_descriptor_status,
+	.rx_queue_intr_enable		= sfc_rx_queue_intr_enable,
+	.rx_queue_intr_disable		= sfc_rx_queue_intr_disable,
 	.tx_queue_setup			= sfc_tx_queue_setup,
 	.tx_queue_release		= sfc_tx_queue_release,
 	.flow_ctrl_get			= sfc_flow_ctrl_get,
diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c
index 5992833..0f216da 100644
--- a/drivers/net/sfc/sfc_ev.c
+++ b/drivers/net/sfc/sfc_ev.c
@@ -602,7 +602,8 @@
 	(void)memset((void *)esmp->esm_base, 0xff,
 		     efx_evq_size(sa->nic, evq->entries));
 
-	if (sa->intr.lsc_intr && hw_index == sa->mgmt_evq_index)
+	if ((sa->intr.lsc_intr && hw_index == sa->mgmt_evq_index) ||
+	    (sa->intr.rxq_intr && evq->dp_rxq != NULL))
 		evq_flags |= EFX_EVQ_FLAGS_NOTIFY_INTERRUPT;
 	else
 		evq_flags |= EFX_EVQ_FLAGS_NOTIFY_DISABLED;
diff --git a/drivers/net/sfc/sfc_ev.h b/drivers/net/sfc/sfc_ev.h
index 5d070b1..2c401c7 100644
--- a/drivers/net/sfc/sfc_ev.h
+++ b/drivers/net/sfc/sfc_ev.h
@@ -46,6 +46,7 @@ struct sfc_evq {
 	efx_evq_t			*common;
 	const efx_ev_callbacks_t	*callbacks;
 	unsigned int			read_ptr;
+	unsigned int			read_ptr_primed;
 	boolean_t			exception;
 	efsys_mem_t			mem;
 	struct sfc_dp_rxq		*dp_rxq;
diff --git a/drivers/net/sfc/sfc_intr.c b/drivers/net/sfc/sfc_intr.c
index 0fbcd61..1f4969b 100644
--- a/drivers/net/sfc/sfc_intr.c
+++ b/drivers/net/sfc/sfc_intr.c
@@ -162,6 +162,27 @@
 	intr_handle = &pci_dev->intr_handle;
 
 	if (intr->handler != NULL) {
+		if (intr->rxq_intr && rte_intr_cap_multiple(intr_handle)) {
+			uint32_t intr_vector;
+
+			intr_vector = sa->eth_dev->data->nb_rx_queues;
+			rc = rte_intr_efd_enable(intr_handle, intr_vector);
+			if (rc != 0)
+				goto fail_rte_intr_efd_enable;
+		}
+		if (rte_intr_dp_is_en(intr_handle)) {
+			intr_handle->intr_vec =
+				rte_calloc("intr_vec",
+				sa->eth_dev->data->nb_rx_queues, sizeof(int),
+				0);
+			if (intr_handle->intr_vec == NULL) {
+				sfc_err(sa,
+					"Failed to allocate %d rx_queues intr_vec",
+					sa->eth_dev->data->nb_rx_queues);
+				goto fail_intr_vector_alloc;
+			}
+		}
+
 		sfc_log_init(sa, "rte_intr_callback_register");
 		rc = rte_intr_callback_register(intr_handle, intr->handler,
 						(void *)sa);
@@ -202,6 +223,12 @@
 	rte_intr_callback_unregister(intr_handle, intr->handler, (void *)sa);
 
 fail_rte_intr_cb_reg:
+	rte_free(intr_handle->intr_vec);
+
+fail_intr_vector_alloc:
+	rte_intr_efd_disable(intr_handle);
+
+fail_rte_intr_efd_enable:
 	efx_intr_fini(sa->nic);
 
 fail_intr_init:
@@ -224,6 +251,10 @@
 		efx_intr_disable(sa->nic);
 
 		intr_handle = &pci_dev->intr_handle;
+
+		rte_free(intr_handle->intr_vec);
+		rte_intr_efd_disable(intr_handle);
+
 		if (rte_intr_disable(intr_handle) != 0)
 			sfc_err(sa, "cannot disable interrupts");
 
@@ -250,10 +281,10 @@
 
 	intr->handler = NULL;
 	intr->lsc_intr = (sa->eth_dev->data->dev_conf.intr_conf.lsc != 0);
-	if (!intr->lsc_intr) {
-		sfc_notice(sa, "LSC tracking using interrupts is disabled");
+	intr->rxq_intr = (sa->eth_dev->data->dev_conf.intr_conf.rxq != 0);
+
+	if (!intr->lsc_intr && !intr->rxq_intr)
 		goto done;
-	}
 
 	switch (intr->type) {
 	case EFX_INTR_MESSAGE:
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 70e7614..23dff09 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -52,6 +52,19 @@
 	rxq_info->state &= ~SFC_RXQ_FLUSHING;
 }
 
+static int
+sfc_efx_rx_qprime(struct sfc_efx_rxq *rxq)
+{
+	int rc = 0;
+
+	if (rxq->evq->read_ptr_primed != rxq->evq->read_ptr) {
+		rc = efx_ev_qprime(rxq->evq->common, rxq->evq->read_ptr);
+		if (rc == 0)
+			rxq->evq->read_ptr_primed = rxq->evq->read_ptr;
+	}
+	return rc;
+}
+
 static void
 sfc_efx_rx_qrefill(struct sfc_efx_rxq *rxq)
 {
@@ -306,6 +319,9 @@
 
 	sfc_efx_rx_qrefill(rxq);
 
+	if (rxq->flags & SFC_EFX_RXQ_FLAG_INTR_EN)
+		sfc_efx_rx_qprime(rxq);
+
 	return done_pkts;
 }
 
@@ -493,6 +509,12 @@ struct sfc_rxq *
 	rte_free(rxq);
 }
 
+
+/* Use qstop and qstart functions in the case of qstart failure */
+static sfc_dp_rx_qstop_t sfc_efx_rx_qstop;
+static sfc_dp_rx_qpurge_t sfc_efx_rx_qpurge;
+
+
 static sfc_dp_rx_qstart_t sfc_efx_rx_qstart;
 static int
 sfc_efx_rx_qstart(struct sfc_dp_rxq *dp_rxq,
@@ -501,6 +523,7 @@ struct sfc_rxq *
 	/* libefx-based datapath is specific to libefx-based PMD */
 	struct sfc_efx_rxq *rxq = sfc_efx_rxq_by_dp_rxq(dp_rxq);
 	struct sfc_rxq *crxq = sfc_rxq_by_dp_rxq(dp_rxq);
+	int rc;
 
 	rxq->common = crxq->common;
 
@@ -510,10 +533,20 @@ struct sfc_rxq *
 
 	rxq->flags |= (SFC_EFX_RXQ_FLAG_STARTED | SFC_EFX_RXQ_FLAG_RUNNING);
 
+	if (rxq->flags & SFC_EFX_RXQ_FLAG_INTR_EN) {
+		rc = sfc_efx_rx_qprime(rxq);
+		if (rc != 0)
+			goto fail_rx_qprime;
+	}
+
 	return 0;
+
+fail_rx_qprime:
+	sfc_efx_rx_qstop(dp_rxq, NULL);
+	sfc_efx_rx_qpurge(dp_rxq);
+	return rc;
 }
 
-static sfc_dp_rx_qstop_t sfc_efx_rx_qstop;
 static void
 sfc_efx_rx_qstop(struct sfc_dp_rxq *dp_rxq,
 		 __rte_unused unsigned int *evq_read_ptr)
@@ -528,7 +561,6 @@ struct sfc_rxq *
 	 */
 }
 
-static sfc_dp_rx_qpurge_t sfc_efx_rx_qpurge;
 static void
 sfc_efx_rx_qpurge(struct sfc_dp_rxq *dp_rxq)
 {
@@ -551,13 +583,40 @@ struct sfc_rxq *
 	rxq->flags &= ~SFC_EFX_RXQ_FLAG_STARTED;
 }
 
+static sfc_dp_rx_intr_enable_t sfc_efx_rx_intr_enable;
+static int
+sfc_efx_rx_intr_enable(struct sfc_dp_rxq *dp_rxq)
+{
+	struct sfc_efx_rxq *rxq = sfc_efx_rxq_by_dp_rxq(dp_rxq);
+	int rc = 0;
+
+	rxq->flags |= SFC_EFX_RXQ_FLAG_INTR_EN;
+	if (rxq->flags & SFC_EFX_RXQ_FLAG_STARTED) {
+		rc = sfc_efx_rx_qprime(rxq);
+		if (rc != 0)
+			rxq->flags &= ~SFC_EFX_RXQ_FLAG_INTR_EN;
+	}
+	return rc;
+}
+
+static sfc_dp_rx_intr_disable_t sfc_efx_rx_intr_disable;
+static int
+sfc_efx_rx_intr_disable(struct sfc_dp_rxq *dp_rxq)
+{
+	struct sfc_efx_rxq *rxq = sfc_efx_rxq_by_dp_rxq(dp_rxq);
+
+	/* Cannot disarm, just disable rearm */
+	rxq->flags &= ~SFC_EFX_RXQ_FLAG_INTR_EN;
+	return 0;
+}
+
 struct sfc_dp_rx sfc_efx_rx = {
 	.dp = {
 		.name		= SFC_KVARG_DATAPATH_EFX,
 		.type		= SFC_DP_RX,
 		.hw_fw_caps	= 0,
 	},
-	.features		= 0,
+	.features		= SFC_DP_RX_FEAT_INTR,
 	.dev_offload_capa	= DEV_RX_OFFLOAD_CHECKSUM,
 	.queue_offload_capa	= DEV_RX_OFFLOAD_SCATTER,
 	.qsize_up_rings		= sfc_efx_rx_qsize_up_rings,
@@ -569,6 +628,8 @@ struct sfc_dp_rx sfc_efx_rx = {
 	.supported_ptypes_get	= sfc_efx_supported_ptypes_get,
 	.qdesc_npending		= sfc_efx_rx_qdesc_npending,
 	.qdesc_status		= sfc_efx_rx_qdesc_status,
+	.intr_enable		= sfc_efx_rx_intr_enable,
+	.intr_disable		= sfc_efx_rx_intr_disable,
 	.pkt_burst		= sfc_efx_recv_pkts,
 };
 
@@ -1094,6 +1155,7 @@ struct sfc_dp_rx sfc_efx_rx = {
 
 	info.rxq_entries = rxq_info->entries;
 	info.rxq_hw_ring = rxq->mem.esm_base;
+	info.evq_hw_index = sfc_evq_index_by_rxq_sw_index(sa, sw_index);
 	info.evq_entries = evq_entries;
 	info.evq_hw_ring = evq->mem.esm_base;
 	info.hw_index = rxq->hw_index;
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index aca0925..42b16e2 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -73,6 +73,7 @@ struct sfc_efx_rxq {
 #define SFC_EFX_RXQ_FLAG_STARTED	0x1
 #define SFC_EFX_RXQ_FLAG_RUNNING	0x2
 #define SFC_EFX_RXQ_FLAG_RSS_HASH	0x4
+#define SFC_EFX_RXQ_FLAG_INTR_EN	0x8
 	unsigned int			ptr_mask;
 	unsigned int			pending;
 	unsigned int			completed;
-- 
1.8.3.1


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

end of thread, other threads:[~2019-06-12  7:56 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-06 17:33 [dpdk-dev] [PATCH 1/2] net/sfc: add Rx interrupts support for efx datapath Andrew Rybchenko
2019-06-06 17:33 ` [dpdk-dev] [PATCH 2/2] net/sfc: add Rx interrupts support for ef10 datapath Andrew Rybchenko
2019-06-12  7:56 ` [dpdk-dev] [PATCH 1/2] net/sfc: add Rx interrupts support for efx datapath 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).