Date: Thu, 31 Oct 2019 15:39:54 +0000 (UTC) From: Marcin Wojtas <mw@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r354219 - head/sys/dev/ena Message-ID: <201910311539.x9VFds1q053143@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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@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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201910311539.x9VFds1q053143>