aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-11-18 09:25:00 -0500
committerLuis Henriques <luis.henriques@canonical.com>2012-04-05 11:17:29 -0400
commit04673eceec08bebd021690a77e60abaabac38a07 (patch)
treeee86317374b073e14051b50b116062b88935e7c1
parent43b5579781c620548de06e9179f77e9817427112 (diff)
e1000e: Avoid wrong check on TX hang
BugLink: http://bugs.launchpad.net/bugs/971808 commit 09357b00255c233705b1cf6d76a8d147340545b8 upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/net/e1000e/e1000.h1
-rw-r--r--drivers/net/e1000e/netdev.c23
2 files changed, 21 insertions, 3 deletions
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 9549879e66a..8a265f3528d 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -311,6 +311,7 @@ struct e1000_adapter {
311 u32 txd_cmd; 311 u32 txd_cmd;
312 312
313 bool detect_tx_hung; 313 bool detect_tx_hung;
314 bool tx_hang_recheck;
314 u8 tx_timeout_factor; 315 u8 tx_timeout_factor;
315 316
316 u32 tx_int_delay; 317 u32 tx_int_delay;
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 3310c3d477d..5430a9a4a28 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -930,6 +930,7 @@ static void e1000_print_hw_hang(struct work_struct *work)
930 struct e1000_adapter *adapter = container_of(work, 930 struct e1000_adapter *adapter = container_of(work,
931 struct e1000_adapter, 931 struct e1000_adapter,
932 print_hang_task); 932 print_hang_task);
933 struct net_device *netdev = adapter->netdev;
933 struct e1000_ring *tx_ring = adapter->tx_ring; 934 struct e1000_ring *tx_ring = adapter->tx_ring;
934 unsigned int i = tx_ring->next_to_clean; 935 unsigned int i = tx_ring->next_to_clean;
935 unsigned int eop = tx_ring->buffer_info[i].next_to_watch; 936 unsigned int eop = tx_ring->buffer_info[i].next_to_watch;
@@ -941,6 +942,21 @@ static void e1000_print_hw_hang(struct work_struct *work)
941 if (test_bit(__E1000_DOWN, &adapter->state)) 942 if (test_bit(__E1000_DOWN, &adapter->state))
942 return; 943 return;
943 944
945 if (!adapter->tx_hang_recheck &&
946 (adapter->flags2 & FLAG2_DMA_BURST)) {
947 /* May be block on write-back, flush and detect again
948 * flush pending descriptor writebacks to memory
949 */
950 ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
951 /* execute the writes immediately */
952 e1e_flush();
953 adapter->tx_hang_recheck = true;
954 return;
955 }
956 /* Real hang detected */
957 adapter->tx_hang_recheck = false;
958 netif_stop_queue(netdev);
959
944 e1e_rphy(hw, PHY_STATUS, &phy_status); 960 e1e_rphy(hw, PHY_STATUS, &phy_status);
945 e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status); 961 e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status);
946 e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status); 962 e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status);
@@ -1054,10 +1070,10 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
1054 if (tx_ring->buffer_info[i].time_stamp && 1070 if (tx_ring->buffer_info[i].time_stamp &&
1055 time_after(jiffies, tx_ring->buffer_info[i].time_stamp 1071 time_after(jiffies, tx_ring->buffer_info[i].time_stamp
1056 + (adapter->tx_timeout_factor * HZ)) && 1072 + (adapter->tx_timeout_factor * HZ)) &&
1057 !(er32(STATUS) & E1000_STATUS_TXOFF)) { 1073 !(er32(STATUS) & E1000_STATUS_TXOFF))
1058 schedule_work(&adapter->print_hang_task); 1074 schedule_work(&adapter->print_hang_task);
1059 netif_stop_queue(netdev); 1075 else
1060 } 1076 adapter->tx_hang_recheck = false;
1061 } 1077 }
1062 adapter->total_tx_bytes += total_tx_bytes; 1078 adapter->total_tx_bytes += total_tx_bytes;
1063 adapter->total_tx_packets += total_tx_packets; 1079 adapter->total_tx_packets += total_tx_packets;
@@ -3678,6 +3694,7 @@ static int e1000_open(struct net_device *netdev)
3678 3694
3679 e1000_irq_enable(adapter); 3695 e1000_irq_enable(adapter);
3680 3696
3697 adapter->tx_hang_recheck = false;
3681 netif_start_queue(netdev); 3698 netif_start_queue(netdev);
3682 3699
3683 adapter->idle_check = true; 3700 adapter->idle_check = true;