aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Brandeburg <jesse.brandeburg@intel.com>2007-01-18 12:25:23 -0500
committerJeff Garzik <jeff@garzik.org>2007-02-05 16:58:41 -0500
commit60cba200f11b6f90f35634c5cd608773ae3721b7 (patch)
tree0f3724c16dac27138f55ff125af1351b586e328b
parentb5fc8f0c43d388d76ebbb5650b20f4ce4420a5ad (diff)
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>
-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 d408949d61dd..ab1b40f644d7 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)
3814 3814
3815 for (i = 0; i < E1000_MAX_INTR; i++) 3815 for (i = 0; i < E1000_MAX_INTR; i++)
3816 if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) & 3816 if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
3817 !e1000_clean_tx_irq(adapter, adapter->tx_ring))) 3817 e1000_clean_tx_irq(adapter, adapter->tx_ring)))
3818 break; 3818 break;
3819 3819
3820 if (likely(adapter->itr_setting & 3)) 3820 if (likely(adapter->itr_setting & 3))
@@ -3917,7 +3917,7 @@ e1000_intr(int irq, void *data)
3917 3917
3918 for (i = 0; i < E1000_MAX_INTR; i++) 3918 for (i = 0; i < E1000_MAX_INTR; i++)
3919 if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) & 3919 if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
3920 !e1000_clean_tx_irq(adapter, adapter->tx_ring))) 3920 e1000_clean_tx_irq(adapter, adapter->tx_ring)))
3921 break; 3921 break;
3922 3922
3923 if (likely(adapter->itr_setting & 3)) 3923 if (likely(adapter->itr_setting & 3))
@@ -3967,7 +3967,7 @@ e1000_clean(struct net_device *poll_dev, int *budget)
3967 poll_dev->quota -= work_done; 3967 poll_dev->quota -= work_done;
3968 3968
3969 /* If no Tx and not enough Rx work done, exit the polling mode */ 3969 /* If no Tx and not enough Rx work done, exit the polling mode */
3970 if ((!tx_cleaned && (work_done == 0)) || 3970 if ((tx_cleaned && (work_done < work_to_do)) ||
3971 !netif_running(poll_dev)) { 3971 !netif_running(poll_dev)) {
3972quit_polling: 3972quit_polling:
3973 if (likely(adapter->itr_setting & 3)) 3973 if (likely(adapter->itr_setting & 3))
@@ -3997,7 +3997,7 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
3997#ifdef CONFIG_E1000_NAPI 3997#ifdef CONFIG_E1000_NAPI
3998 unsigned int count = 0; 3998 unsigned int count = 0;
3999#endif 3999#endif
4000 boolean_t cleaned = FALSE; 4000 boolean_t cleaned = TRUE;
4001 unsigned int total_tx_bytes=0, total_tx_packets=0; 4001 unsigned int total_tx_bytes=0, total_tx_packets=0;
4002 4002
4003 i = tx_ring->next_to_clean; 4003 i = tx_ring->next_to_clean;
@@ -4028,7 +4028,10 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
4028#ifdef CONFIG_E1000_NAPI 4028#ifdef CONFIG_E1000_NAPI
4029#define E1000_TX_WEIGHT 64 4029#define E1000_TX_WEIGHT 64
4030 /* weight of a sort for tx, to avoid endless transmit cleanup */ 4030 /* weight of a sort for tx, to avoid endless transmit cleanup */
4031 if (count++ == E1000_TX_WEIGHT) break; 4031 if (count++ == E1000_TX_WEIGHT) {
4032 cleaned = FALSE;
4033 break;
4034 }
4032#endif 4035#endif
4033 } 4036 }
4034 4037