summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/pensando/ionic/ionic_dev.c
diff options
context:
space:
mode:
authorShannon Nelson <snelson@pensando.io>2022-01-24 21:53:11 +0300
committerDavid S. Miller <davem@davemloft.net>2022-01-25 14:15:09 +0300
commitec8ee714736e6b975b45b896ab66bbfa48fbe3d8 (patch)
treebbd24142fea5559021b792cc0423d67740724531 /drivers/net/ethernet/pensando/ionic/ionic_dev.c
parentb1552a4c839ee27d362d35a90300326dd6f7abdf (diff)
downloadlinux-ec8ee714736e6b975b45b896ab66bbfa48fbe3d8.tar.xz
ionic: stretch heartbeat detection
The driver can be premature in detecting stalled firmware when the heartbeat is not updated because the firmware can occasionally take a long time (more than 2 seconds) to service a request, and doesn't update the heartbeat during that time. The firmware heartbeat is not necessarily a steady 1 second periodic beat, but better described as something that should progress at least once in every DECVMD_TIMEOUT period. The single-threaded design in the FW means that if a devcmd or adminq request launches a large internal job, it is stuck waiting for that job to finish before it can get back to updating the heartbeat. Since all requests are "guaranteed" to finish within the DEVCMD_TIMEOUT period, the driver needs to less aggressive in checking the heartbeat progress. We change our current 2 second window to something bigger than DEVCMD_TIMEOUT which should take care of most of the issue. We stop checking for the heartbeat while waiting for a request, as long as we're still watching for the FW status. Lastly, we make sure our FW status is up to date before running a devcmd request. Once we do this, we need to not check the heartbeat on DEV commands because it may be stalled while we're on the fw_down path. Instead, we can rely on the is_fw_running check. Fixes: b2b9a8d7ed13 ("ionic: avoid races in ionic_heartbeat_check") Signed-off-by: Brett Creeley <brett@pensando.io> Signed-off-by: Shannon Nelson <snelson@pensando.io> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/pensando/ionic/ionic_dev.c')
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_dev.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.c b/drivers/net/ethernet/pensando/ionic/ionic_dev.c
index 1535a40a5fab..51d36a549ef7 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.c
@@ -236,9 +236,11 @@ do_check_time:
if (!idev->fw_status_ready)
return -ENXIO;
- /* wait at least one watchdog period since the last heartbeat */
+ /* Because of some variability in the actual FW heartbeat, we
+ * wait longer than the DEVCMD_TIMEOUT before checking again.
+ */
last_check_time = idev->last_hb_time;
- if (time_before(check_time, last_check_time + ionic->watchdog_period))
+ if (time_before(check_time, last_check_time + DEVCMD_TIMEOUT * 2 * HZ))
return 0;
fw_hb = ioread32(&idev->dev_info_regs->fw_heartbeat);