]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.0-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 26 Mar 2012 22:11:48 +0000 (15:11 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 26 Mar 2012 22:11:48 +0000 (15:11 -0700)
added patches:
e1000e-avoid-wrong-check-on-tx-hang.patch

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

diff --git a/queue-3.0/e1000e-avoid-wrong-check-on-tx-hang.patch b/queue-3.0/e1000e-avoid-wrong-check-on-tx-hang.patch
new file mode 100644 (file)
index 0000000..b753136
--- /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/e1000e/e1000.h  |    1 +
+ drivers/net/e1000e/netdev.c |   23 ++++++++++++++++++++---
+ 2 files changed, 21 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/e1000e/e1000.h
++++ b/drivers/net/e1000e/e1000.h
+@@ -311,6 +311,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/e1000e/netdev.c
++++ b/drivers/net/e1000e/netdev.c
+@@ -930,6 +930,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;
+@@ -941,6 +942,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);
+@@ -1054,10 +1070,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;
+@@ -3678,6 +3694,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 3249bcaba2ebaa5fbedaa6ea3b77012da7e7e3bf..750daf667166db808784671b02655dfbc2ae7036 100644 (file)
@@ -76,3 +76,4 @@ proc-ns-use-d_set_d_op-api-to-set-dentry-ops-in-proc_ns_instantiate.patch
 hwmon-fam15h_power-correct-sign-extension-of-running_avg_capture.patch
 lgdt330x-fix-signedness-error-in-i2c_read_demod_bytes.patch
 pvrusb2-fix-7mhz-8mhz-dvb-t-tuner-support-for-hvr1900-rev-d1f5.patch
+e1000e-avoid-wrong-check-on-tx-hang.patch