Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 14 Jan 2016 14:27:20 +0000 (UTC)
From:      Andrew Rybchenko <arybchik@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r293938 - stable/10/sys/dev/sfxge/common
Message-ID:  <201601141427.u0EERKlU023324@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: arybchik
Date: Thu Jan 14 14:27:20 2016
New Revision: 293938
URL: https://svnweb.freebsd.org/changeset/base/293938

Log:
  MFC r291590
  
  sfxge: retry VF vAdaptor allocation if it fails because of no EVB port yet
  
  After an MC reboot, a VF driver may reset before the PF driver has
  finished bringing everything back up. This includes the VFs EVB port.
  MC_CMD_VADAPTOR_ALLOC is the first MCDI call after an MC reboot to
  require the EVB port, so if it fails with MC_CMD_ERR_NO_EVB_PORT,
  retry the command a few times after waiting a while.
  
  Submitted by:   Mark Spender <mspender at solarflare.com>
  Sponsored by:   Solarflare Communications, Inc.

Modified:
  stable/10/sys/dev/sfxge/common/hunt_nic.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/sfxge/common/hunt_nic.c
==============================================================================
--- stable/10/sys/dev/sfxge/common/hunt_nic.c	Thu Jan 14 14:25:49 2016	(r293937)
+++ stable/10/sys/dev/sfxge/common/hunt_nic.c	Thu Jan 14 14:27:20 2016	(r293938)
@@ -1532,6 +1532,8 @@ hunt_nic_init(
 	uint32_t min_vi_count, max_vi_count;
 	uint32_t vi_count, vi_base;
 	uint32_t i;
+	uint32_t retry;
+	uint32_t delay_us;
 	efx_rc_t rc;
 
 	EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
@@ -1622,14 +1624,48 @@ hunt_nic_init(
 		}
 	}
 
-	/* Allocate a vAdapter attached to our upstream vPort/pPort */
-	if ((rc = efx_mcdi_vadaptor_alloc(enp, EVB_PORT_ID_ASSIGNED)) != 0)
-		goto fail5;
+	/*
+	 * Allocate a vAdaptor attached to our upstream vPort/pPort.
+	 *
+	 * On a VF, this may fail with MC_CMD_ERR_NO_EVB_PORT (ENOENT) if the PF
+	 * driver has yet to bring up the EVB port. See bug 56147. In this case,
+	 * retry the request several times after waiting a while. The wait time
+	 * between retries starts small (10ms) and exponentially increases.
+	 * Total wait time is a little over two seconds. Retry logic in the
+	 * client driver may mean this whole loop is repeated if it continues to
+	 * fail.
+	 */
+	retry = 0;
+	delay_us = 10000;
+	while ((rc = efx_mcdi_vadaptor_alloc(enp, EVB_PORT_ID_ASSIGNED)) != 0) {
+		if (EFX_PCI_FUNCTION_IS_PF(&enp->en_nic_cfg) ||
+		    (rc != ENOENT)) {
+			/*
+			 * Do not retry alloc for PF, or for other errors on
+			 * a VF.
+			 */
+			goto fail5;
+		}
+
+		/* VF startup before PF is ready. Retry allocation. */
+		if (retry > 5) {
+			/* Too many attempts */
+			rc = EINVAL;
+			goto fail6;
+		}
+		EFSYS_PROBE1(mcdi_no_evb_port_retry, int, retry);
+		EFSYS_SLEEP(delay_us);
+		retry++;
+		if (delay_us < 500000)
+			delay_us <<= 2;
+	}
 
 	enp->en_vport_id = EVB_PORT_ID_ASSIGNED;
 
 	return (0);
 
+fail6:
+	EFSYS_PROBE(fail6);
 fail5:
 	EFSYS_PROBE(fail5);
 fail4:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201601141427.u0EERKlU023324>