diff options
author | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-11-18 09:25:00 -0500 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-12-05 03:12:11 -0500 |
commit | 09357b00255c233705b1cf6d76a8d147340545b8 (patch) | |
tree | eefe3d9ede51b4ec653107c91fb6948aa4e523ce /drivers/net/ethernet/intel/e1000e/netdev.c | |
parent | 340e8dc1fb4032b6c8334c9bff20b2aec42ecfd8 (diff) |
e1000e: Avoid wrong check on TX hang
Based on the original patch submitted my Michael Wang
<wangyun@linux.vnet.ibm.com>.
Descriptors may not be write-back while checking TX hang with flag
FLAG2_DMA_BURST on.
So when we detect hang, we just flush the descriptor and detect
again for once.
-v2 change 1 to true and 0 to false and remove extra ()
CC: Michael Wang <wangyun@linux.vnet.ibm.com>
CC: Flavio Leitner <fbl@redhat.com>
Acked-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/e1000e/netdev.c')
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/netdev.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index c6e976302f97..c12df6972b35 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c | |||
@@ -1014,6 +1014,7 @@ static void e1000_print_hw_hang(struct work_struct *work) | |||
1014 | struct e1000_adapter *adapter = container_of(work, | 1014 | struct e1000_adapter *adapter = container_of(work, |
1015 | struct e1000_adapter, | 1015 | struct e1000_adapter, |
1016 | print_hang_task); | 1016 | print_hang_task); |
1017 | struct net_device *netdev = adapter->netdev; | ||
1017 | struct e1000_ring *tx_ring = adapter->tx_ring; | 1018 | struct e1000_ring *tx_ring = adapter->tx_ring; |
1018 | unsigned int i = tx_ring->next_to_clean; | 1019 | unsigned int i = tx_ring->next_to_clean; |
1019 | unsigned int eop = tx_ring->buffer_info[i].next_to_watch; | 1020 | unsigned int eop = tx_ring->buffer_info[i].next_to_watch; |
@@ -1025,6 +1026,21 @@ static void e1000_print_hw_hang(struct work_struct *work) | |||
1025 | if (test_bit(__E1000_DOWN, &adapter->state)) | 1026 | if (test_bit(__E1000_DOWN, &adapter->state)) |
1026 | return; | 1027 | return; |
1027 | 1028 | ||
1029 | if (!adapter->tx_hang_recheck && | ||
1030 | (adapter->flags2 & FLAG2_DMA_BURST)) { | ||
1031 | /* May be block on write-back, flush and detect again | ||
1032 | * flush pending descriptor writebacks to memory | ||
1033 | */ | ||
1034 | ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD); | ||
1035 | /* execute the writes immediately */ | ||
1036 | e1e_flush(); | ||
1037 | adapter->tx_hang_recheck = true; | ||
1038 | return; | ||
1039 | } | ||
1040 | /* Real hang detected */ | ||
1041 | adapter->tx_hang_recheck = false; | ||
1042 | netif_stop_queue(netdev); | ||
1043 | |||
1028 | e1e_rphy(hw, PHY_STATUS, &phy_status); | 1044 | e1e_rphy(hw, PHY_STATUS, &phy_status); |
1029 | e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status); | 1045 | e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status); |
1030 | e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status); | 1046 | e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status); |
@@ -1145,10 +1161,10 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) | |||
1145 | if (tx_ring->buffer_info[i].time_stamp && | 1161 | if (tx_ring->buffer_info[i].time_stamp && |
1146 | time_after(jiffies, tx_ring->buffer_info[i].time_stamp | 1162 | time_after(jiffies, tx_ring->buffer_info[i].time_stamp |
1147 | + (adapter->tx_timeout_factor * HZ)) && | 1163 | + (adapter->tx_timeout_factor * HZ)) && |
1148 | !(er32(STATUS) & E1000_STATUS_TXOFF)) { | 1164 | !(er32(STATUS) & E1000_STATUS_TXOFF)) |
1149 | schedule_work(&adapter->print_hang_task); | 1165 | schedule_work(&adapter->print_hang_task); |
1150 | netif_stop_queue(netdev); | 1166 | else |
1151 | } | 1167 | adapter->tx_hang_recheck = false; |
1152 | } | 1168 | } |
1153 | adapter->total_tx_bytes += total_tx_bytes; | 1169 | adapter->total_tx_bytes += total_tx_bytes; |
1154 | adapter->total_tx_packets += total_tx_packets; | 1170 | adapter->total_tx_packets += total_tx_packets; |
@@ -3838,6 +3854,7 @@ static int e1000_open(struct net_device *netdev) | |||
3838 | 3854 | ||
3839 | e1000_irq_enable(adapter); | 3855 | e1000_irq_enable(adapter); |
3840 | 3856 | ||
3857 | adapter->tx_hang_recheck = false; | ||
3841 | netif_start_queue(netdev); | 3858 | netif_start_queue(netdev); |
3842 | 3859 | ||
3843 | adapter->idle_check = true; | 3860 | adapter->idle_check = true; |