]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.2-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 24 Mar 2012 18:32:13 +0000 (11:32 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 24 Mar 2012 18:32:13 +0000 (11:32 -0700)
added patches:
e1000e-avoid-wrong-check-on-tx-hang.patch

queue-3.2/e1000e-avoid-wrong-check-on-tx-hang.patch [new file with mode: 0644]
queue-3.2/series

diff --git a/queue-3.2/e1000e-avoid-wrong-check-on-tx-hang.patch b/queue-3.2/e1000e-avoid-wrong-check-on-tx-hang.patch
new file mode 100644 (file)
index 0000000..ce8851e
--- /dev/null
@@ -0,0 +1,94 @@
+From 09357b00255c233705b1cf6d76a8d147340545b8 Mon Sep 17 00:00:00 2001
+From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+Date: Fri, 18 Nov 2011 14:25:00 +0000
+Subject: e1000e: Avoid wrong check on TX hang
+
+From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+
+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>
+
+---
+ drivers/net/ethernet/intel/e1000e/e1000.h  |    1 +
+ drivers/net/ethernet/intel/e1000e/netdev.c |   23 ++++++++++++++++++++---
+ 2 files changed, 21 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/intel/e1000e/e1000.h
++++ b/drivers/net/ethernet/intel/e1000e/e1000.h
+@@ -309,6 +309,7 @@ struct e1000_adapter {
+       u32 txd_cmd;
+       bool detect_tx_hung;
++      bool tx_hang_recheck;
+       u8 tx_timeout_factor;
+       u32 tx_int_delay;
+--- a/drivers/net/ethernet/intel/e1000e/netdev.c
++++ b/drivers/net/ethernet/intel/e1000e/netdev.c
+@@ -1030,6 +1030,7 @@ static void e1000_print_hw_hang(struct w
+       struct e1000_adapter *adapter = container_of(work,
+                                                    struct e1000_adapter,
+                                                    print_hang_task);
++      struct net_device *netdev = adapter->netdev;
+       struct e1000_ring *tx_ring = adapter->tx_ring;
+       unsigned int i = tx_ring->next_to_clean;
+       unsigned int eop = tx_ring->buffer_info[i].next_to_watch;
+@@ -1041,6 +1042,21 @@ static void e1000_print_hw_hang(struct w
+       if (test_bit(__E1000_DOWN, &adapter->state))
+               return;
++      if (!adapter->tx_hang_recheck &&
++          (adapter->flags2 & FLAG2_DMA_BURST)) {
++              /* May be block on write-back, flush and detect again
++               * flush pending descriptor writebacks to memory
++               */
++              ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
++              /* execute the writes immediately */
++              e1e_flush();
++              adapter->tx_hang_recheck = true;
++              return;
++      }
++      /* Real hang detected */
++      adapter->tx_hang_recheck = false;
++      netif_stop_queue(netdev);
++
+       e1e_rphy(hw, PHY_STATUS, &phy_status);
+       e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status);
+       e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status);
+@@ -1154,10 +1170,10 @@ static bool e1000_clean_tx_irq(struct e1
+               if (tx_ring->buffer_info[i].time_stamp &&
+                   time_after(jiffies, tx_ring->buffer_info[i].time_stamp
+                              + (adapter->tx_timeout_factor * HZ)) &&
+-                  !(er32(STATUS) & E1000_STATUS_TXOFF)) {
++                  !(er32(STATUS) & E1000_STATUS_TXOFF))
+                       schedule_work(&adapter->print_hang_task);
+-                      netif_stop_queue(netdev);
+-              }
++              else
++                      adapter->tx_hang_recheck = false;
+       }
+       adapter->total_tx_bytes += total_tx_bytes;
+       adapter->total_tx_packets += total_tx_packets;
+@@ -3782,6 +3798,7 @@ static int e1000_open(struct net_device
+       e1000_irq_enable(adapter);
++      adapter->tx_hang_recheck = false;
+       netif_start_queue(netdev);
+       adapter->idle_check = true;
index 3e5066c9f72a5c0f7c44dfc2cc58fbf3de2dd934..04c90bffdbb9bdebe9e1048b4b3a0c4a39f1ff07 100644 (file)
@@ -97,3 +97,4 @@ ubi-fix-eraseblock-picking-criteria.patch
 sunrpc-we-must-not-use-list_for_each_entry_safe-in-rpc_wake_up.patch
 usbnet-increase-urb-reference-count-before-usb_unlink_urb.patch
 usbnet-don-t-clear-urb-dev-in-tx_complete.patch
+e1000e-avoid-wrong-check-on-tx-hang.patch