Commit 187dcf19 authored by Mallikarjuna R Chilakala's avatar Mallikarjuna R Chilakala Committed by Jeff Garzik

[PATCH] ixgb: Avoid race e1000_watchdog and ixgb_clean_tx_irq

Avoid race between e1000_watchdog and ixgb_clean_tx_irq
Signed-off-by: default avatarMallikarjuna R Chilakala <mallikarjuna.chilakala@intel.com>
Signed-off-by: default avatarGanesh Venkatesan <ganesh.venkatesan@intel.com>
Signed-off-by: default avatarJohn Ronciak <john.ronciak@intel.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent 08252873
...@@ -176,6 +176,7 @@ struct ixgb_adapter { ...@@ -176,6 +176,7 @@ struct ixgb_adapter {
uint64_t hw_csum_tx_error; uint64_t hw_csum_tx_error;
uint32_t tx_int_delay; uint32_t tx_int_delay;
boolean_t tx_int_delay_enable; boolean_t tx_int_delay_enable;
boolean_t detect_tx_hung;
/* RX */ /* RX */
struct ixgb_desc_ring rx_ring; struct ixgb_desc_ring rx_ring;
......
...@@ -1100,7 +1100,6 @@ ixgb_watchdog(unsigned long data) ...@@ -1100,7 +1100,6 @@ ixgb_watchdog(unsigned long data)
struct ixgb_adapter *adapter = (struct ixgb_adapter *)data; struct ixgb_adapter *adapter = (struct ixgb_adapter *)data;
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct ixgb_desc_ring *txdr = &adapter->tx_ring; struct ixgb_desc_ring *txdr = &adapter->tx_ring;
unsigned int i;
ixgb_check_for_link(&adapter->hw); ixgb_check_for_link(&adapter->hw);
...@@ -1143,12 +1142,8 @@ ixgb_watchdog(unsigned long data) ...@@ -1143,12 +1142,8 @@ ixgb_watchdog(unsigned long data)
} }
} }
/* Early detection of hung controller */ /* Force detection of hung controller every watchdog period */
i = txdr->next_to_clean; adapter->detect_tx_hung = TRUE;
if(txdr->buffer_info[i].dma &&
time_after(jiffies, txdr->buffer_info[i].time_stamp + HZ) &&
!(IXGB_READ_REG(&adapter->hw, STATUS) & IXGB_STATUS_TXOFF))
netif_stop_queue(netdev);
/* generate an interrupt to force clean up of any stragglers */ /* generate an interrupt to force clean up of any stragglers */
IXGB_WRITE_REG(&adapter->hw, ICS, IXGB_INT_TXDW); IXGB_WRITE_REG(&adapter->hw, ICS, IXGB_INT_TXDW);
...@@ -1748,6 +1743,17 @@ ixgb_clean_tx_irq(struct ixgb_adapter *adapter) ...@@ -1748,6 +1743,17 @@ ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
} }
spin_unlock(&adapter->tx_lock); spin_unlock(&adapter->tx_lock);
if(adapter->detect_tx_hung) {
/* detect a transmit hang in hardware, this serializes the
* check with the clearing of time_stamp and movement of i */
adapter->detect_tx_hung = FALSE;
if(tx_ring->buffer_info[i].dma &&
time_after(jiffies, tx_ring->buffer_info[i].time_stamp + HZ)
&& !(IXGB_READ_REG(&adapter->hw, STATUS) &
IXGB_STATUS_TXOFF))
netif_stop_queue(netdev);
}
return cleaned; return cleaned;
} }
......
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