i40e/i40evf: fix Tx hang workaround code
authorJesse Brandeburg <jesse.brandeburg@intel.com>
Thu, 23 Jul 2015 20:54:34 +0000 (16:54 -0400)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Wed, 30 Sep 2015 12:21:26 +0000 (05:21 -0700)
The arm writeback (arm_wb) code is used for kicking the Tx ring to
make sure any pending work is completed even if interrupts are
disabled. It was running when it didn't need to, and not clearing
the ring->arm_wb state after it was set.  This caused Tx hangs
to still occur occasionally when there really was no hang.
Fix this by resetting the variable right after it was used.

Change-ID: I7bf75d552ba9c4bd203d40615213861a24bb5594
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40e/i40e_txrx.c
drivers/net/ethernet/intel/i40evf/i40e_txrx.c

index 3ce4900c0c43c40aa78422a5366cca1c634a8cde..47dba9b0299b62609e74bec0a9e846c844c99d81 100644 (file)
@@ -1842,6 +1842,7 @@ int i40e_napi_poll(struct napi_struct *napi, int budget)
        i40e_for_each_ring(ring, q_vector->tx) {
                clean_complete &= i40e_clean_tx_irq(ring, vsi->work_limit);
                arm_wb |= ring->arm_wb;
+               ring->arm_wb = false;
        }
 
        /* We attempt to distribute budget to each Rx queue fairly, but don't
index 8309793804665b49949ee5112b8d11fc7b33ab90..aaee89fd6526094e4fa93a629dc26dd3956c47ee 100644 (file)
@@ -254,8 +254,6 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget)
            !test_bit(__I40E_DOWN, &tx_ring->vsi->state) &&
            (I40E_DESC_UNUSED(tx_ring) != tx_ring->count))
                tx_ring->arm_wb = true;
-       else
-               tx_ring->arm_wb = false;
 
        netdev_tx_completed_queue(netdev_get_tx_queue(tx_ring->netdev,
                                                      tx_ring->queue_index),
@@ -1288,6 +1286,7 @@ int i40evf_napi_poll(struct napi_struct *napi, int budget)
        i40e_for_each_ring(ring, q_vector->tx) {
                clean_complete &= i40e_clean_tx_irq(ring, vsi->work_limit);
                arm_wb |= ring->arm_wb;
+               ring->arm_wb = false;
        }
 
        /* We attempt to distribute budget to each Rx queue fairly, but don't