From 76a64685e812d8f1de840773358c2ce821ecb370 Mon Sep 17 00:00:00 2001 From: Eugene Syromiatnikov Date: Thu, 27 Aug 2020 19:10:02 +0200 Subject: [PATCH 4/5] Revert "[netdrv] ice: Removing hung_queue variable to use txqueue function parameter" This reverts commit 669e50a2e214aea57e159e9af04196e32dfb2856. --- drivers/net/ethernet/intel/ice/ice_main.c | 41 ++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index 4853a1e0632c..ed66596ba75d 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -5447,17 +5447,36 @@ static void ice_tx_timeout(struct net_device *netdev, unsigned int txqueue) struct ice_ring *tx_ring = NULL; struct ice_vsi *vsi = np->vsi; struct ice_pf *pf = vsi->back; + int hung_queue = -1; u32 i; pf->tx_timeout_count++; - /* now that we have an index, find the tx_ring struct */ - for (i = 0; i < vsi->num_txq; i++) - if (vsi->tx_rings[i] && vsi->tx_rings[i]->desc) - if (txqueue == vsi->tx_rings[i]->q_index) { - tx_ring = vsi->tx_rings[i]; - break; - } + /* find the stopped queue the same way dev_watchdog() does */ + for (i = 0; i < netdev->num_tx_queues; i++) { + unsigned long trans_start; + struct netdev_queue *q; + + q = netdev_get_tx_queue(netdev, i); + trans_start = q->trans_start; + if (netif_xmit_stopped(q) && + time_after(jiffies, + trans_start + netdev->watchdog_timeo)) { + hung_queue = i; + break; + } + } + + if (i == netdev->num_tx_queues) + netdev_info(netdev, "tx_timeout: no netdev hung queue found\n"); + else + /* now that we have an index, find the tx_ring struct */ + for (i = 0; i < vsi->num_txq; i++) + if (vsi->tx_rings[i] && vsi->tx_rings[i]->desc) + if (hung_queue == vsi->tx_rings[i]->q_index) { + tx_ring = vsi->tx_rings[i]; + break; + } /* Reset recovery level if enough time has elapsed after last timeout. * Also ensure no new reset action happens before next timeout period. @@ -5472,19 +5491,19 @@ static void ice_tx_timeout(struct net_device *netdev, unsigned int txqueue) struct ice_hw *hw = &pf->hw; u32 head, val = 0; - head = (rd32(hw, QTX_COMM_HEAD(vsi->txq_map[txqueue])) & + head = (rd32(hw, QTX_COMM_HEAD(vsi->txq_map[hung_queue])) & QTX_COMM_HEAD_HEAD_M) >> QTX_COMM_HEAD_HEAD_S; /* Read interrupt register */ val = rd32(hw, GLINT_DYN_CTL(tx_ring->q_vector->reg_idx)); netdev_info(netdev, "tx_timeout: VSI_num: %d, Q %d, NTC: 0x%x, HW_HEAD: 0x%x, NTU: 0x%x, INT: 0x%x\n", - vsi->vsi_num, txqueue, tx_ring->next_to_clean, + vsi->vsi_num, hung_queue, tx_ring->next_to_clean, head, tx_ring->next_to_use, val); } pf->tx_timeout_last_recovery = jiffies; - netdev_info(netdev, "tx_timeout recovery level %d, txqueue %d\n", - pf->tx_timeout_recovery_level, txqueue); + netdev_info(netdev, "tx_timeout recovery level %d, hung_queue %d\n", + pf->tx_timeout_recovery_level, hung_queue); switch (pf->tx_timeout_recovery_level) { case 1: -- 2.13.6