Commit ccfb342c authored by Alexander Duyck's avatar Alexander Duyck Committed by David S. Miller

e1000: cleanup clean_tx_irq routine so that it completely cleans ring

The tx cleanup routine was stopping after 64 packets and this was causing
issues resulting in the ring not being completely cleaned.

This change updates the driver to clean the entire ring and if it doesn't
it then will retry on the next pass.
Signed-off-by: default avatarAlexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 37e73df8
...@@ -3769,7 +3769,7 @@ static int e1000_clean(struct napi_struct *napi, int budget) ...@@ -3769,7 +3769,7 @@ static int e1000_clean(struct napi_struct *napi, int budget)
adapter->clean_rx(adapter, &adapter->rx_ring[0], adapter->clean_rx(adapter, &adapter->rx_ring[0],
&work_done, budget); &work_done, budget);
if (tx_cleaned) if (!tx_cleaned)
work_done = budget; work_done = budget;
/* If budget not fully consumed, exit the polling mode */ /* If budget not fully consumed, exit the polling mode */
...@@ -3796,15 +3796,16 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter, ...@@ -3796,15 +3796,16 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
struct e1000_buffer *buffer_info; struct e1000_buffer *buffer_info;
unsigned int i, eop; unsigned int i, eop;
unsigned int count = 0; unsigned int count = 0;
bool cleaned = false; bool cleaned;
unsigned int total_tx_bytes=0, total_tx_packets=0; unsigned int total_tx_bytes=0, total_tx_packets=0;
i = tx_ring->next_to_clean; i = tx_ring->next_to_clean;
eop = tx_ring->buffer_info[i].next_to_watch; eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop); eop_desc = E1000_TX_DESC(*tx_ring, eop);
while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) { while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
for (cleaned = false; !cleaned; ) { (count < tx_ring->count)) {
for (cleaned = false; !cleaned; count++) {
tx_desc = E1000_TX_DESC(*tx_ring, i); tx_desc = E1000_TX_DESC(*tx_ring, i);
buffer_info = &tx_ring->buffer_info[i]; buffer_info = &tx_ring->buffer_info[i];
cleaned = (i == eop); cleaned = (i == eop);
...@@ -3827,10 +3828,6 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter, ...@@ -3827,10 +3828,6 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
eop = tx_ring->buffer_info[i].next_to_watch; eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop); eop_desc = E1000_TX_DESC(*tx_ring, eop);
#define E1000_TX_WEIGHT 64
/* weight of a sort for tx, to avoid endless transmit cleanup */
if (count++ == E1000_TX_WEIGHT)
break;
} }
tx_ring->next_to_clean = i; tx_ring->next_to_clean = i;
...@@ -3852,8 +3849,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter, ...@@ -3852,8 +3849,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
/* Detect a transmit hang in hardware, this serializes the /* Detect a transmit hang in hardware, this serializes the
* check with the clearing of time_stamp and movement of i */ * check with the clearing of time_stamp and movement of i */
adapter->detect_tx_hung = false; adapter->detect_tx_hung = false;
if (tx_ring->buffer_info[eop].time_stamp && if (tx_ring->buffer_info[i].time_stamp &&
time_after(jiffies, tx_ring->buffer_info[eop].time_stamp + time_after(jiffies, tx_ring->buffer_info[i].time_stamp +
(adapter->tx_timeout_factor * HZ)) (adapter->tx_timeout_factor * HZ))
&& !(er32(STATUS) & E1000_STATUS_TXOFF)) { && !(er32(STATUS) & E1000_STATUS_TXOFF)) {
...@@ -3875,7 +3872,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter, ...@@ -3875,7 +3872,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
readl(hw->hw_addr + tx_ring->tdt), readl(hw->hw_addr + tx_ring->tdt),
tx_ring->next_to_use, tx_ring->next_to_use,
tx_ring->next_to_clean, tx_ring->next_to_clean,
tx_ring->buffer_info[eop].time_stamp, tx_ring->buffer_info[i].time_stamp,
eop, eop,
jiffies, jiffies,
eop_desc->upper.fields.status); eop_desc->upper.fields.status);
...@@ -3886,7 +3883,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter, ...@@ -3886,7 +3883,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
adapter->total_tx_packets += total_tx_packets; adapter->total_tx_packets += total_tx_packets;
adapter->net_stats.tx_bytes += total_tx_bytes; adapter->net_stats.tx_bytes += total_tx_bytes;
adapter->net_stats.tx_packets += total_tx_packets; adapter->net_stats.tx_packets += total_tx_packets;
return cleaned; return (count < tx_ring->count);
} }
/** /**
......
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