Browse Source

backport i40e fixes

Signed-off-by: Thomas Lamprecht <[email protected]>
Thomas Lamprecht 6 years ago
parent
commit
91b336e761

+ 64 - 0
patches/kernel/0008-i40e-Fix-for-Tx-timeouts-when-interface-is-brought-u.patch

@@ -0,0 +1,64 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Martyna Szapar <[email protected]>
+Date: Tue, 7 Aug 2018 17:11:23 -0700
+Subject: [PATCH] i40e: Fix for Tx timeouts when interface is brought up if DCB
+ is enabled
+
+If interface is connected to switch port configured for DCB there are
+TX timeouts when bringing up interface. Problem started appearing after
+adding in i40e driver code mqprio hardware offload mode. In function
+i40e_vsi_configure_bw_alloc was added resetting BW rate which should
+be executing when mqprio qdisc is removed but was also when there was
+no mqprio qdisc added and DCB was enabled. In this patch was added
+additional check for DCB flag so now when DCB is enabled the correct
+DCB configs from before mqprio patch are restored.
+
+Signed-off-by: Martyna Szapar <[email protected]>
+Tested-by: Andrew Bowers <[email protected]>
+Signed-off-by: Jeff Kirsher <[email protected]>
+Signed-off-by: Thomas Lamprecht <[email protected]>
+---
+ drivers/net/ethernet/intel/i40e/i40e_main.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index 08f7bd9001bc..7895a0af37e6 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -5219,15 +5219,17 @@ static int i40e_vsi_configure_bw_alloc(struct i40e_vsi *vsi, u8 enabled_tc,
+ 				       u8 *bw_share)
+ {
+ 	struct i40e_aqc_configure_vsi_tc_bw_data bw_data;
++	struct i40e_pf *pf = vsi->back;
+ 	i40e_status ret;
+ 	int i;
+ 
+-	if (vsi->back->flags & I40E_FLAG_TC_MQPRIO)
++	/* There is no need to reset BW when mqprio mode is on.  */
++	if (pf->flags & I40E_FLAG_TC_MQPRIO)
+ 		return 0;
+-	if (!vsi->mqprio_qopt.qopt.hw) {
++	if (!vsi->mqprio_qopt.qopt.hw && !(pf->flags & I40E_FLAG_DCB_ENABLED)) {
+ 		ret = i40e_set_bw_limit(vsi, vsi->seid, 0);
+ 		if (ret)
+-			dev_info(&vsi->back->pdev->dev,
++			dev_info(&pf->pdev->dev,
+ 				 "Failed to reset tx rate for vsi->seid %u\n",
+ 				 vsi->seid);
+ 		return ret;
+@@ -5236,12 +5238,11 @@ static int i40e_vsi_configure_bw_alloc(struct i40e_vsi *vsi, u8 enabled_tc,
+ 	for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
+ 		bw_data.tc_bw_credits[i] = bw_share[i];
+ 
+-	ret = i40e_aq_config_vsi_tc_bw(&vsi->back->hw, vsi->seid, &bw_data,
+-				       NULL);
++	ret = i40e_aq_config_vsi_tc_bw(&pf->hw, vsi->seid, &bw_data, NULL);
+ 	if (ret) {
+-		dev_info(&vsi->back->pdev->dev,
++		dev_info(&pf->pdev->dev,
+ 			 "AQ command Config VSI BW allocation per TC failed = %d\n",
+-			 vsi->back->hw.aq.asq_last_status);
++			 pf->hw.aq.asq_last_status);
+ 		return -EINVAL;
+ 	}
+ 

+ 58 - 0
patches/kernel/0009-i40e-prevent-overlapping-tx_timeout-recover.patch

@@ -0,0 +1,58 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Alan Brady <[email protected]>
+Date: Mon, 29 Oct 2018 11:27:21 -0700
+Subject: [PATCH] i40e: prevent overlapping tx_timeout recover
+
+If a TX hang occurs, we attempt to recover by incrementally resetting.
+If we're starved for CPU time, it's possible the reset doesn't actually
+complete (or even fire) before another tx_timeout fires causing us to
+fly through the different resets without actually doing them.
+
+This adds a bit to set and check if a timeout recovery is already
+pending and, if so, bail out of tx_timeout.  The bit will get cleared at
+the end of i40e_rebuild when reset is complete.
+
+Signed-off-by: Alan Brady <[email protected]>
+Tested-by: Andrew Bowers <[email protected]>
+Signed-off-by: Jeff Kirsher <[email protected]>
+Signed-off-by: Thomas Lamprecht <[email protected]>
+---
+ drivers/net/ethernet/intel/i40e/i40e.h      | 1 +
+ drivers/net/ethernet/intel/i40e/i40e_main.c | 5 +++++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
+index e019baa905c5..80114d6a910a 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e.h
++++ b/drivers/net/ethernet/intel/i40e/i40e.h
+@@ -145,6 +145,7 @@ enum i40e_state_t {
+ 	__I40E_MDD_EVENT_PENDING,
+ 	__I40E_VFLR_EVENT_PENDING,
+ 	__I40E_RESET_RECOVERY_PENDING,
++	__I40E_TIMEOUT_RECOVERY_PENDING,
+ 	__I40E_MISC_IRQ_REQUESTED,
+ 	__I40E_RESET_INTR_RECEIVED,
+ 	__I40E_REINIT_REQUESTED,
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index 7895a0af37e6..874fd143c351 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -365,6 +365,10 @@ static void i40e_tx_timeout(struct net_device *netdev)
+ 		      (pf->tx_timeout_last_recovery + netdev->watchdog_timeo)))
+ 		return;   /* don't do any new action before the next timeout */
+ 
++	/* don't kick off another recovery if one is already pending */
++	if (test_and_set_bit(__I40E_TIMEOUT_RECOVERY_PENDING, pf->state))
++		return;
++
+ 	if (tx_ring) {
+ 		head = i40e_get_head(tx_ring);
+ 		/* Read interrupt register */
+@@ -9478,6 +9482,7 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
+ 	clear_bit(__I40E_RESET_FAILED, pf->state);
+ clear_recovery:
+ 	clear_bit(__I40E_RESET_RECOVERY_PENDING, pf->state);
++	clear_bit(__I40E_TIMEOUT_RECOVERY_PENDING, pf->state);
+ }
+ 
+ /**