All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/13] net/sfc: fix device reconfigure
@ 2017-03-31 10:22 Andrew Rybchenko
  2017-03-31 10:22 ` [PATCH 01/13] net/sfc: clarify interrupts support function names Andrew Rybchenko
                   ` (13 more replies)
  0 siblings, 14 replies; 15+ messages in thread
From: Andrew Rybchenko @ 2017-03-31 10:22 UTC (permalink / raw)
  To: dev

When I implemented initial version of the driver I had incorrect
understanding of the required state transition to reconfigure
device. It was assumed that close is required before reconfigure.
Looking at description in rte_ethdev.h, rte_eth_dev_close()
description and rte_eth_dev_configure() implementation I see that
I was wrong.

If reconfigure attempt is done without the patch series, testpmd
crashes on segmentation fault. The patch series fixes it. So,
technically it is a bug fix, but unfortunately pretty big.

The patch series should be applied after [1] (patch [2]).

Testing the patch requires [3] (patch [4]). Intel compilation of
the patch fails since it is applied to dpdk.git tree instead of
dpdk-next-net.git.

[1] http://dpdk.org/ml/archives/dev/2017-March/062155.html
[2] http://dpdk.org/dev/patchwork/patch/22758/
[3] http://dpdk.org/ml/archives/dev/2017-March/062157.html
[4] http://dpdk.org/dev/patchwork/patch/22756/

Andrew Rybchenko (13):
  net/sfc: clarify interrupts support function names
  net/sfc: bind EvQ DMA space to EvQ type and type-local index
  net/sfc: remove unused max entries from EvQ info
  net/sfc: move EvQ entries to the EvQ control structure
  net/sfc: remove flags from EvQ info
  net/sfc: remove EvQ info array to simplify reconfigure
  net/sfc: move event support init to attach stage
  net/sfc: initialize port data on attach
  net/sfc: clarify Rx subsystem configure/close function names
  net/sfc: clarify Tx subsystem configure/close function names
  net/sfc: support changing the number of receive queues
  net/sfc: support changing the number of transmit queues
  net/sfc: fix device reconfigure

 drivers/net/sfc/sfc.c        |  67 ++++++++-------
 drivers/net/sfc/sfc.h        |  41 +++++-----
 drivers/net/sfc/sfc_ethdev.c |   2 -
 drivers/net/sfc/sfc_ev.c     | 191 +++++++++++++++----------------------------
 drivers/net/sfc/sfc_ev.h     |  69 +++++-----------
 drivers/net/sfc/sfc_intr.c   |   6 +-
 drivers/net/sfc/sfc_port.c   |  32 ++++++--
 drivers/net/sfc/sfc_rx.c     | 113 ++++++++++++++++---------
 drivers/net/sfc/sfc_rx.h     |   4 +-
 drivers/net/sfc/sfc_tx.c     | 103 +++++++++++++++--------
 drivers/net/sfc/sfc_tx.h     |   4 +-
 11 files changed, 322 insertions(+), 310 deletions(-)

-- 
2.9.3

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

* [PATCH 01/13] net/sfc: clarify interrupts support function names
  2017-03-31 10:22 [PATCH 00/13] net/sfc: fix device reconfigure Andrew Rybchenko
@ 2017-03-31 10:22 ` Andrew Rybchenko
  2017-03-31 10:22 ` [PATCH 02/13] net/sfc: bind EvQ DMA space to EvQ type and type-local index Andrew Rybchenko
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Andrew Rybchenko @ 2017-03-31 10:22 UTC (permalink / raw)
  To: dev

Make it clear that corresponding functions should be called on device
configure and close operations. No functional change.

Fixes: 06bc197796e2 ("net/sfc: interrupts support sufficient for event queue init")

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/sfc.c      | 10 +++++-----
 drivers/net/sfc/sfc.h      |  4 ++--
 drivers/net/sfc/sfc_intr.c |  4 ++--
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index 181d87a..ad3dab1 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -405,9 +405,9 @@ sfc_configure(struct sfc_adapter *sa)
 	if (rc != 0)
 		goto fail_check_conf;
 
-	rc = sfc_intr_init(sa);
+	rc = sfc_intr_configure(sa);
 	if (rc != 0)
-		goto fail_intr_init;
+		goto fail_intr_configure;
 
 	rc = sfc_ev_init(sa);
 	if (rc != 0)
@@ -439,9 +439,9 @@ sfc_configure(struct sfc_adapter *sa)
 	sfc_ev_fini(sa);
 
 fail_ev_init:
-	sfc_intr_fini(sa);
+	sfc_intr_close(sa);
 
-fail_intr_init:
+fail_intr_configure:
 fail_check_conf:
 	sa->state = SFC_ADAPTER_INITIALIZED;
 	sfc_log_init(sa, "failed %d", rc);
@@ -462,7 +462,7 @@ sfc_close(struct sfc_adapter *sa)
 	sfc_rx_fini(sa);
 	sfc_port_fini(sa);
 	sfc_ev_fini(sa);
-	sfc_intr_fini(sa);
+	sfc_intr_close(sa);
 
 	sa->state = SFC_ADAPTER_INITIALIZED;
 	sfc_log_init(sa, "done");
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index a7a9868..e77639e 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -298,8 +298,8 @@ void sfc_close(struct sfc_adapter *sa);
 
 int sfc_intr_attach(struct sfc_adapter *sa);
 void sfc_intr_detach(struct sfc_adapter *sa);
-int sfc_intr_init(struct sfc_adapter *sa);
-void sfc_intr_fini(struct sfc_adapter *sa);
+int sfc_intr_configure(struct sfc_adapter *sa);
+void sfc_intr_close(struct sfc_adapter *sa);
 int sfc_intr_start(struct sfc_adapter *sa);
 void sfc_intr_stop(struct sfc_adapter *sa);
 
diff --git a/drivers/net/sfc/sfc_intr.c b/drivers/net/sfc/sfc_intr.c
index c57cdae..0d199b4 100644
--- a/drivers/net/sfc/sfc_intr.c
+++ b/drivers/net/sfc/sfc_intr.c
@@ -259,7 +259,7 @@ sfc_intr_stop(struct sfc_adapter *sa)
 }
 
 int
-sfc_intr_init(struct sfc_adapter *sa)
+sfc_intr_configure(struct sfc_adapter *sa)
 {
 	struct sfc_intr *intr = &sa->intr;
 
@@ -293,7 +293,7 @@ sfc_intr_init(struct sfc_adapter *sa)
 }
 
 void
