svn commit: r354219 - head/sys/dev/ena

Marcin Wojtas mw at FreeBSD.org
Thu Oct 31 15:39:55 UTC 2019


Author: mw
Date: Thu Oct 31 15:39:54 2019
New Revision: 354219
URL: https://svnweb.freebsd.org/changeset/base/354219

Log:
  Fix ENA keep-alive timeout due to prolonged reset
  
  When the ENA_FLAG_DEVICE_RUNNING flag is disabled, the AENQ handlers
  aren't executed. To fix that, the watchdog timestamp should be updated
  just before enabling the watchdog.
  
  Timer service was always being enabled, even if the device wasn't up
  before the reset. That shouldn't happen, as the timer service is being
  executed only for working interface.
  
  Differential Revision: https://reviews.freebsd.org/D21932
  Submitted by:  Michal Krawczyk <mk at semihalf.com>
  Obtained from: Semihalf
  Sponsored by:  Amazon, Inc.

Modified:
  head/sys/dev/ena/ena.c

Modified: head/sys/dev/ena/ena.c
==============================================================================
--- head/sys/dev/ena/ena.c	Thu Oct 31 15:38:17 2019	(r354218)
+++ head/sys/dev/ena/ena.c	Thu Oct 31 15:39:54 2019	(r354219)
@@ -2350,8 +2350,14 @@ ena_up(struct ena_adapter *adapter)
 		if_setdrvflagbits(adapter->ifp, IFF_DRV_RUNNING,
 		    IFF_DRV_OACTIVE);
 
-		callout_reset_sbt(&adapter->timer_service, SBT_1S, SBT_1S,
-		    ena_timer_service, (void *)adapter, 0);
+		/* Activate timer service only if the device is running.
+		 * If this flag is not set, it means that the driver is being
+		 * reset and timer service will be activated afterwards.
+		 */
+		if (ENA_FLAG_ISSET(ENA_FLAG_DEVICE_RUNNING, adapter)) {
+			callout_reset_sbt(&adapter->timer_service, SBT_1S,
+			    SBT_1S, ena_timer_service, (void *)adapter, 0);
+		}
 
 		ENA_FLAG_SET_ATOMIC(ENA_FLAG_DEV_UP, adapter);
 
@@ -4222,9 +4228,20 @@ ena_restore_device(struct ena_adapter *adapter)
 		}
 	}
 
+	/* Indicate that device is running again and ready to work */
 	ENA_FLAG_SET_ATOMIC(ENA_FLAG_DEVICE_RUNNING, adapter);
-	callout_reset_sbt(&adapter->timer_service, SBT_1S, SBT_1S,
-	    ena_timer_service, (void *)adapter, 0);
+
+	if (ENA_FLAG_ISSET(ENA_FLAG_DEV_UP_BEFORE_RESET, adapter)) {
+		/*
+		 * As the AENQ handlers weren't executed during reset because
+		 * the flag ENA_FLAG_DEVICE_RUNNING was turned off, the
+		 * timestamp must be updated again That will prevent next reset
+		 * caused by missing keep alive.
+		 */
+		adapter->keep_alive_timestamp = getsbinuptime();
+		callout_reset_sbt(&adapter->timer_service, SBT_1S, SBT_1S,
+		    ena_timer_service, (void *)adapter, 0);
+	}
 
 	device_printf(dev,
 	    "Device reset completed successfully, Driver info: %s\n", ena_version);


More information about the svn-src-all mailing list