Commit 60cba200 authored by Jesse Brandeburg's avatar Jesse Brandeburg Committed by Jeff Garzik

e1000: fix NAPI performance on 4-port adapters

This fix attempts to solve a customer (IBM) reported issue with NAPI
enabled e1000 having bad performance when transmitting simultaneously
on four ports.  The issue comes down to an interaction between NAPI,
hardware interrupt balancing, and the driver rescheduling poll on
the same processor.  Try to fix by allowing the driver to re-enable
interrupts sooner instead of polling one more time, when there was
recently all the work completed in cleanup.
Signed-off-by: default avatarJesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: default avatarAuke Kok <auke-jan.h.kok@intel.com>
parent b5fc8f0c
...@@ -3814,7 +3814,7 @@ e1000_intr_msi(int irq, void *data) ...@@ -3814,7 +3814,7 @@ e1000_intr_msi(int irq, void *data)
for (i = 0; i < E1000_MAX_INTR; i++) for (i = 0; i < E1000_MAX_INTR; i++)
if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) & if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
!e1000_clean_tx_irq(adapter, adapter->tx_ring))) e1000_clean_tx_irq(adapter, adapter->tx_ring)))
break; break;
if (likely(adapter->itr_setting & 3)) if (likely(adapter->itr_setting & 3))
...@@ -3917,7 +3917,7 @@ e1000_intr(int irq, void *data) ...@@ -3917,7 +3917,7 @@ e1000_intr(int irq, void *data)
for (i = 0; i < E1000_MAX_INTR; i++) for (i = 0; i < E1000_MAX_INTR; i++)
if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) & if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
!e1000_clean_tx_irq(adapter, adapter->tx_ring))) e1000_clean_tx_irq(adapter, adapter->tx_ring)))
break; break;
if (likely(adapter->itr_setting & 3)) if (likely(adapter->itr_setting & 3))
...@@ -3967,7 +3967,7 @@ e1000_clean(struct net_device *poll_dev, int *budget) ...@@ -3967,7 +3967,7 @@ e1000_clean(struct net_device *poll_dev, int *budget)
poll_dev->quota -= work_done; poll_dev->quota -= work_done;
/* If no Tx and not enough Rx work done, exit the polling mode */ /* If no Tx and not enough Rx work done, exit the polling mode */
if ((!tx_cleaned && (work_done == 0)) || if ((tx_cleaned && (work_done < work_to_do)) ||
!netif_running(poll_dev)) { !netif_running(poll_dev)) {
quit_polling: quit_polling:
if (likely(adapter->itr_setting & 3)) if (likely(adapter->itr_setting & 3))
...@@ -3997,7 +3997,7 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, ...@@ -3997,7 +3997,7 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
#ifdef CONFIG_E1000_NAPI #ifdef CONFIG_E1000_NAPI
unsigned int count = 0; unsigned int count = 0;
#endif #endif
boolean_t cleaned = FALSE; boolean_t cleaned = TRUE;
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;
...@@ -4028,7 +4028,10 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, ...@@ -4028,7 +4028,10 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
#ifdef CONFIG_E1000_NAPI #ifdef CONFIG_E1000_NAPI
#define E1000_TX_WEIGHT 64 #define E1000_TX_WEIGHT 64
/* weight of a sort for tx, to avoid endless transmit cleanup */ /* weight of a sort for tx, to avoid endless transmit cleanup */
if (count++ == E1000_TX_WEIGHT) break; if (count++ == E1000_TX_WEIGHT) {
cleaned = FALSE;
break;
}
#endif #endif
} }
......
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