Commit dad8a3b3 authored by John Fastabend's avatar John Fastabend Committed by Jeff Kirsher

igb, ixgbe: netdev_tx_reset_queue incorrectly called from tx init path

igb and ixgbe incorrectly call netdev_tx_reset_queue() from
i{gb|xgbe}_clean_tx_ring() this sort of works in most cases except
when the number of real tx queues changes. When the number of real
tx queues changes netdev_tx_reset_queue() only gets called on the
new number of queues so when we reduce the number of queues we risk
triggering the watchdog timer and repeated device resets.

So this is not only a cosmetic issue but causes real bugs. For
example enabling/disabling DCB or FCoE in ixgbe will trigger this.

CC: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: default avatarJohn Fastabend <john.r.fastabend@intel.com>
Tested-by: default avatarJohn Bishop <johnx.bishop@intel.com>
Tested-by: default avatarAaron Brown <aaron.f.brown@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent f525c6d2
...@@ -2771,8 +2771,6 @@ void igb_configure_tx_ring(struct igb_adapter *adapter, ...@@ -2771,8 +2771,6 @@ void igb_configure_tx_ring(struct igb_adapter *adapter,
txdctl |= E1000_TXDCTL_QUEUE_ENABLE; txdctl |= E1000_TXDCTL_QUEUE_ENABLE;
wr32(E1000_TXDCTL(reg_idx), txdctl); wr32(E1000_TXDCTL(reg_idx), txdctl);
netdev_tx_reset_queue(txring_txq(ring));
} }
/** /**
...@@ -3282,6 +3280,8 @@ static void igb_clean_tx_ring(struct igb_ring *tx_ring) ...@@ -3282,6 +3280,8 @@ static void igb_clean_tx_ring(struct igb_ring *tx_ring)
igb_unmap_and_free_tx_resource(tx_ring, buffer_info); igb_unmap_and_free_tx_resource(tx_ring, buffer_info);
} }
netdev_tx_reset_queue(txring_txq(tx_ring));
size = sizeof(struct igb_tx_buffer) * tx_ring->count; size = sizeof(struct igb_tx_buffer) * tx_ring->count;
memset(tx_ring->tx_buffer_info, 0, size); memset(tx_ring->tx_buffer_info, 0, size);
......
...@@ -1780,6 +1780,8 @@ static u16 ixgbe_clean_test_rings(struct ixgbe_ring *rx_ring, ...@@ -1780,6 +1780,8 @@ static u16 ixgbe_clean_test_rings(struct ixgbe_ring *rx_ring,
rx_desc = IXGBE_RX_DESC(rx_ring, rx_ntc); rx_desc = IXGBE_RX_DESC(rx_ring, rx_ntc);
} }
netdev_tx_reset_queue(txring_txq(tx_ring));
/* re-map buffers to ring, store next to clean values */ /* re-map buffers to ring, store next to clean values */
ixgbe_alloc_rx_buffers(rx_ring, count); ixgbe_alloc_rx_buffers(rx_ring, count);
rx_ring->next_to_clean = rx_ntc; rx_ring->next_to_clean = rx_ntc;
......
...@@ -2671,8 +2671,6 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter, ...@@ -2671,8 +2671,6 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
/* enable queue */ /* enable queue */
IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), txdctl); IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), txdctl);
netdev_tx_reset_queue(txring_txq(ring));
/* TXDCTL.EN will return 0 on 82598 if link is down, so skip it */ /* TXDCTL.EN will return 0 on 82598 if link is down, so skip it */
if (hw->mac.type == ixgbe_mac_82598EB && if (hw->mac.type == ixgbe_mac_82598EB &&
!(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP)) !(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP))
...@@ -4167,6 +4165,8 @@ static void ixgbe_clean_tx_ring(struct ixgbe_ring *tx_ring) ...@@ -4167,6 +4165,8 @@ static void ixgbe_clean_tx_ring(struct ixgbe_ring *tx_ring)
ixgbe_unmap_and_free_tx_resource(tx_ring, tx_buffer_info); ixgbe_unmap_and_free_tx_resource(tx_ring, tx_buffer_info);
} }
netdev_tx_reset_queue(txring_txq(tx_ring));
size = sizeof(struct ixgbe_tx_buffer) * tx_ring->count; size = sizeof(struct ixgbe_tx_buffer) * tx_ring->count;
memset(tx_ring->tx_buffer_info, 0, size); memset(tx_ring->tx_buffer_info, 0, size);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment