summaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000/e1000_main.c
diff options
context:
space:
mode:
authorJesse Brandeburg <jesse.brandeburg@intel.com>2007-01-18 09:25:23 -0800
committerJeff Garzik <jeff@garzik.org>2007-02-05 16:58:41 -0500
commit60cba200f11b6f90f35634c5cd608773ae3721b7 (patch)
tree0f3724c16dac27138f55ff125af1351b586e328b /drivers/net/e1000/e1000_main.c
parentb5fc8f0c43d388d76ebbb5650b20f4ce4420a5ad (diff)
downloadkernel-crypto-60cba200f11b6f90f35634c5cd608773ae3721b7.tar.gz
kernel-crypto-60cba200f11b6f90f35634c5cd608773ae3721b7.tar.xz
kernel-crypto-60cba200f11b6f90f35634c5cd608773ae3721b7.zip
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: Jesse Brandeburg <jesse.brandeburg@intel.com> Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
Diffstat (limited to 'drivers/net/e1000/e1000_main.c')
-rw-r--r--drivers/net/e1000/e1000_main.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index d408949d61d..ab1b40f644d 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -3814,7 +3814,7 @@ e1000_intr_msi(int irq, void *data)
for (i = 0; i < E1000_MAX_INTR; i++)
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;
if (likely(adapter->itr_setting & 3))
@@ -3917,7 +3917,7 @@ e1000_intr(int irq, void *data)
for (i = 0; i < E1000_MAX_INTR; i++)
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;
if (likely(adapter->itr_setting & 3))
@@ -3967,7 +3967,7 @@ e1000_clean(struct net_device *poll_dev, int *budget)
poll_dev->quota -= work_done;
/* 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)) {
quit_polling:
if (likely(adapter->itr_setting & 3))
@@ -3997,7 +3997,7 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
#ifdef CONFIG_E1000_NAPI
unsigned int count = 0;
#endif
- boolean_t cleaned = FALSE;
+ boolean_t cleaned = TRUE;
unsigned int total_tx_bytes=0, total_tx_packets=0;
i = tx_ring->next_to_clean;
@@ -4028,7 +4028,10 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
#ifdef CONFIG_E1000_NAPI
#define E1000_TX_WEIGHT 64
/* 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
}