-sfc_intr_fini(struct sfc_adapter *sa)
+sfc_intr_close(struct sfc_adapter *sa)
 {
 	sfc_log_init(sa, "entry");
 
-- 
2.9.3

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

* [PATCH 02/13] net/sfc: bind EvQ DMA space to EvQ type and type-local index
  2017-03-31 10:22 [PATCH 00/13] net/sfc: fix device reconfigure Andrew Rybchenko
  2017-03-31 10:22 ` [PATCH 01/13] net/sfc: clarify interrupts support function names Andrew Rybchenko
@ 2017-03-31 10:22 ` Andrew Rybchenko
  2017-03-31 10:22 ` [PATCH 03/13] net/sfc: remove unused max entries from EvQ info Andrew Rybchenko
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Andrew Rybchenko @ 2017-03-31 10:22 UTC (permalink / raw)
  To: dev

The index of an event queue index is computed from the index of the
corresponding transmit or receive queue, and depends on the total
number of receive queues. As a consequence, the index of an event
queue bound to a transmit queue changes if the total number of
receive queues is changed.

Fixes: 58294ee65afb ("net/sfc: support event queue")

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc_ev.c | 27 +++++++++++++++++++++++----
 drivers/net/sfc/sfc_ev.h | 10 ++++++++++
 drivers/net/sfc/sfc_rx.c |  3 ++-
 drivers/net/sfc/sfc_tx.c |  3 ++-
 4 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c
index 800b08e..46de7a5 100644
--- a/drivers/net/sfc/sfc_ev.c
+++ b/drivers/net/sfc/sfc_ev.c
@@ -55,6 +55,21 @@
 /* Management event queue polling period in microseconds */
 #define SFC_MGMT_EV_QPOLL_PERIOD_US	(US_PER_S)
 
+static const char *
+sfc_evq_type2str(enum sfc_evq_type type)
+{
+	switch (type) {
+	case SFC_EVQ_TYPE_MGMT:
+		return "mgmt-evq";
+	case SFC_EVQ_TYPE_RX:
+		return "rx-evq";
+	case SFC_EVQ_TYPE_TX:
+		return "tx-evq";
+	default:
+		SFC_ASSERT(B_FALSE);
+		return NULL;
+	}
+}
 
 static boolean_t
 sfc_ev_initialized(void *arg)
@@ -786,13 +801,15 @@ sfc_ev_stop(struct sfc_adapter *sa)
 
 int
 sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index,
+	     enum sfc_evq_type type, unsigned int type_index,
 	     unsigned int entries, int socket_id)
 {
 	struct sfc_evq_info *evq_info;
 	struct sfc_evq *evq;
 	int rc;
 
-	sfc_log_init(sa, "sw_index=%u", sw_index);
+	sfc_log_init(sa, "sw_index=%u type=%s type_index=%u",
+		     sw_index, sfc_evq_type2str(type), type_index);
 
 	evq_info = &sa->evq_info[sw_index];
 
@@ -808,9 +825,11 @@ sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 
 	evq->sa = sa;
 	evq->evq_index = sw_index;
+	evq->type = type;
 
 	/* Allocate DMA space */
-	rc = sfc_dma_alloc(sa, "evq", sw_index, EFX_EVQ_SIZE(evq_info->entries),
+	rc = sfc_dma_alloc(sa, sfc_evq_type2str(type), type_index,
+			   EFX_EVQ_SIZE(evq_info->entries),
 			   socket_id, &evq->mem);
 	if (rc != 0)
 		goto fail_dma_alloc;
@@ -930,8 +949,8 @@ sfc_ev_init(struct sfc_adapter *sa)
 			goto fail_ev_qinit_info;
 	}
 
-	rc = sfc_ev_qinit(sa, sa->mgmt_evq_index, SFC_MGMT_EVQ_ENTRIES,
-			  sa->socket_id);
+	rc = sfc_ev_qinit(sa, sa->mgmt_evq_index, SFC_EVQ_TYPE_MGMT, 0,
+			  SFC_MGMT_EVQ_ENTRIES, sa->socket_id);
 	if (rc != 0)
 		goto fail_mgmt_evq_init;
 
diff --git a/drivers/net/sfc/sfc_ev.h b/drivers/net/sfc/sfc_ev.h
index e8d3090..f5e6415 100644
--- a/drivers/net/sfc/sfc_ev.h
+++ b/drivers/net/sfc/sfc_ev.h
@@ -58,6 +58,14 @@ enum sfc_evq_state {
 	SFC_EVQ_NSTATES
 };
 
+enum sfc_evq_type {
+	SFC_EVQ_TYPE_MGMT = 0,
+	SFC_EVQ_TYPE_RX,
+	SFC_EVQ_TYPE_TX,
+
+	SFC_EVQ_NTYPES
+};
+
 struct sfc_evq {
 	/* Used on datapath */
 	efx_evq_t			*common;
@@ -72,6 +80,7 @@ struct sfc_evq {
 	struct sfc_adapter		*sa;
 	unsigned int			evq_index;
 	enum sfc_evq_state		init_state;
+	enum sfc_evq_type		type;
 };
 
 struct sfc_evq_info {
@@ -138,6 +147,7 @@ int sfc_ev_start(struct sfc_adapter *sa);
 void sfc_ev_stop(struct sfc_adapter *sa);
 
 int sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index,
+		 enum sfc_evq_type type, unsigned int type_index,
 		 unsigned int entries, int socket_id);
 void sfc_ev_qfini(struct sfc_adapter *sa, unsigned int sw_index);
 int sfc_ev_qstart(struct sfc_adapter *sa, unsigned int sw_index);
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 403e991..8c929f8 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -902,7 +902,8 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 
 	evq_index = sfc_evq_index_by_rxq_sw_index(sa, sw_index);
 
-	rc = sfc_ev_qinit(sa, evq_index, rxq_info->entries, socket_id);
+	rc = sfc_ev_qinit(sa, evq_index, SFC_EVQ_TYPE_RX, sw_index,
+			  rxq_info->entries, socket_id);
 	if (rc != 0)
 		goto fail_ev_qinit;
 
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 3c4717f..2c45e1a 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -150,7 +150,8 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	SFC_ASSERT(nb_tx_desc <= sa->txq_max_entries);
 	txq_info->entries = nb_tx_desc;
 
-	rc = sfc_ev_qinit(sa, evq_index, txq_info->entries, socket_id);
+	rc = sfc_ev_qinit(sa, evq_index, SFC_EVQ_TYPE_TX, sw_index,
+			  txq_info->entries, socket_id);
 	if (rc != 0)
 		goto fail_ev_qinit;
 
-- 
2.9.3

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

* [PATCH 03/13] net/sfc: remove unused max entries from EvQ info
  2017-03-31 10:22 [PATCH 00/13] net/sfc: fix device reconfigure Andrew Rybchenko
  2017-03-31 10:22 ` [PATCH 01/13] net/sfc: clarify interrupts support function names Andrew Rybchenko
  2017-03-31 10:22 ` [PATCH 02/13] net/sfc: bind EvQ DMA space to EvQ type and type-local index Andrew Rybchenko
@ 2017-03-31 10:22 ` Andrew Rybchenko
  2017-03-31 10:22 ` [PATCH 04/13] net/sfc: move EvQ entries to the EvQ control structure Andrew Rybchenko
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Andrew Rybchenko @ 2017-03-31 10:22 UTC (permalink / raw)
  To: dev

Fixes: 58294ee65afb ("net/sfc: support event queue")

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc_ev.c |  6 ------
 drivers/net/sfc/sfc_ev.h | 21 +--------------------
 2 files changed, 1 insertion(+), 26 deletions(-)

diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c
index 46de7a5..7c8ec32 100644
--- a/drivers/net/sfc/sfc_ev.c
+++ b/drivers/net/sfc/sfc_ev.c
@@ -814,7 +814,6 @@ sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	evq_info = &sa->evq_info[sw_index];
 
 	SFC_ASSERT(rte_is_power_of_2(entries));
-	SFC_ASSERT(entries <= evq_info->max_entries);
 	evq_info->entries = entries;
 
 	rc = ENOMEM;
@@ -871,14 +870,9 @@ static int
 sfc_ev_qinit_info(struct sfc_adapter *sa, unsigned int sw_index)
 {
 	struct sfc_evq_info *evq_info = &sa->evq_info[sw_index];
-	unsigned int max_entries;
 
 	sfc_log_init(sa, "sw_index=%u", sw_index);
 
-	max_entries = sfc_evq_max_entries(sa, sw_index);
-	SFC_ASSERT(rte_is_power_of_2(max_entries));
-
-	evq_info->max_entries = max_entries;
 	evq_info->flags = sa->evq_flags |
 		((sa->intr.lsc_intr && sw_index == sa->mgmt_evq_index) ?
 			EFX_EVQ_FLAGS_NOTIFY_INTERRUPT :
diff --git a/drivers/net/sfc/sfc_ev.h b/drivers/net/sfc/sfc_ev.h
index f5e6415..8f43d73 100644
--- a/drivers/net/sfc/sfc_ev.h
+++ b/drivers/net/sfc/sfc_ev.h
@@ -84,11 +84,7 @@ struct sfc_evq {
 };
 
 struct sfc_evq_info {
-	/* Maximum number of EVQ entries taken into account when buffer
-	 * table space is allocated.
-	 */
-	unsigned int		max_entries;
-	/* Real number of EVQ entries, less or equal to max_entries */
+	/* Number of EVQ entries */
 	unsigned int		entries;
 	/* Event queue creation flags */
 	uint32_t		flags;
@@ -114,21 +110,6 @@ sfc_ev_qcount(struct sfc_adapter *sa)
 }
 
 static inline unsigned int
-sfc_evq_max_entries(struct sfc_adapter *sa, unsigned int sw_index)
-{
-	unsigned int max_entries;
-
-	if (sw_index == sa->mgmt_evq_index)
-		max_entries = SFC_MGMT_EVQ_ENTRIES;
-	else if (sw_index <= sa->eth_dev->data->nb_rx_queues)
-		max_entries = EFX_RXQ_MAXNDESCS;
-	else
-		max_entries = efx_nic_cfg_get(sa->nic)->enc_txq_max_ndescs;
-
-	return max_entries;
-}
-
-static inline unsigned int
 sfc_evq_index_by_rxq_sw_index(__rte_unused struct sfc_adapter *sa,
 			      unsigned int rxq_sw_index)
 {
-- 
2.9.3

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

* [PATCH 04/13] net/sfc: move EvQ entries to the EvQ control structure
  2017-03-31 10:22 [PATCH 00/13] net/sfc: fix device reconfigure Andrew Rybchenko
                   ` (2 preceding siblings ...)
  2017-03-31 10:22 ` [PATCH 03/13] net/sfc: remove unused max entries from EvQ info Andrew Rybchenko
@ 2017-03-31 10:22 ` Andrew Rybchenko
  2017-03-31 10:22 ` [PATCH 05/13] net/sfc: remove flags from EvQ info Andrew Rybchenko
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Andrew Rybchenko @ 2017-03-31 10:22 UTC (permalink / raw)
  To: dev

EvQ info array is a problem on device reconfigure when number of
Rx and Tx queues may change. It is a step to get rid of it.

Fixes: 58294ee65afb ("net/sfc: support event queue")

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc_ev.c | 10 ++++------
 drivers/net/sfc/sfc_ev.h |  3 +--
 2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c
index 7c8ec32..60288ce 100644
--- a/drivers/net/sfc/sfc_ev.c
+++ b/drivers/net/sfc/sfc_ev.c
@@ -599,11 +599,10 @@ sfc_ev_qstart(struct sfc_adapter *sa, unsigned int sw_index)
 	esmp = &evq->mem;
 
 	/* Clear all events */
-	(void)memset((void *)esmp->esm_base, 0xff,
-		     EFX_EVQ_SIZE(evq_info->entries));
+	(void)memset((void *)esmp->esm_base, 0xff, EFX_EVQ_SIZE(evq->entries));
 
 	/* Create the common code event queue */
-	rc = efx_ev_qcreate(sa->nic, sw_index, esmp, evq_info->entries,
+	rc = efx_ev_qcreate(sa->nic, sw_index, esmp, evq->entries,
 			    0 /* unused on EF10 */, 0, evq_info->flags,
 			    &evq->common);
 	if (rc != 0)
@@ -814,7 +813,6 @@ sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	evq_info = &sa->evq_info[sw_index];
 
 	SFC_ASSERT(rte_is_power_of_2(entries));
-	evq_info->entries = entries;
 
 	rc = ENOMEM;
 	evq = rte_zmalloc_socket("sfc-evq", sizeof(*evq), RTE_CACHE_LINE_SIZE,
@@ -825,11 +823,11 @@ sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	evq->sa = sa;
 	evq->evq_index = sw_index;
 	evq->type = type;
+	evq->entries = entries;
 
 	/* Allocate DMA space */
 	rc = sfc_dma_alloc(sa, sfc_evq_type2str(type), type_index,
-			   EFX_EVQ_SIZE(evq_info->entries),
-			   socket_id, &evq->mem);
+			   EFX_EVQ_SIZE(evq->entries), socket_id, &evq->mem);
 	if (rc != 0)
 		goto fail_dma_alloc;
 
diff --git a/drivers/net/sfc/sfc_ev.h b/drivers/net/sfc/sfc_ev.h
index 8f43d73..a0addd7 100644
--- a/drivers/net/sfc/sfc_ev.h
+++ b/drivers/net/sfc/sfc_ev.h
@@ -81,11 +81,10 @@ struct sfc_evq {
 	unsigned int			evq_index;
 	enum sfc_evq_state		init_state;
 	enum sfc_evq_type		type;
+	unsigned int			entries;
 };
 
 struct sfc_evq_info {
-	/* Number of EVQ entries */
-	unsigned int		entries;
 	/* Event queue creation flags */
 	uint32_t		flags;
 	/* NUMA-aware EVQ data structure used on datapath */
-- 
2.9.3

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

* [PATCH 05/13] net/sfc: remove flags from EvQ info
  2017-03-31 10:22 [PATCH 00/13] net/sfc: fix device reconfigure Andrew Rybchenko
                   ` (3 preceding siblings ...)
  2017-03-31 10:22 ` [PATCH 04/13] net/sfc: move EvQ entries to the EvQ control structure Andrew Rybchenko
@ 2017-03-31 10:22 ` Andrew Rybchenko
  2017-03-31 10:22 ` [PATCH 06/13] net/sfc: remove EvQ info array to simplify reconfigure Andrew Rybchenko
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Andrew Rybchenko @ 2017-03-31 10:22 UTC (permalink / raw)
  To: dev

Next step to get rid of EvQ info at all.

Fixes: c22d3c508e0c ("net/sfc: support parameter to choose performance profile")
Fixes: 3b809c27b1fe ("net/sfc: support link status change interrupt")

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc_ev.c | 15 +++++++--------
 drivers/net/sfc/sfc_ev.h |  2 --
 2 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c
index 60288ce..bf108f1 100644
--- a/drivers/net/sfc/sfc_ev.c
+++ b/drivers/net/sfc/sfc_ev.c
@@ -588,6 +588,7 @@ sfc_ev_qstart(struct sfc_adapter *sa, unsigned int sw_index)
 	const struct sfc_evq_info *evq_info;
 	struct sfc_evq *evq;
 	efsys_mem_t *esmp;
+	uint32_t evq_flags = sa->evq_flags;
 	unsigned int total_delay_us;
 	unsigned int delay_us;
 	int rc;
@@ -601,9 +602,14 @@ sfc_ev_qstart(struct sfc_adapter *sa, unsigned int sw_index)
 	/* Clear all events */
 	(void)memset((void *)esmp->esm_base, 0xff, EFX_EVQ_SIZE(evq->entries));
 
+	if (sa->intr.lsc_intr && sw_index == sa->mgmt_evq_index)
+		evq_flags |= EFX_EVQ_FLAGS_NOTIFY_INTERRUPT;
+	else
+		evq_flags |= EFX_EVQ_FLAGS_NOTIFY_DISABLED;
+
 	/* Create the common code event queue */
 	rc = efx_ev_qcreate(sa->nic, sw_index, esmp, evq->entries,
-			    0 /* unused on EF10 */, 0, evq_info->flags,
+			    0 /* unused on EF10 */, 0, evq_flags,
 			    &evq->common);
 	if (rc != 0)
 		goto fail_ev_qcreate;
@@ -867,15 +873,8 @@ sfc_ev_qfini(struct sfc_adapter *sa, unsigned int sw_index)
 static int
 sfc_ev_qinit_info(struct sfc_adapter *sa, unsigned int sw_index)
 {
-	struct sfc_evq_info *evq_info = &sa->evq_info[sw_index];
-
 	sfc_log_init(sa, "sw_index=%u", sw_index);
 
-	evq_info->flags = sa->evq_flags |
-		((sa->intr.lsc_intr && sw_index == sa->mgmt_evq_index) ?
-			EFX_EVQ_FLAGS_NOTIFY_INTERRUPT :
-			EFX_EVQ_FLAGS_NOTIFY_DISABLED);
-
 	return 0;
 }
 
diff --git a/drivers/net/sfc/sfc_ev.h b/drivers/net/sfc/sfc_ev.h
index a0addd7..bc96213 100644
--- a/drivers/net/sfc/sfc_ev.h
+++ b/drivers/net/sfc/sfc_ev.h
@@ -85,8 +85,6 @@ struct sfc_evq {
 };
 
 struct sfc_evq_info {
-	/* Event queue creation flags */
-	uint32_t		flags;
 	/* NUMA-aware EVQ data structure used on datapath */
 	struct sfc_evq		*evq;
 };
-- 
2.9.3

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

* [PATCH 06/13] net/sfc: remove EvQ info array to simplify reconfigure
  2017-03-31 10:22 [PATCH 00/13] net/sfc: fix device reconfigure Andrew Rybchenko
                   ` (4 preceding siblings ...)
  2017-03-31 10:22 ` [PATCH 05/13] net/sfc: remove flags from EvQ info Andrew Rybchenko
@ 2017-03-31 10:22 ` Andrew Rybchenko
  2017-03-31 10:22 ` [PATCH 07/13] net/sfc: move event support init to attach stage Andrew Rybchenko
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Andrew Rybchenko @ 2017-03-31 10:22 UTC (permalink / raw)
  To: dev

EvQ info array keeps information about EvQ centralized, however
EvQ pointers are available in TxQ and RxQ structures. Single
array for all EvQs complicates device reconfigure handling, so
simply git rid of it.

It removes notion of EvQ software index since there is no EvQ
array in software any more.

Fixes: 58294ee65afb ("net/sfc: support event queue")
Fixes: 9a75f75cb1f2 ("net/sfc: maintain management event queue")
Fixes: ce35b05c635e ("net/sfc: implement Rx queue setup release operations")
Fixes: 28944ac098aa ("net/sfc: implement Rx queue start and stop operations")
Fixes: b1b7ad933b39 ("net/sfc: set up and release Tx queues")
Fixes: fed9aeb46c19 ("net/sfc: implement transmit path start / stop")
Fixes: 3b809c27b1fe ("net/sfc: support link status change interrupt")

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc.h      |   3 +-
 drivers/net/sfc/sfc_ev.c   | 143 ++++++++++++---------------------------------
 drivers/net/sfc/sfc_ev.h   |  31 +++-------
 drivers/net/sfc/sfc_intr.c |   2 +-
 drivers/net/sfc/sfc_rx.c   |  23 ++++----
 drivers/net/sfc/sfc_tx.c   |  21 ++++---
 6 files changed, 68 insertions(+), 155 deletions(-)

diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index e77639e..5fd734e 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -139,7 +139,6 @@ struct sfc_intr {
 	boolean_t			lsc_intr;
 };
 
-struct sfc_evq_info;
 struct sfc_rxq_info;
 struct sfc_txq_info;
 struct sfc_dp_rx;
@@ -204,10 +203,10 @@ struct sfc_adapter {
 
 	uint32_t			evq_flags;
 	unsigned int			evq_count;
-	struct sfc_evq_info		*evq_info;
 
 	unsigned int			mgmt_evq_index;
 	rte_spinlock_t			mgmt_evq_lock;
+	struct sfc_evq			*mgmt_evq;
 
 	unsigned int			rxq_count;
 	struct sfc_rxq_info		*rxq_info;
diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c
index bf108f1..b007af8 100644
--- a/drivers/net/sfc/sfc_ev.c
+++ b/drivers/net/sfc/sfc_ev.c
@@ -566,7 +566,7 @@ void
 sfc_ev_mgmt_qpoll(struct sfc_adapter *sa)
 {
 	if (rte_spinlock_trylock(&sa->mgmt_evq_lock)) {
-		struct sfc_evq *mgmt_evq = sa->evq_info[sa->mgmt_evq_index].evq;
+		struct sfc_evq *mgmt_evq = sa->mgmt_evq;
 
 		if (mgmt_evq->init_state == SFC_EVQ_STARTED)
 			sfc_ev_qpoll(mgmt_evq);
@@ -582,33 +582,33 @@ sfc_ev_qprime(struct sfc_evq *evq)
 	return efx_ev_qprime(evq->common, evq->read_ptr);
 }
 
+/* Event queue HW index allocation scheme is described in sfc_ev.h. */
 int
-sfc_ev_qstart(struct sfc_adapter *sa, unsigned int sw_index)
+sfc_ev_qstart(struct sfc_evq *evq, unsigned int hw_index)
 {
-	const struct sfc_evq_info *evq_info;
-	struct sfc_evq *evq;
+	struct sfc_adapter *sa = evq->sa;
 	efsys_mem_t *esmp;
 	uint32_t evq_flags = sa->evq_flags;
 	unsigned int total_delay_us;
 	unsigned int delay_us;
 	int rc;
 
-	sfc_log_init(sa, "sw_index=%u", sw_index);
+	sfc_log_init(sa, "hw_index=%u", hw_index);
 
-	evq_info = &sa->evq_info[sw_index];
-	evq = evq_info->evq;
 	esmp = &evq->mem;
 
+	evq->evq_index = hw_index;
+
 	/* Clear all events */
 	(void)memset((void *)esmp->esm_base, 0xff, EFX_EVQ_SIZE(evq->entries));
 
-	if (sa->intr.lsc_intr && sw_index == sa->mgmt_evq_index)
+	if (sa->intr.lsc_intr && hw_index == sa->mgmt_evq_index)
 		evq_flags |= EFX_EVQ_FLAGS_NOTIFY_INTERRUPT;
 	else
 		evq_flags |= EFX_EVQ_FLAGS_NOTIFY_DISABLED;
 
 	/* Create the common code event queue */
-	rc = efx_ev_qcreate(sa->nic, sw_index, esmp, evq->entries,
+	rc = efx_ev_qcreate(sa->nic, hw_index, esmp, evq->entries,
 			    0 /* unused on EF10 */, 0, evq_flags,
 			    &evq->common);
 	if (rc != 0)
@@ -671,17 +671,11 @@ sfc_ev_qstart(struct sfc_adapter *sa, unsigned int sw_index)
 }
 
 void
-sfc_ev_qstop(struct sfc_adapter *sa, unsigned int sw_index)
+sfc_ev_qstop(struct sfc_evq *evq)
 {
-	const struct sfc_evq_info *evq_info;
-	struct sfc_evq *evq;
-
-	sfc_log_init(sa, "sw_index=%u", sw_index);
-
-	SFC_ASSERT(sw_index < sa->evq_count);
+	struct sfc_adapter *sa = evq->sa;
 
-	evq_info = &sa->evq_info[sw_index];
-	evq = evq_info->evq;
+	sfc_log_init(sa, "hw_index=%u", evq->evq_index);
 
 	if (evq == NULL || evq->init_state != SFC_EVQ_STARTED)
 		return;
@@ -692,6 +686,8 @@ sfc_ev_qstop(struct sfc_adapter *sa, unsigned int sw_index)
 	evq->exception = B_FALSE;
 
 	efx_ev_qdestroy(evq->common);
+
+	evq->evq_index = 0;
 }
 
 static void
@@ -740,12 +736,12 @@ sfc_ev_start(struct sfc_adapter *sa)
 	/* Start management EVQ used for global events */
 	rte_spinlock_lock(&sa->mgmt_evq_lock);
 
-	rc = sfc_ev_qstart(sa, sa->mgmt_evq_index);
+	rc = sfc_ev_qstart(sa->mgmt_evq, sa->mgmt_evq_index);
 	if (rc != 0)
 		goto fail_mgmt_evq_start;
 
 	if (sa->intr.lsc_intr) {
-		rc = sfc_ev_qprime(sa->evq_info[sa->mgmt_evq_index].evq);
+		rc = sfc_ev_qprime(sa->mgmt_evq);
 		if (rc != 0)
 			goto fail_evq0_prime;
 	}
@@ -768,7 +764,7 @@ sfc_ev_start(struct sfc_adapter *sa)
 	return 0;
 
 fail_evq0_prime:
-	sfc_ev_qstop(sa, 0);
+	sfc_ev_qstop(sa->mgmt_evq);
 
 fail_mgmt_evq_start:
 	rte_spinlock_unlock(&sa->mgmt_evq_lock);
@@ -782,41 +778,27 @@ sfc_ev_start(struct sfc_adapter *sa)
 void
 sfc_ev_stop(struct sfc_adapter *sa)
 {
-	unsigned int sw_index;
-
 	sfc_log_init(sa, "entry");
 
 	sfc_ev_mgmt_periodic_qpoll_stop(sa);
 
-	/* Make sure that all event queues are stopped */
-	sw_index = sa->evq_count;
-	while (sw_index-- > 0) {
-		if (sw_index == sa->mgmt_evq_index) {
-			/* Locks are required for the management EVQ */
-			rte_spinlock_lock(&sa->mgmt_evq_lock);
-			sfc_ev_qstop(sa, sa->mgmt_evq_index);
-			rte_spinlock_unlock(&sa->mgmt_evq_lock);
-		} else {
-			sfc_ev_qstop(sa, sw_index);
-		}
-	}
+	rte_spinlock_lock(&sa->mgmt_evq_lock);
+	sfc_ev_qstop(sa->mgmt_evq);
+	rte_spinlock_unlock(&sa->mgmt_evq_lock);
 
 	efx_ev_fini(sa->nic);
 }
 
 int
-sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index,
+sfc_ev_qinit(struct sfc_adapter *sa,
 	     enum sfc_evq_type type, unsigned int type_index,
-	     unsigned int entries, int socket_id)
+	     unsigned int entries, int socket_id, struct sfc_evq **evqp)
 {
-	struct sfc_evq_info *evq_info;
 	struct sfc_evq *evq;
 	int rc;
 
-	sfc_log_init(sa, "sw_index=%u type=%s type_index=%u",
-		     sw_index, sfc_evq_type2str(type), type_index);
-
-	evq_info = &sa->evq_info[sw_index];
+	sfc_log_init(sa, "type=%s type_index=%u",
+		     sfc_evq_type2str(type), type_index);
 
 	SFC_ASSERT(rte_is_power_of_2(entries));
 
@@ -827,7 +809,6 @@ sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		goto fail_evq_alloc;
 
 	evq->sa = sa;
-	evq->evq_index = sw_index;
 	evq->type = type;
 	evq->entries = entries;
 
@@ -839,7 +820,9 @@ sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 
 	evq->init_state = SFC_EVQ_INITIALIZED;
 
-	evq_info->evq = evq;
+	sa->evq_count++;
+
+	*evqp = evq;
 
 	return 0;
 
@@ -853,29 +836,18 @@ sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 }
 
 void
-sfc_ev_qfini(struct sfc_adapter *sa, unsigned int sw_index)
+sfc_ev_qfini(struct sfc_evq *evq)
 {
-	struct sfc_evq *evq;
-
-	sfc_log_init(sa, "sw_index=%u", sw_index);
-
-	evq = sa->evq_info[sw_index].evq;
+	struct sfc_adapter *sa = evq->sa;
 
 	SFC_ASSERT(evq->init_state == SFC_EVQ_INITIALIZED);
 
-	sa->evq_info[sw_index].evq = NULL;
-
 	sfc_dma_free(sa, &evq->mem);
 
 	rte_free(evq);
-}
-
-static int
-sfc_ev_qinit_info(struct sfc_adapter *sa, unsigned int sw_index)
-{
-	sfc_log_init(sa, "sw_index=%u", sw_index);
 
-	return 0;
+	SFC_ASSERT(sa->evq_count > 0);
+	sa->evq_count--;
 }
 
 static int
@@ -896,19 +868,10 @@ sfc_kvarg_perf_profile_handler(__rte_unused const char *key,
 	return 0;
 }
 
-static void
-sfc_ev_qfini_info(struct sfc_adapter *sa, unsigned int sw_index)
-{
-	sfc_log_init(sa, "sw_index=%u", sw_index);
-
-	/* Nothing to cleanup */
-}
-
 int
 sfc_ev_init(struct sfc_adapter *sa)
 {
 	int rc;
-	unsigned int sw_index;
 
 	sfc_log_init(sa, "entry");
 
@@ -922,26 +885,11 @@ sfc_ev_init(struct sfc_adapter *sa)
 		goto fail_kvarg_perf_profile;
 	}
 
-	sa->evq_count = sfc_ev_qcount(sa);
 	sa->mgmt_evq_index = 0;
 	rte_spinlock_init(&sa->mgmt_evq_lock);
 
-	/* Allocate EVQ info array */
-	rc = ENOMEM;
-	sa->evq_info = rte_calloc_socket("sfc-evqs", sa->evq_count,
-					 sizeof(struct sfc_evq_info), 0,
-					 sa->socket_id);
-	if (sa->evq_info == NULL)
-		goto fail_evqs_alloc;
-
-	for (sw_index = 0; sw_index < sa->evq_count; ++sw_index) {
-		rc = sfc_ev_qinit_info(sa, sw_index);
-		if (rc != 0)
-			goto fail_ev_qinit_info;
-	}
-
-	rc = sfc_ev_qinit(sa, sa->mgmt_evq_index, SFC_EVQ_TYPE_MGMT, 0,
-			  SFC_MGMT_EVQ_ENTRIES, sa->socket_id);
+	rc = sfc_ev_qinit(sa, SFC_EVQ_TYPE_MGMT, 0, SFC_MGMT_EVQ_ENTRIES,
+			  sa->socket_id, &sa->mgmt_evq);
 	if (rc != 0)
 		goto fail_mgmt_evq_init;
 
@@ -953,15 +901,6 @@ sfc_ev_init(struct sfc_adapter *sa)
 	return 0;
 
 fail_mgmt_evq_init:
-fail_ev_qinit_info:
-	while (sw_index-- > 0)
-		sfc_ev_qfini_info(sa, sw_index);
-
-	rte_free(sa->evq_info);
-	sa->evq_info = NULL;
-
-fail_evqs_alloc:
-	sa->evq_count = 0;
 
 fail_kvarg_perf_profile:
 	sfc_log_init(sa, "failed %d", rc);
@@ -971,19 +910,11 @@ sfc_ev_init(struct sfc_adapter *sa)
 void
 sfc_ev_fini(struct sfc_adapter *sa)
 {
-	int sw_index;
-
 	sfc_log_init(sa, "entry");
 
-	/* Cleanup all event queues */
-	sw_index = sa->evq_count;
-	while (--sw_index >= 0) {
-		if (sa->evq_info[sw_index].evq != NULL)
-			sfc_ev_qfini(sa, sw_index);
-		sfc_ev_qfini_info(sa, sw_index);
-	}
+	sfc_ev_qfini(sa->mgmt_evq);
 
-	rte_free(sa->evq_info);
-	sa->evq_info = NULL;
-	sa->evq_count = 0;
+	if (sa->evq_count != 0)
+		sfc_err(sa, "%u EvQs are not destroyed before detach",
+			sa->evq_count);
 }
diff --git a/drivers/net/sfc/sfc_ev.h b/drivers/net/sfc/sfc_ev.h
index bc96213..f73201b 100644
--- a/drivers/net/sfc/sfc_ev.h
+++ b/drivers/net/sfc/sfc_ev.h
@@ -84,29 +84,16 @@ struct sfc_evq {
 	unsigned int			entries;
 };
 
-struct sfc_evq_info {
-	/* NUMA-aware EVQ data structure used on datapath */
-	struct sfc_evq		*evq;
-};
-
 /*
  * Functions below define event queue to transmit/receive queue and vice
  * versa mapping.
+ * Own event queue is allocated for management, each Rx and each Tx queue.
+ * Zero event queue is used for management events.
+ * Rx event queues from 1 to RxQ number follow management event queue.
+ * Tx event queues follow Rx event queues.
  */
 
 static inline unsigned int
-sfc_ev_qcount(struct sfc_adapter *sa)
-{
-	const struct rte_eth_dev_data *dev_data = sa->eth_dev->data;
-
-	/*
-	 * One management EVQ for global events.
-	 * Own EVQ for each Tx and Rx queue.
-	 */
-	return 1 + dev_data->nb_rx_queues + dev_data->nb_tx_queues;
-}
-
-static inline unsigned int
 sfc_evq_index_by_rxq_sw_index(__rte_unused struct sfc_adapter *sa,
 			      unsigned int rxq_sw_index)
 {
@@ -124,12 +111,12 @@ void sfc_ev_fini(struct sfc_adapter *sa);
 int sfc_ev_start(struct sfc_adapter *sa);
 void sfc_ev_stop(struct sfc_adapter *sa);
 
-int sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index,
+int sfc_ev_qinit(struct sfc_adapter *sa,
 		 enum sfc_evq_type type, unsigned int type_index,
-		 unsigned int entries, int socket_id);
-void sfc_ev_qfini(struct sfc_adapter *sa, unsigned int sw_index);
-int sfc_ev_qstart(struct sfc_adapter *sa, unsigned int sw_index);
-void sfc_ev_qstop(struct sfc_adapter *sa, unsigned int sw_index);
+		 unsigned int entries, int socket_id, struct sfc_evq **evqp);
+void sfc_ev_qfini(struct sfc_evq *evq);
+int sfc_ev_qstart(struct sfc_evq *evq, unsigned int hw_index);
+void sfc_ev_qstop(struct sfc_evq *evq);
 
 int sfc_ev_qprime(struct sfc_evq *evq);
 void sfc_ev_qpoll(struct sfc_evq *evq);
diff --git a/drivers/net/sfc/sfc_intr.c b/drivers/net/sfc/sfc_intr.c
index 0d199b4..448709c 100644
--- a/drivers/net/sfc/sfc_intr.c
+++ b/drivers/net/sfc/sfc_intr.c
@@ -55,7 +55,7 @@ sfc_intr_handle_mgmt_evq(struct sfc_adapter *sa)
 
 	rte_spinlock_lock(&sa->mgmt_evq_lock);
 
-	evq = sa->evq_info[sa->mgmt_evq_index].evq;
+	evq = sa->mgmt_evq;
 
 	if (evq->init_state != SFC_EVQ_STARTED) {
 		sfc_log_init(sa, "interrupt on stopped EVQ %u", evq->evq_index);
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 8c929f8..9ca5eeb 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -643,7 +643,7 @@ sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
 
 	evq = rxq->evq;
 
-	rc = sfc_ev_qstart(sa, evq->evq_index);
+	rc = sfc_ev_qstart(evq, sfc_evq_index_by_rxq_sw_index(sa, sw_index));
 	if (rc != 0)
 		goto fail_ev_qstart;
 
@@ -681,7 +681,7 @@ sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
 	sfc_rx_qflush(sa, sw_index);
 
 fail_rx_qcreate:
-	sfc_ev_qstop(sa, evq->evq_index);
+	sfc_ev_qstop(evq);
 
 fail_ev_qstart:
 	return rc;
@@ -719,7 +719,7 @@ sfc_rx_qstop(struct sfc_adapter *sa, unsigned int sw_index)
 
 	efx_rx_qdestroy(rxq->common);
 
-	sfc_ev_qstop(sa, rxq->evq->evq_index);
+	sfc_ev_qstop(rxq->evq);
 }
 
 static int
@@ -862,7 +862,6 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	int rc;
 	uint16_t buf_size;
 	struct sfc_rxq_info *rxq_info;
-	unsigned int evq_index;
 	struct sfc_evq *evq;
 	struct sfc_rxq *rxq;
 	struct sfc_dp_rx_qcreate_info info;
@@ -900,15 +899,11 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		sa->eth_dev->data->dev_conf.rxmode.enable_scatter ?
 		EFX_RXQ_TYPE_SCATTER : EFX_RXQ_TYPE_DEFAULT;
 
-	evq_index = sfc_evq_index_by_rxq_sw_index(sa, sw_index);
-
-	rc = sfc_ev_qinit(sa, evq_index, SFC_EVQ_TYPE_RX, sw_index,
-			  rxq_info->entries, socket_id);
+	rc = sfc_ev_qinit(sa, SFC_EVQ_TYPE_RX, sw_index,
+			  rxq_info->entries, socket_id, &evq);
 	if (rc != 0)
 		goto fail_ev_qinit;
 
-	evq = sa->evq_info[evq_index].evq;
-
 	rc = ENOMEM;
 	rxq = rte_zmalloc_socket("sfc-rxq", sizeof(*rxq), RTE_CACHE_LINE_SIZE,
 				 socket_id);
@@ -969,7 +964,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	rte_free(rxq);
 
 fail_rxq_alloc:
-	sfc_ev_qfini(sa, evq_index);
+	sfc_ev_qfini(evq);
 
 fail_ev_qinit:
 	rxq_info->entries = 0;
@@ -999,9 +994,11 @@ sfc_rx_qfini(struct sfc_adapter *sa, unsigned int sw_index)
 	rxq_info->entries = 0;
 
 	sfc_dma_free(sa, &rxq->mem);
-	rte_free(rxq);
 
-	sfc_ev_qfini(sa, sfc_evq_index_by_rxq_sw_index(sa, sw_index));
+	sfc_ev_qfini(rxq->evq);
+	rxq->evq = NULL;
+
+	rte_free(rxq);
 }
 
 #if EFSYS_OPT_RX_SCALE
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 2c45e1a..9597029 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -134,7 +134,6 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	struct sfc_txq_info *txq_info;
 	struct sfc_evq *evq;
 	struct sfc_txq *txq;
-	unsigned int evq_index = sfc_evq_index_by_txq_sw_index(sa, sw_index);
 	int rc = 0;
 	struct sfc_dp_tx_qcreate_info info;
 
@@ -150,13 +149,11 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	SFC_ASSERT(nb_tx_desc <= sa->txq_max_entries);
 	txq_info->entries = nb_tx_desc;
 
-	rc = sfc_ev_qinit(sa, evq_index, SFC_EVQ_TYPE_TX, sw_index,
-			  txq_info->entries, socket_id);
+	rc = sfc_ev_qinit(sa, SFC_EVQ_TYPE_TX, sw_index,
+			  txq_info->entries, socket_id, &evq);
 	if (rc != 0)
 		goto fail_ev_qinit;
 
-	evq = sa->evq_info[evq_index].evq;
-
 	rc = ENOMEM;
 	txq = rte_zmalloc_socket("sfc-txq", sizeof(*txq), 0, socket_id);
 	if (txq == NULL)
@@ -209,7 +206,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 	rte_free(txq);
 
 fail_txq_alloc:
-	sfc_ev_qfini(sa, evq_index);
+	sfc_ev_qfini(evq);
 
 fail_ev_qinit:
 	txq_info->entries = 0;
@@ -241,9 +238,11 @@ sfc_tx_qfini(struct sfc_adapter *sa, unsigned int sw_index)
 	txq_info->entries = 0;
 
 	sfc_dma_free(sa, &txq->mem);
-	rte_free(txq);
 
-	sfc_ev_qfini(sa, sfc_evq_index_by_txq_sw_index(sa, sw_index));
+	sfc_ev_qfini(txq->evq);
+	txq->evq = NULL;
+
+	rte_free(txq);
 }
 
 static int
@@ -379,7 +378,7 @@ sfc_tx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
 
 	evq = txq->evq;
 
-	rc = sfc_ev_qstart(sa, evq->evq_index);
+	rc = sfc_ev_qstart(evq, sfc_evq_index_by_txq_sw_index(sa, sw_index));
 	if (rc != 0)
 		goto fail_ev_qstart;
 
@@ -429,7 +428,7 @@ sfc_tx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
 	efx_tx_qdestroy(txq->common);
 
 fail_tx_qcreate:
-	sfc_ev_qstop(sa, evq->evq_index);
+	sfc_ev_qstop(evq);
 
 fail_ev_qstart:
 	return rc;
@@ -497,7 +496,7 @@ sfc_tx_qstop(struct sfc_adapter *sa, unsigned int sw_index)
 
 	efx_tx_qdestroy(txq->common);
 
-	sfc_ev_qstop(sa, txq->evq->evq_index);
+	sfc_ev_qstop(txq->evq);
 
 	/*
 	 * It seems to be used by DPDK for debug purposes only ('rte_ether')
-- 
2.9.3

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

* [PATCH 07/13] net/sfc: move event support init to attach stage
  2017-03-31 10:22 [PATCH 00/13] net/sfc: fix device reconfigure Andrew Rybchenko
                   ` (5 preceding siblings ...)
  2017-03-31 10:22 ` [PATCH 06/13] net/sfc: remove EvQ info array to simplify reconfigure Andrew Rybchenko
@ 2017-03-31 10:22 ` Andrew Rybchenko
  2017-03-31 10:22 ` [PATCH 08/13] net/sfc: initialize port data on attach Andrew Rybchenko
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Andrew Rybchenko @ 2017-03-31 10:22 UTC (permalink / raw)
  To: dev

Prepare to fix device reconfigure.
Device arguments should be parsed once on attach.
Management event queue should be initialized once on attach.

Fixes: 58294ee65afb ("net/sfc: support event queue")
Fixes: c22d3c508e0c ("net/sfc: support parameter to choose performance profile")

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc.c    | 17 ++++++++---------
 drivers/net/sfc/sfc_ev.c |  4 ++--
 drivers/net/sfc/sfc_ev.h |  4 ++--
 3 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index ad3dab1..a5d4736 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -409,10 +409,6 @@ sfc_configure(struct sfc_adapter *sa)
 	if (rc != 0)
 		goto fail_intr_configure;
 
-	rc = sfc_ev_init(sa);
-	if (rc != 0)
-		goto fail_ev_init;
-
 	rc = sfc_port_init(sa);
 	if (rc != 0)
 		goto fail_port_init;
@@ -436,9 +432,6 @@ sfc_configure(struct sfc_adapter *sa)
 	sfc_port_fini(sa);
 
 fail_port_init:
-	sfc_ev_fini(sa);
-
-fail_ev_init:
 	sfc_intr_close(sa);
 
 fail_intr_configure:
@@ -461,7 +454,6 @@ sfc_close(struct sfc_adapter *sa)
 	sfc_tx_fini(sa);
 	sfc_rx_fini(sa);
 	sfc_port_fini(sa);
-	sfc_ev_fini(sa);
 	sfc_intr_close(sa);
 
 	sa->state = SFC_ADAPTER_INITIALIZED;
@@ -607,6 +599,10 @@ sfc_attach(struct sfc_adapter *sa)
 	if (rc != 0)
 		goto fail_intr_attach;
 
+	rc = sfc_ev_attach(sa);
+	if (rc != 0)
+		goto fail_ev_attach;
+
 	efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_PERM,
 			    &sa->port.phy_adv_cap_mask);
 
@@ -630,6 +626,9 @@ sfc_attach(struct sfc_adapter *sa)
 
 fail_filter_attach:
 fail_set_rss_defaults:
+	sfc_ev_detach(sa);
+
+fail_ev_attach:
 	sfc_intr_detach(sa);
 
 fail_intr_attach:
@@ -652,7 +651,7 @@ sfc_detach(struct sfc_adapter *sa)
 	sfc_flow_fini(sa);
 
 	sfc_filter_detach(sa);
-
+	sfc_ev_detach(sa);
 	sfc_intr_detach(sa);
 
 	sa->state = SFC_ADAPTER_UNINITIALIZED;
diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c
index b007af8..26e6b2f 100644
--- a/drivers/net/sfc/sfc_ev.c
+++ b/drivers/net/sfc/sfc_ev.c
@@ -869,7 +869,7 @@ sfc_kvarg_perf_profile_handler(__rte_unused const char *key,
 }
 
 int
-sfc_ev_init(struct sfc_adapter *sa)
+sfc_ev_attach(struct sfc_adapter *sa)
 {
 	int rc;
 
@@ -908,7 +908,7 @@ sfc_ev_init(struct sfc_adapter *sa)
 }
 
 void
-sfc_ev_fini(struct sfc_adapter *sa)
+sfc_ev_detach(struct sfc_adapter *sa)
 {
 	sfc_log_init(sa, "entry");
 
diff --git a/drivers/net/sfc/sfc_ev.h b/drivers/net/sfc/sfc_ev.h
index f73201b..065defe 100644
--- a/drivers/net/sfc/sfc_ev.h
+++ b/drivers/net/sfc/sfc_ev.h
@@ -106,8 +106,8 @@ sfc_evq_index_by_txq_sw_index(struct sfc_adapter *sa, unsigned int txq_sw_index)
 	return 1 + sa->eth_dev->data->nb_rx_queues + txq_sw_index;
 }
 
-int sfc_ev_init(struct sfc_adapter *sa);
-void sfc_ev_fini(struct sfc_adapter *sa);
+int sfc_ev_attach(struct sfc_adapter *sa);
+void sfc_ev_detach(struct sfc_adapter *sa);
 int sfc_ev_start(struct sfc_adapter *sa);
 void sfc_ev_stop(struct sfc_adapter *sa);
 
-- 
2.9.3

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

* [PATCH 08/13] net/sfc: initialize port data on attach
  2017-03-31 10:22 [PATCH 00/13] net/sfc: fix device reconfigure Andrew Rybchenko
                   ` (6 preceding siblings ...)
  2017-03-31 10:22 ` [PATCH 07/13] net/sfc: move event support init to attach stage Andrew Rybchenko
@ 2017-03-31 10:22 ` Andrew Rybchenko
  2017-03-31 10:22 ` [PATCH 09/13] net/sfc: clarify Rx subsystem configure/close function names Andrew Rybchenko
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Andrew Rybchenko @ 2017-03-31 10:22 UTC (permalink / raw)
  To: dev

Port configuration should be initialized on attach to avoid reset to
defaults on device reconfigure.

Fixes: 03ed21195d9e ("net/sfc: minimum port control sufficient to receive traffic")

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc.c      | 19 ++++++++++++-------
 drivers/net/sfc/sfc.h      |  6 ++++--
 drivers/net/sfc/sfc_port.c | 32 +++++++++++++++++++++++++-------
 3 files changed, 41 insertions(+), 16 deletions(-)

diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index a5d4736..8da7879 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -409,9 +409,9 @@ sfc_configure(struct sfc_adapter *sa)
 	if (rc != 0)
 		goto fail_intr_configure;
 
-	rc = sfc_port_init(sa);
+	rc = sfc_port_configure(sa);
 	if (rc != 0)
-		goto fail_port_init;
+		goto fail_port_configure;
 
 	rc = sfc_rx_init(sa);
 	if (rc != 0)
@@ -429,9 +429,9 @@ sfc_configure(struct sfc_adapter *sa)
 	sfc_rx_fini(sa);
 
 fail_rx_init:
-	sfc_port_fini(sa);
+	sfc_port_close(sa);
 
-fail_port_init:
+fail_port_configure:
 	sfc_intr_close(sa);
 
 fail_intr_configure:
@@ -453,7 +453,7 @@ sfc_close(struct sfc_adapter *sa)
 
 	sfc_tx_fini(sa);
 	sfc_rx_fini(sa);
-	sfc_port_fini(sa);
+	sfc_port_close(sa);
 	sfc_intr_close(sa);
 
 	sa->state = SFC_ADAPTER_INITIALIZED;
@@ -603,8 +603,9 @@ sfc_attach(struct sfc_adapter *sa)
 	if (rc != 0)
 		goto fail_ev_attach;
 
-	efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_PERM,
-			    &sa->port.phy_adv_cap_mask);
+	rc = sfc_port_attach(sa);
+	if (rc != 0)
+		goto fail_port_attach;
 
 	rc = sfc_set_rss_defaults(sa);
 	if (rc != 0)
@@ -626,6 +627,9 @@ sfc_attach(struct sfc_adapter *sa)
 
 fail_filter_attach:
 fail_set_rss_defaults:
+	sfc_port_detach(sa);
+
+fail_port_attach:
 	sfc_ev_detach(sa);
 
 fail_ev_attach:
@@ -651,6 +655,7 @@ sfc_detach(struct sfc_adapter *sa)
 	sfc_flow_fini(sa);
 
 	sfc_filter_detach(sa);
+	sfc_port_detach(sa);
 	sfc_ev_detach(sa);
 	sfc_intr_detach(sa);
 
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 5fd734e..cee1eb8 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -302,8 +302,10 @@ void sfc_intr_close(struct sfc_adapter *sa);
 int sfc_intr_start(struct sfc_adapter *sa);
 void sfc_intr_stop(struct sfc_adapter *sa);
 
-int sfc_port_init(struct sfc_adapter *sa);
-void sfc_port_fini(struct sfc_adapter *sa);
+int sfc_port_attach(struct sfc_adapter *sa);
+void sfc_port_detach(struct sfc_adapter *sa);
+int sfc_port_configure(struct sfc_adapter *sa);
+void sfc_port_close(struct sfc_adapter *sa);
 int sfc_port_start(struct sfc_adapter *sa);
 void sfc_port_stop(struct sfc_adapter *sa);
 void sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c
index 7d1005e..ee96bcd 100644
--- a/drivers/net/sfc/sfc_port.c
+++ b/drivers/net/sfc/sfc_port.c
@@ -296,24 +296,42 @@ sfc_port_stop(struct sfc_adapter *sa)
 }
 
 int
-sfc_port_init(struct sfc_adapter *sa)
+sfc_port_configure(struct sfc_adapter *sa)
 {
 	const struct rte_eth_dev_data *dev_data = sa->eth_dev->data;
 	struct sfc_port *port = &sa->port;
+
+	sfc_log_init(sa, "entry");
+
+	if (dev_data->dev_conf.rxmode.jumbo_frame)
+		port->pdu = dev_data->dev_conf.rxmode.max_rx_pkt_len;
+	else
+		port->pdu = EFX_MAC_PDU(dev_data->mtu);
+
+	return 0;
+}
+
+void
+sfc_port_close(struct sfc_adapter *sa)
+{
+	sfc_log_init(sa, "entry");
+}
+
+int
+sfc_port_attach(struct sfc_adapter *sa)
+{
+	struct sfc_port *port = &sa->port;
 	long kvarg_stats_update_period_ms;
 	int rc;
 
 	sfc_log_init(sa, "entry");
 
+	efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_PERM, &port->phy_adv_cap_mask);
+
 	/* Enable flow control by default */
 	port->flow_ctrl = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
 	port->flow_ctrl_autoneg = B_TRUE;
 
-	if (dev_data->dev_conf.rxmode.jumbo_frame)
-		port->pdu = dev_data->dev_conf.rxmode.max_rx_pkt_len;
-	else
-		port->pdu = EFX_MAC_PDU(dev_data->mtu);
-
 	port->max_mcast_addrs = EFX_MAC_MULTICAST_LIST_MAX;
 	port->nb_mcast_addrs = 0;
 	port->mcast_addrs = rte_calloc_socket("mcast_addr_list_buf",
@@ -374,7 +392,7 @@ sfc_port_init(struct sfc_adapter *sa)
 }
 
 void
-sfc_port_fini(struct sfc_adapter *sa)
+sfc_port_detach(struct sfc_adapter *sa)
 {
 	struct sfc_port *port = &sa->port;
 
-- 
2.9.3

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

* [PATCH 09/13] net/sfc: clarify Rx subsystem configure/close function names
  2017-03-31 10:22 [PATCH 00/13] net/sfc: fix device reconfigure Andrew Rybchenko
                   ` (7 preceding siblings ...)
  2017-03-31 10:22 ` [PATCH 08/13] net/sfc: initialize port data on attach Andrew Rybchenko
@ 2017-03-31 10:22 ` Andrew Rybchenko
  2017-03-31 10:22 ` [PATCH 10/13] net/sfc: clarify Tx " Andrew Rybchenko
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Andrew Rybchenko @ 2017-03-31 10:22 UTC (permalink / raw)
  To: dev

Prepare to fix device reconfigure. Make it clear that corresponding
functions should be called on device configure and close operations.
No functional change.

Fixes: a8e64c6b455f ("net/sfc: implement Rx subsystem stubs")

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

diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index 8da7879..88228ae 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -413,9 +413,9 @@ sfc_configure(struct sfc_adapter *sa)
 	if (rc != 0)
 		goto fail_port_configure;
 
-	rc = sfc_rx_init(sa);
+	rc = sfc_rx_configure(sa);
 	if (rc != 0)
-		goto fail_rx_init;
+		goto fail_rx_configure;
 
 	rc = sfc_tx_init(sa);
 	if (rc != 0)
@@ -426,9 +426,9 @@ sfc_configure(struct sfc_adapter *sa)
 	return 0;
 
 fail_tx_init:
-	sfc_rx_fini(sa);
+	sfc_rx_close(sa);
 
-fail_rx_init:
+fail_rx_configure:
 	sfc_port_close(sa);
 
 fail_port_configure:
@@ -452,7 +452,7 @@ sfc_close(struct sfc_adapter *sa)
 	sa->state = SFC_ADAPTER_CLOSING;
 
 	sfc_tx_fini(sa);
-	sfc_rx_fini(sa);
+	sfc_rx_close(sa);
 	sfc_port_close(sa);
 	sfc_intr_close(sa);
 
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 9ca5eeb..92c5424 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -1216,7 +1216,7 @@ sfc_rx_check_mode(struct sfc_adapter *sa, struct rte_eth_rxmode *rxmode)
  * It should be used to allocate NUMA-unaware resources.
  */
 int
-sfc_rx_init(struct sfc_adapter *sa)
+sfc_rx_configure(struct sfc_adapter *sa)
 {
 	struct rte_eth_conf *dev_conf = &sa->eth_dev->data->dev_conf;
 	unsigned int sw_index;
@@ -1271,7 +1271,7 @@ sfc_rx_init(struct sfc_adapter *sa)
  * reconfiguration or shutdown.
  */
 void
-sfc_rx_fini(struct sfc_adapter *sa)
+sfc_rx_close(struct sfc_adapter *sa)
 {
 	unsigned int sw_index;
 
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index 521e50e..9e6282e 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -149,8 +149,8 @@ struct sfc_rxq_info {
 	boolean_t		deferred_started;
 };
 
-int sfc_rx_init(struct sfc_adapter *sa);
-void sfc_rx_fini(struct sfc_adapter *sa);
+int sfc_rx_configure(struct sfc_adapter *sa);
+void sfc_rx_close(struct sfc_adapter *sa);
 int sfc_rx_start(struct sfc_adapter *sa);
 void sfc_rx_stop(struct sfc_adapter *sa);
 
-- 
2.9.3

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

* [PATCH 10/13] net/sfc: clarify Tx subsystem configure/close function names
  2017-03-31 10:22 [PATCH 00/13] net/sfc: fix device reconfigure Andrew Rybchenko
                   ` (8 preceding siblings ...)
  2017-03-31 10:22 ` [PATCH 09/13] net/sfc: clarify Rx subsystem configure/close function names Andrew Rybchenko
@ 2017-03-31 10:22 ` Andrew Rybchenko
  2017-03-31 10:22 ` [PATCH 11/13] net/sfc: support changing the number of receive queues Andrew Rybchenko
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Andrew Rybchenko @ 2017-03-31 10:22 UTC (permalink / raw)
  To: dev

Prepare to fix device reconfigure. Make it clear that corresponding
functions should be called on device configure and close operations.
No functional change.

Fixes: a8ad8cf83f01 ("net/sfc: provide basic stubs for Tx subsystem")

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

diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index 88228ae..22141c6 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -417,15 +417,15 @@ sfc_configure(struct sfc_adapter *sa)
 	if (rc != 0)
 		goto fail_rx_configure;
 
-	rc = sfc_tx_init(sa);
+	rc = sfc_tx_configure(sa);
 	if (rc != 0)
-		goto fail_tx_init;
+		goto fail_tx_configure;
 
 	sa->state = SFC_ADAPTER_CONFIGURED;
 	sfc_log_init(sa, "done");
 	return 0;
 
-fail_tx_init:
+fail_tx_configure:
 	sfc_rx_close(sa);
 
 fail_rx_configure:
@@ -451,7 +451,7 @@ sfc_close(struct sfc_adapter *sa)
 	SFC_ASSERT(sa->state == SFC_ADAPTER_CONFIGURED);
 	sa->state = SFC_ADAPTER_CLOSING;
 
-	sfc_tx_fini(sa);
+	sfc_tx_close(sa);
 	sfc_rx_close(sa);
 	sfc_port_close(sa);
 	sfc_intr_close(sa);
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 9597029..1605eaa 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -290,7 +290,7 @@ sfc_tx_check_mode(struct sfc_adapter *sa, const struct rte_eth_txmode *txmode)
 }
 
 int
-sfc_tx_init(struct sfc_adapter *sa)
+sfc_tx_configure(struct sfc_adapter *sa)
 {
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
 	const struct rte_eth_conf *dev_conf = &sa->eth_dev->data->dev_conf;
@@ -341,7 +341,7 @@ sfc_tx_init(struct sfc_adapter *sa)
 }
 
 void
-sfc_tx_fini(struct sfc_adapter *sa)
+sfc_tx_close(struct sfc_adapter *sa)
 {
 	int sw_index;
 
diff --git a/drivers/net/sfc/sfc_tx.h b/drivers/net/sfc/sfc_tx.h
index 94477f7..6c3ac3b 100644
--- a/drivers/net/sfc/sfc_tx.h
+++ b/drivers/net/sfc/sfc_tx.h
@@ -134,8 +134,8 @@ struct sfc_txq_info {
 	boolean_t		deferred_started;
 };
 
-int sfc_tx_init(struct sfc_adapter *sa);
-void sfc_tx_fini(struct sfc_adapter *sa);
+int sfc_tx_configure(struct sfc_adapter *sa);
+void sfc_tx_close(struct sfc_adapter *sa);
 
 int sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		 uint16_t nb_tx_desc, unsigned int socket_id,
-- 
2.9.3

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

* [PATCH 11/13] net/sfc: support changing the number of receive queues
  2017-03-31 10:22 [PATCH 00/13] net/sfc: fix device reconfigure Andrew Rybchenko
                   ` (9 preceding siblings ...)
  2017-03-31 10:22 ` [PATCH 10/13] net/sfc: clarify Tx " Andrew Rybchenko
@ 2017-03-31 10:22 ` Andrew Rybchenko
  2017-03-31 10:22 ` [PATCH 12/13] net/sfc: support changing the number of transmit queues Andrew Rybchenko
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Andrew Rybchenko @ 2017-03-31 10:22 UTC (permalink / raw)
  To: dev

Fixes: a8e64c6b455f ("net/sfc: implement Rx subsystem stubs")

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc_rx.c | 87 +++++++++++++++++++++++++++++++++++-------------
 1 file changed, 63 insertions(+), 24 deletions(-)

diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 92c5424..05f7436 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -1208,9 +1208,29 @@ sfc_rx_check_mode(struct sfc_adapter *sa, struct rte_eth_rxmode *rxmode)
 }
 
 /**
+ * Destroy excess queues that are no longer needed after reconfiguration
+ * or complete close.
+ */
+static void
+sfc_rx_fini_queues(struct sfc_adapter *sa, unsigned int nb_rx_queues)
+{
+	int sw_index;
+
+	SFC_ASSERT(nb_rx_queues <= sa->rxq_count);
+
+	sw_index = sa->rxq_count;
+	while (--sw_index >= (int)nb_rx_queues) {
+		if (sa->rxq_info[sw_index].rxq != NULL)
+			sfc_rx_qfini(sa, sw_index);
+	}
+
+	sa->rxq_count = nb_rx_queues;
+}
+
+/**
  * Initialize Rx subsystem.
  *
- * Called at device configuration stage when number of receive queues is
+ * Called at device (re)configuration stage when number of receive queues is
  * specified together with other device level receive configuration.
  *
  * It should be used to allocate NUMA-unaware resources.
@@ -1219,26 +1239,53 @@ int
 sfc_rx_configure(struct sfc_adapter *sa)
 {
 	struct rte_eth_conf *dev_conf = &sa->eth_dev->data->dev_conf;
+	const unsigned int nb_rx_queues = sa->eth_dev->data->nb_rx_queues;
 	unsigned int sw_index;
 	int rc;
 
+	sfc_log_init(sa, "nb_rx_queues=%u (old %u)",
+		     nb_rx_queues, sa->rxq_count);
+
 	rc = sfc_rx_check_mode(sa, &dev_conf->rxmode);
 	if (rc != 0)
 		goto fail_check_mode;
 
-	sa->rxq_count = sa->eth_dev->data->nb_rx_queues;
+	if (nb_rx_queues == sa->rxq_count)
+		goto done;
 
-	rc = ENOMEM;
-	sa->rxq_info = rte_calloc_socket("sfc-rxqs", sa->rxq_count,
-					 sizeof(struct sfc_rxq_info), 0,
-					 sa->socket_id);
-	if (sa->rxq_info == NULL)
-		goto fail_rxqs_alloc;
+	if (sa->rxq_info == NULL) {
+		rc = ENOMEM;
+		sa->rxq_info = rte_calloc_socket("sfc-rxqs", nb_rx_queues,
+						 sizeof(sa->rxq_info[0]), 0,
+						 sa->socket_id);
+		if (sa->rxq_info == NULL)
+			goto fail_rxqs_alloc;
+	} else {
+		struct sfc_rxq_info *new_rxq_info;
+
+		if (nb_rx_queues < sa->rxq_count)
+			sfc_rx_fini_queues(sa, nb_rx_queues);
+
+		rc = ENOMEM;
+		new_rxq_info =
+			rte_realloc(sa->rxq_info,
+				    nb_rx_queues * sizeof(sa->rxq_info[0]), 0);
+		if (new_rxq_info == NULL && nb_rx_queues > 0)
+			goto fail_rxqs_realloc;
+
+		sa->rxq_info = new_rxq_info;
+		if (nb_rx_queues > sa->rxq_count)
+			memset(&sa->rxq_info[sa->rxq_count], 0,
+			       (nb_rx_queues - sa->rxq_count) *
+			       sizeof(sa->rxq_info[0]));
+	}
 
-	for (sw_index = 0; sw_index < sa->rxq_count; ++sw_index) {
-		rc = sfc_rx_qinit_info(sa, sw_index);
+	while (sa->rxq_count < nb_rx_queues) {
+		rc = sfc_rx_qinit_info(sa, sa->rxq_count);
 		if (rc != 0)
 			goto fail_rx_qinit_info;
+
+		sa->rxq_count++;
 	}
 
 #if EFSYS_OPT_RX_SCALE
@@ -1251,14 +1298,14 @@ sfc_rx_configure(struct sfc_adapter *sa)
 	}
 #endif
 
+done:
 	return 0;
 
 fail_rx_qinit_info:
-	rte_free(sa->rxq_info);
-	sa->rxq_info = NULL;
-
+fail_rxqs_realloc:
 fail_rxqs_alloc:
-	sa->rxq_count = 0;
+	sfc_rx_close(sa);
+
 fail_check_mode:
 	sfc_log_init(sa, "failed %d", rc);
 	return rc;
@@ -1267,21 +1314,13 @@ sfc_rx_configure(struct sfc_adapter *sa)
 /**
  * Shutdown Rx subsystem.
  *
- * Called at device close stage, for example, before device
- * reconfiguration or shutdown.
+ * Called at device close stage, for example, before device shutdown.
  */
 void
 sfc_rx_close(struct sfc_adapter *sa)
 {
-	unsigned int sw_index;
-
-	sw_index = sa->rxq_count;
-	while (sw_index-- > 0) {
-		if (sa->rxq_info[sw_index].rxq != NULL)
-			sfc_rx_qfini(sa, sw_index);
-	}
+	sfc_rx_fini_queues(sa, 0);
 
 	rte_free(sa->rxq_info);
 	sa->rxq_info = NULL;
-	sa->rxq_count = 0;
 }
-- 
2.9.3

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

* [PATCH 12/13] net/sfc: support changing the number of transmit queues
  2017-03-31 10:22 [PATCH 00/13] net/sfc: fix device reconfigure Andrew Rybchenko
                   ` (10 preceding siblings ...)
  2017-03-31 10:22 ` [PATCH 11/13] net/sfc: support changing the number of receive queues Andrew Rybchenko
@ 2017-03-31 10:22 ` Andrew Rybchenko
  2017-03-31 10:22 ` [PATCH 13/13] net/sfc: fix device reconfigure Andrew Rybchenko
  2017-03-31 15:31 ` [PATCH 00/13] " Ferruh Yigit
  13 siblings, 0 replies; 15+ messages in thread
From: Andrew Rybchenko @ 2017-03-31 10:22 UTC (permalink / raw)
  To: dev

Fixes: a8ad8cf83f01 ("net/sfc: provide basic stubs for Tx subsystem")

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc_tx.c | 79 +++++++++++++++++++++++++++++++++++-------------
 1 file changed, 58 insertions(+), 21 deletions(-)

diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 1605eaa..b8581d1 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -289,14 +289,37 @@ sfc_tx_check_mode(struct sfc_adapter *sa, const struct rte_eth_txmode *txmode)
 	return rc;
 }
 
