[dpdk-dev,04/14] net/sfc: retry port start to handle MC reboot in the middle

Message ID 1514112404-13398-5-git-send-email-arybchenko@solarflare.com (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation fail apply patch file failure

Commit Message

Andrew Rybchenko Dec. 24, 2017, 10:46 a.m. UTC
  MC reboot may be provoked by the other function which is either
starting in parallel or, for example, reconfiguring UDP tunnel
ports.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
Reviewed-by: Ivan Malov <ivan.malov@oktetlabs.ru>
---
 drivers/net/sfc/sfc.c | 59 +++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 43 insertions(+), 16 deletions(-)
  

Patch

diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index 0dcfdd8..1ca123a 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -271,27 +271,15 @@  sfc_set_drv_limits(struct sfc_adapter *sa)
 	return efx_nic_set_drv_limits(sa->nic, &lim);
 }
 
-int
-sfc_start(struct sfc_adapter *sa)
+static int
+sfc_try_start(struct sfc_adapter *sa)
 {
 	int rc;
 
 	sfc_log_init(sa, "entry");
 
 	SFC_ASSERT(sfc_adapter_is_locked(sa));
-
-	switch (sa->state) {
-	case SFC_ADAPTER_CONFIGURED:
-		break;
-	case SFC_ADAPTER_STARTED:
-		sfc_info(sa, "already started");
-		return 0;
-	default:
-		rc = EINVAL;
-		goto fail_bad_state;
-	}
-
-	sa->state = SFC_ADAPTER_STARTING;
+	SFC_ASSERT(sa->state == SFC_ADAPTER_STARTING);
 
 	sfc_log_init(sa, "set resource limits");
 	rc = sfc_set_drv_limits(sa);
@@ -327,7 +315,6 @@  sfc_start(struct sfc_adapter *sa)
 	if (rc != 0)
 		goto fail_flows_insert;
 
-	sa->state = SFC_ADAPTER_STARTED;
 	sfc_log_init(sa, "done");
 	return 0;
 
@@ -351,6 +338,46 @@  sfc_start(struct sfc_adapter *sa)
 
 fail_nic_init:
 fail_set_drv_limits:
+	sfc_log_init(sa, "failed %d", rc);
+	return rc;
+}
+
+int
+sfc_start(struct sfc_adapter *sa)
+{
+	unsigned int start_tries = 3;
+	int rc;
+
+	sfc_log_init(sa, "entry");
+
+	SFC_ASSERT(sfc_adapter_is_locked(sa));
+
+	switch (sa->state) {
+	case SFC_ADAPTER_CONFIGURED:
+		break;
+	case SFC_ADAPTER_STARTED:
+		sfc_info(sa, "already started");
+		return 0;
+	default:
+		rc = EINVAL;
+		goto fail_bad_state;
+	}
+
+	sa->state = SFC_ADAPTER_STARTING;
+
+	do {
+		rc = sfc_try_start(sa);
+	} while ((--start_tries > 0) &&
+		 (rc == EIO || rc == EAGAIN || rc == ENOENT || rc == EINVAL));
+
+	if (rc != 0)
+		goto fail_try_start;
+
+	sa->state = SFC_ADAPTER_STARTED;
+	sfc_log_init(sa, "done");
+	return 0;
+
+fail_try_start:
 	sa->state = SFC_ADAPTER_CONFIGURED;
 fail_bad_state:
 	sfc_log_init(sa, "failed %d", rc);