aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
diff options
context:
space:
mode:
authorGreg Rose <gregory.v.rose@intel.com>2011-06-03 03:53:24 +0000
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-08-26 23:31:09 -0700
commit98b9e48fca11c8aa54b25c02d3329392b52db8ab (patch)
tree9fe0adc6cb1cef157878c35a11f75ca37fcdfc9b /drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
parente1000e: convert to netdev features/hw_features API (diff)
downloadlinux-dev-98b9e48fca11c8aa54b25c02d3329392b52db8ab.tar.xz
linux-dev-98b9e48fca11c8aa54b25c02d3329392b52db8ab.zip
ixgbevf: Check if EOP has changed before using it
There is a chance that between the time EOP is read and the time it is used another transmit on a different CPU could have run and completed, thus leaving EOP in a bad state. Signed-off-by: Greg Rose <gregory.v.rose@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to '')
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index b1e1c2daf5f9..936532fa42ad 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -203,6 +203,9 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_adapter *adapter,
(count < tx_ring->work_limit)) {
bool cleaned = false;
rmb(); /* read buffer_info after eop_desc */
+ /* eop could change between read and DD-check */
+ if (unlikely(eop != tx_ring->tx_buffer_info[i].next_to_watch))
+ goto cont_loop;
for ( ; !cleaned; count++) {
struct sk_buff *skb;
tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
@@ -232,6 +235,7 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_adapter *adapter,
i = 0;
}
+cont_loop:
eop = tx_ring->tx_buffer_info[i].next_to_watch;
eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
}