+/**
+ * Destroy excess queues that are no longer needed after reconfiguration
+ * or complete close.
+ */
+static void
+sfc_tx_fini_queues(struct sfc_adapter *sa, unsigned int nb_tx_queues)
+{
+	int sw_index;
+
+	SFC_ASSERT(nb_tx_queues <= sa->txq_count);
+
+	sw_index = sa->txq_count;
+	while (--sw_index >= (int)nb_tx_queues) {
+		if (sa->txq_info[sw_index].txq != NULL)
+			sfc_tx_qfini(sa, sw_index);
+	}
+
+	sa->txq_count = nb_tx_queues;
+}
+
 int
 sfc_tx_configure(struct sfc_adapter *sa)
 {
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
 	const struct rte_eth_conf *dev_conf = &sa->eth_dev->data->dev_conf;
-	unsigned int sw_index;
+	const unsigned int nb_tx_queues = sa->eth_dev->data->nb_tx_queues;
 	int rc = 0;
 
+	sfc_log_init(sa, "nb_tx_queues=%u (old %u)",
+		     nb_tx_queues, sa->txq_count);
+
 	/*
 	 * The datapath implementation assumes absence of boundary
 	 * limits on Tx DMA descriptors. Addition of these checks on
@@ -311,28 +334,49 @@ sfc_tx_configure(struct sfc_adapter *sa)
 	if (rc != 0)
 		goto fail_check_mode;
 
-	sa->txq_count = sa->eth_dev->data->nb_tx_queues;
+	if (nb_tx_queues == sa->txq_count)
+		goto done;
 
-	sa->txq_info = rte_calloc_socket("sfc-txqs", sa->txq_count,
-					 sizeof(sa->txq_info[0]), 0,
-					 sa->socket_id);
-	if (sa->txq_info == NULL)
-		goto fail_txqs_alloc;
+	if (sa->txq_info == NULL) {
+		sa->txq_info = rte_calloc_socket("sfc-txqs", nb_tx_queues,
+						 sizeof(sa->txq_info[0]), 0,
+						 sa->socket_id);
+		if (sa->txq_info == NULL)
+			goto fail_txqs_alloc;
+	} else {
+		struct sfc_txq_info *new_txq_info;
+
+		if (nb_tx_queues < sa->txq_count)
+			sfc_tx_fini_queues(sa, nb_tx_queues);
+
+		new_txq_info =
+			rte_realloc(sa->txq_info,
+				    nb_tx_queues * sizeof(sa->txq_info[0]), 0);
+		if (new_txq_info == NULL && nb_tx_queues > 0)
+			goto fail_txqs_realloc;
+
+		sa->txq_info = new_txq_info;
+		if (nb_tx_queues > sa->txq_count)
+			memset(&sa->txq_info[sa->txq_count], 0,
+			       (nb_tx_queues - sa->txq_count) *
+			       sizeof(sa->txq_info[0]));
+	}
 
-	for (sw_index = 0; sw_index < sa->txq_count; ++sw_index) {
-		rc = sfc_tx_qinit_info(sa, sw_index);
+	while (sa->txq_count < nb_tx_queues) {
+		rc = sfc_tx_qinit_info(sa, sa->txq_count);
 		if (rc != 0)
 			goto fail_tx_qinit_info;
+
+		sa->txq_count++;
 	}
 
+done:
 	return 0;
 
 fail_tx_qinit_info:
-	rte_free(sa->txq_info);
-	sa->txq_info = NULL;
-
+fail_txqs_realloc:
 fail_txqs_alloc:
-	sa->txq_count = 0;
+	sfc_tx_close(sa);
 
 fail_check_mode:
 fail_tx_dma_desc_boundary:
@@ -343,17 +387,10 @@ sfc_tx_configure(struct sfc_adapter *sa)
 void
 sfc_tx_close(struct sfc_adapter *sa)
 {
-	int sw_index;
-
-	sw_index = sa->txq_count;
-	while (--sw_index >= 0) {
-		if (sa->txq_info[sw_index].txq != NULL)
-			sfc_tx_qfini(sa, sw_index);
-	}
+	sfc_tx_fini_queues(sa, 0);
 
 	rte_free(sa->txq_info);
 	sa->txq_info = NULL;
-	sa->txq_count = 0;
 }
 
 int
-- 
2.9.3

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

* [PATCH 13/13] net/sfc: fix device reconfigure
  2017-03-31 10:22 [PATCH 00/13] net/sfc: fix device reconfigure Andrew Rybchenko
                   ` (11 preceding siblings ...)
  2017-03-31 10:22 ` [PATCH 12/13] net/sfc: support changing the number of transmit queues Andrew Rybchenko
@ 2017-03-31 10:22 ` Andrew Rybchenko
  2017-03-31 15:31 ` [PATCH 00/13] " Ferruh Yigit
  13 siblings, 0 replies; 15+ messages in thread
From: Andrew Rybchenko @ 2017-03-31 10:22 UTC (permalink / raw)
  To: dev

Device reconfigure should be done without close which releases
all transmit and receive queue. ethdev API assumes that previously
setup queues (minimum from configured before and now) are kept
across device reconfigure.

Fixes: aaa3f5f0f79d ("net/sfc: add configure and close stubs")

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc.c        |  3 ++-
 drivers/net/sfc/sfc.h        | 28 ++++++++++++++--------------
 drivers/net/sfc/sfc_ethdev.c |  2 --
 3 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index 22141c6..4e241b2 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -398,7 +398,8 @@ sfc_configure(struct sfc_adapter *sa)
 
 	SFC_ASSERT(sfc_adapter_is_locked(sa));
 
-	SFC_ASSERT(sa->state == SFC_ADAPTER_INITIALIZED);
+	SFC_ASSERT(sa->state == SFC_ADAPTER_INITIALIZED ||
+		   sa->state == SFC_ADAPTER_CONFIGURED);
 	sa->state = SFC_ADAPTER_CONFIGURING;
 
 	rc = sfc_check_conf(sa);
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index cee1eb8..fad0ce0 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -64,20 +64,20 @@ extern "C" {
  *	V			|
  * +---------------+------------+
  * |  INITIALIZED  |
- * +---------------+<-----------+
- *	|.dev_configure		|
- *	V			|
- * +---------------+		|
- * |  CONFIGURING  |------------^
- * +---------------+ failed	|
- *	|success		|
- *	|		+---------------+
- *	|		|    CLOSING    |
- *	|		+---------------+
- *	|			^
- *	V			|.dev_close
- * +---------------+------------+
- * |  CONFIGURED   |
+ * +---------------+<-----------<---------------+
+ *	|.dev_configure		|		|
+ *	V			|failed		|
+ * +---------------+------------+		|
+ * |  CONFIGURING  |				|
+ * +---------------+----+			|
+ *	|success	|			|
+ *	|		|		+---------------+
+ *	|		|		|    CLOSING    |
+ *	|		|		+---------------+
+ *	|		|			^
+ *	V		|.dev_configure		|
+ * +---------------+----+			|.dev_close
+ * |  CONFIGURED   |----------------------------+
  * +---------------+<-----------+
  *	|.dev_start		|
  *	V			|
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 7edb17d..4f7b640 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -192,8 +192,6 @@ sfc_dev_configure(struct rte_eth_dev *dev)
 	sfc_adapter_lock(sa);
 	switch (sa->state) {
 	case SFC_ADAPTER_CONFIGURED:
-		sfc_close(sa);
-		SFC_ASSERT(sa->state == SFC_ADAPTER_INITIALIZED);
 		/* FALLTHROUGH */
 	case SFC_ADAPTER_INITIALIZED:
 		rc = sfc_configure(sa);
-- 
2.9.3

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

* Re: [PATCH 00/13] net/sfc: fix device reconfigure
  2017-03-31 10:22 [PATCH 00/13] net/sfc: fix device reconfigure Andrew Rybchenko
                   ` (12 preceding siblings ...)
  2017-03-31 10:22 ` [PATCH 13/13] net/sfc: fix device reconfigure Andrew Rybchenko
@ 2017-03-31 15:31 ` Ferruh Yigit
  13 siblings, 0 replies; 15+ messages in thread
From: Ferruh Yigit @ 2017-03-31 15:31 UTC (permalink / raw)
  To: Andrew Rybchenko, dev

On 3/31/2017 11:22 AM, Andrew Rybchenko wrote:
> When I implemented initial version of the driver I had incorrect
> understanding of the required state transition to reconfigure
> device. It was assumed that close is required before reconfigure.
> Looking at description in rte_ethdev.h, rte_eth_dev_close()
> description and rte_eth_dev_configure() implementation I see that
> I was wrong.
> 
> If reconfigure attempt is done without the patch series, testpmd
> crashes on segmentation fault. The patch series fixes it. So,
> technically it is a bug fix, but unfortunately pretty big.
> 
> The patch series should be applied after [1] (patch [2]).
> 
> Testing the patch requires [3] (patch [4]). Intel compilation of
> the patch fails since it is applied to dpdk.git tree instead of
> dpdk-next-net.git.
> 
> [1] http://dpdk.org/ml/archives/dev/2017-March/062155.html
> [2] http://dpdk.org/dev/patchwork/patch/22758/
> [3] http://dpdk.org/ml/archives/dev/2017-March/062157.html
> [4] http://dpdk.org/dev/patchwork/patch/22756/
> 
> Andrew Rybchenko (13):
>   net/sfc: clarify interrupts support function names
>   net/sfc: bind EvQ DMA space to EvQ type and type-local index
>   net/sfc: remove unused max entries from EvQ info
>   net/sfc: move EvQ entries to the EvQ control structure
>   net/sfc: remove flags from EvQ info
>   net/sfc: remove EvQ info array to simplify reconfigure
>   net/sfc: move event support init to attach stage
>   net/sfc: initialize port data on attach
>   net/sfc: clarify Rx subsystem configure/close function names
>   net/sfc: clarify Tx subsystem configure/close function names
>   net/sfc: support changing the number of receive queues
>   net/sfc: support changing the number of transmit queues
>   net/sfc: fix device reconfigure

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

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

end of thread, other threads:[~2017-03-31 15:31 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-31 10:22 [PATCH 00/13] net/sfc: fix device reconfigure Andrew Rybchenko
2017-03-31 10:22 ` [PATCH 01/13] net/sfc: clarify interrupts support function names Andrew Rybchenko
2017-03-31 10:22 ` [PATCH 02/13] net/sfc: bind EvQ DMA space to EvQ type and type-local index Andrew Rybchenko
2017-03-31 10:22 ` [PATCH 03/13] net/sfc: remove unused max entries from EvQ info Andrew Rybchenko
2017-03-31 10:22 ` [PATCH 04/13] net/sfc: move EvQ entries to the EvQ control structure Andrew Rybchenko
2017-03-31 10:22 ` [PATCH 05/13] net/sfc: remove flags from EvQ info Andrew Rybchenko
2017-03-31 10:22 ` [PATCH 06/13] net/sfc: remove EvQ info array to simplify reconfigure Andrew Rybchenko
2017-03-31 10:22 ` [PATCH 07/13] net/sfc: move event support init to attach stage Andrew Rybchenko
2017-03-31 10:22 ` [PATCH 08/13] net/sfc: initialize port data on attach Andrew Rybchenko
2017-03-31 10:22 ` [PATCH 09/13] net/sfc: clarify Rx subsystem configure/close function names Andrew Rybchenko
2017-03-31 10:22 ` [PATCH 10/13] net/sfc: clarify Tx " Andrew Rybchenko
2017-03-31 10:22 ` [PATCH 11/13] net/sfc: support changing the number of receive queues Andrew Rybchenko
2017-03-31 10:22 ` [PATCH 12/13] net/sfc: support changing the number of transmit queues Andrew Rybchenko
2017-03-31 10:22 ` [PATCH 13/13] net/sfc: fix device reconfigure Andrew Rybchenko
2017-03-31 15:31 ` [PATCH 00/13] " Ferruh Yigit

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.