aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2011-10-05 09:35:24 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-10-07 01:46:55 -0400
commit13fde97a48b622a192ae7d0a8011248be891cdd4 (patch)
tree99be7848bab986104caa2221ba3abfc59e46da57 /drivers
parentb64e9dd5d04561c2cee7e9d9d70bd6d45cc01e7c (diff)
igb: Make Tx budget for NAPI user adjustable
This change is to make the NAPI budget limits for transmit adjustable. Currently they are only set to 128, and when the changes/improvements to NAPI occur to allow for adjustability, it would be possible to tune the value for optimal performance with applications such as routing. v2: remove tie between NAPI and interrupt moderation fix work limit define name (s/IXGBE/IGB/) Update patch description to better reflect patch Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/intel/igb/igb.h3
-rw-r--r--drivers/net/ethernet/intel/igb/igb_ethtool.c1
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c136
3 files changed, 87 insertions, 53 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index b72593785600..beab918e09ab 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -47,6 +47,7 @@ struct igb_adapter;
47 47
48/* TX/RX descriptor defines */ 48/* TX/RX descriptor defines */
49#define IGB_DEFAULT_TXD 256 49#define IGB_DEFAULT_TXD 256
50#define IGB_DEFAULT_TX_WORK 128
50#define IGB_MIN_TXD 80 51#define IGB_MIN_TXD 80
51#define IGB_MAX_TXD 4096 52#define IGB_MAX_TXD 4096
52 53
@@ -177,6 +178,7 @@ struct igb_q_vector {
177 178
178 u32 eims_value; 179 u32 eims_value;
179 u16 cpu; 180 u16 cpu;
181 u16 tx_work_limit;
180 182
181 u16 itr_val; 183 u16 itr_val;
182 u8 set_itr; 184 u8 set_itr;
@@ -266,6 +268,7 @@ struct igb_adapter {
266 u16 rx_itr; 268 u16 rx_itr;
267 269
268 /* TX */ 270 /* TX */
271 u16 tx_work_limit;
269 u32 tx_timeout_count; 272 u32 tx_timeout_count;
270 int num_tx_queues; 273 int num_tx_queues;
271 struct igb_ring *tx_ring[16]; 274 struct igb_ring *tx_ring[16];
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
index f231d82cc6cf..a445c4fbf19e 100644
--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
+++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -2011,6 +2011,7 @@ static int igb_set_coalesce(struct net_device *netdev,
2011 2011
2012 for (i = 0; i < adapter->num_q_vectors; i++) { 2012 for (i = 0; i < adapter->num_q_vectors; i++) {
2013 struct igb_q_vector *q_vector = adapter->q_vector[i]; 2013 struct igb_q_vector *q_vector = adapter->q_vector[i];
2014 q_vector->tx_work_limit = adapter->tx_work_limit;
2014 if (q_vector->rx_ring) 2015 if (q_vector->rx_ring)
2015 q_vector->itr_val = adapter->rx_itr_setting; 2016 q_vector->itr_val = adapter->rx_itr_setting;
2016 else 2017 else
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 7ad25e867add..12faa99cac53 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -136,8 +136,8 @@ static irqreturn_t igb_msix_ring(int irq, void *);
136static void igb_update_dca(struct igb_q_vector *); 136static void igb_update_dca(struct igb_q_vector *);
137static void igb_setup_dca(struct igb_adapter *); 137static void igb_setup_dca(struct igb_adapter *);
138#endif /* CONFIG_IGB_DCA */ 138#endif /* CONFIG_IGB_DCA */
139static bool igb_clean_tx_irq(struct igb_q_vector *);
140static int igb_poll(struct napi_struct *, int); 139static int igb_poll(struct napi_struct *, int);
140static bool igb_clean_tx_irq(struct igb_q_vector *);
141static bool igb_clean_rx_irq(struct igb_q_vector *, int); 141static bool igb_clean_rx_irq(struct igb_q_vector *, int);
142static int igb_ioctl(struct net_device *, struct ifreq *, int cmd); 142static int igb_ioctl(struct net_device *, struct ifreq *, int cmd);
143static void igb_tx_timeout(struct net_device *); 143static void igb_tx_timeout(struct net_device *);
@@ -1120,6 +1120,7 @@ static void igb_map_tx_ring_to_vector(struct igb_adapter *adapter,
1120 q_vector->tx_ring = adapter->tx_ring[ring_idx]; 1120 q_vector->tx_ring = adapter->tx_ring[ring_idx];
1121 q_vector->tx_ring->q_vector = q_vector; 1121 q_vector->tx_ring->q_vector = q_vector;
1122 q_vector->itr_val = adapter->tx_itr_setting; 1122 q_vector->itr_val = adapter->tx_itr_setting;
1123 q_vector->tx_work_limit = adapter->tx_work_limit;
1123 if (q_vector->itr_val && q_vector->itr_val <= 3) 1124 if (q_vector->itr_val && q_vector->itr_val <= 3)
1124 q_vector->itr_val = IGB_START_ITR; 1125 q_vector->itr_val = IGB_START_ITR;
1125} 1126}
@@ -2388,11 +2389,17 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter)
2388 2389
2389 pci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci_cmd_word); 2390 pci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci_cmd_word);
2390 2391
2392 /* set default ring sizes */
2391 adapter->tx_ring_count = IGB_DEFAULT_TXD; 2393 adapter->tx_ring_count = IGB_DEFAULT_TXD;
2392 adapter->rx_ring_count = IGB_DEFAULT_RXD; 2394 adapter->rx_ring_count = IGB_DEFAULT_RXD;
2395
2396 /* set default ITR values */
2393 adapter->rx_itr_setting = IGB_DEFAULT_ITR; 2397 adapter->rx_itr_setting = IGB_DEFAULT_ITR;
2394 adapter->tx_itr_setting = IGB_DEFAULT_ITR; 2398 adapter->tx_itr_setting = IGB_DEFAULT_ITR;
2395 2399
2400 /* set default work limits */
2401 adapter->tx_work_limit = IGB_DEFAULT_TX_WORK;
2402
2396 adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN + 2403 adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN +
2397 VLAN_HLEN; 2404 VLAN_HLEN;
2398 adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN; 2405 adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
@@ -5496,7 +5503,7 @@ static int igb_poll(struct napi_struct *napi, int budget)
5496 igb_update_dca(q_vector); 5503 igb_update_dca(q_vector);
5497#endif 5504#endif
5498 if (q_vector->tx_ring) 5505 if (q_vector->tx_ring)
5499 clean_complete = !!igb_clean_tx_irq(q_vector); 5506 clean_complete = igb_clean_tx_irq(q_vector);
5500 5507
5501 if (q_vector->rx_ring) 5508 if (q_vector->rx_ring)
5502 clean_complete &= igb_clean_rx_irq(q_vector, budget); 5509 clean_complete &= igb_clean_rx_irq(q_vector, budget);
@@ -5578,64 +5585,69 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
5578{ 5585{
5579 struct igb_adapter *adapter = q_vector->adapter; 5586 struct igb_adapter *adapter = q_vector->adapter;
5580 struct igb_ring *tx_ring = q_vector->tx_ring; 5587 struct igb_ring *tx_ring = q_vector->tx_ring;
5581 struct net_device *netdev = tx_ring->netdev; 5588 struct igb_buffer *tx_buffer;
5582 struct e1000_hw *hw = &adapter->hw; 5589 union e1000_adv_tx_desc *tx_desc;
5583 struct igb_buffer *buffer_info;
5584 union e1000_adv_tx_desc *tx_desc, *eop_desc;
5585 unsigned int total_bytes = 0, total_packets = 0; 5590 unsigned int total_bytes = 0, total_packets = 0;
5586 unsigned int i, eop, count = 0; 5591 unsigned int budget = q_vector->tx_work_limit;
5587 bool cleaned = false; 5592 u16 i = tx_ring->next_to_clean;
5588 5593
5589 i = tx_ring->next_to_clean; 5594 if (test_bit(__IGB_DOWN, &adapter->state))
5590 eop = tx_ring->buffer_info[i].next_to_watch; 5595 return true;
5591 eop_desc = IGB_TX_DESC(tx_ring, eop);
5592 5596
5593 while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) && 5597 tx_buffer = &tx_ring->buffer_info[i];
5594 (count < tx_ring->count)) { 5598 tx_desc = IGB_TX_DESC(tx_ring, i);
5595 rmb(); /* read buffer_info after eop_desc status */
5596 for (cleaned = false; !cleaned; count++) {
5597 tx_desc = IGB_TX_DESC(tx_ring, i);
5598 buffer_info = &tx_ring->buffer_info[i];
5599 cleaned = (i == eop);
5600 5599
5601 if (buffer_info->skb) { 5600 for (; budget; budget--) {
5602 total_bytes += buffer_info->bytecount; 5601 u16 eop = tx_buffer->next_to_watch;
5603 /* gso_segs is currently only valid for tcp */ 5602 union e1000_adv_tx_desc *eop_desc;
5604 total_packets += buffer_info->gso_segs; 5603
5605 igb_tx_hwtstamp(q_vector, buffer_info); 5604 eop_desc = IGB_TX_DESC(tx_ring, eop);
5606 } 5605
5606 /* if DD is not set pending work has not been completed */
5607 if (!(eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)))
5608 break;
5609
5610 /* prevent any other reads prior to eop_desc being verified */
5611 rmb();
5607 5612
5608 igb_unmap_and_free_tx_resource(tx_ring, buffer_info); 5613 do {
5609 tx_desc->wb.status = 0; 5614 tx_desc->wb.status = 0;
5615 if (likely(tx_desc == eop_desc)) {
5616 eop_desc = NULL;
5617
5618 total_bytes += tx_buffer->bytecount;
5619 total_packets += tx_buffer->gso_segs;
5620 igb_tx_hwtstamp(q_vector, tx_buffer);
5621 }
5622
5623 igb_unmap_and_free_tx_resource(tx_ring, tx_buffer);
5610 5624
5625 tx_buffer++;
5626 tx_desc++;
5611 i++; 5627 i++;
5612 if (i == tx_ring->count) 5628 if (unlikely(i == tx_ring->count)) {
5613 i = 0; 5629 i = 0;
5614 } 5630 tx_buffer = tx_ring->buffer_info;
5615 eop = tx_ring->buffer_info[i].next_to_watch; 5631 tx_desc = IGB_TX_DESC(tx_ring, 0);
5616 eop_desc = IGB_TX_DESC(tx_ring, eop); 5632 }
5633 } while (eop_desc);
5617 } 5634 }
5618 5635
5619 tx_ring->next_to_clean = i; 5636 tx_ring->next_to_clean = i;
5637 u64_stats_update_begin(&tx_ring->tx_syncp);
5638 tx_ring->tx_stats.bytes += total_bytes;
5639 tx_ring->tx_stats.packets += total_packets;
5640 u64_stats_update_end(&tx_ring->tx_syncp);
5641 tx_ring->total_bytes += total_bytes;
5642 tx_ring->total_packets += total_packets;
5620 5643
5621 if (unlikely(count && 5644 if (tx_ring->detect_tx_hung) {
5622 netif_carrier_ok(netdev) && 5645 struct e1000_hw *hw = &adapter->hw;
5623 igb_desc_unused(tx_ring) >= IGB_TX_QUEUE_WAKE)) { 5646 u16 eop = tx_ring->buffer_info[i].next_to_watch;
5624 /* Make sure that anybody stopping the queue after this 5647 union e1000_adv_tx_desc *eop_desc;
5625 * sees the new next_to_clean.
5626 */
5627 smp_mb();
5628 if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) &&
5629 !(test_bit(__IGB_DOWN, &adapter->state))) {
5630 netif_wake_subqueue(netdev, tx_ring->queue_index);
5631 5648
5632 u64_stats_update_begin(&tx_ring->tx_syncp); 5649 eop_desc = IGB_TX_DESC(tx_ring, eop);
5633 tx_ring->tx_stats.restart_queue++;
5634 u64_stats_update_end(&tx_ring->tx_syncp);
5635 }
5636 }
5637 5650
5638 if (tx_ring->detect_tx_hung) {
5639 /* Detect a transmit hang in hardware, this serializes the 5651 /* Detect a transmit hang in hardware, this serializes the
5640 * check with the clearing of time_stamp and movement of i */ 5652 * check with the clearing of time_stamp and movement of i */
5641 tx_ring->detect_tx_hung = false; 5653 tx_ring->detect_tx_hung = false;
@@ -5666,16 +5678,34 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
5666 eop, 5678 eop,
5667 jiffies, 5679 jiffies,
5668 eop_desc->wb.status); 5680 eop_desc->wb.status);
5669 netif_stop_subqueue(netdev, tx_ring->queue_index); 5681 netif_stop_subqueue(tx_ring->netdev,
5682 tx_ring->queue_index);
5683
5684 /* we are about to reset, no point in enabling stuff */
5685 return true;
5670 } 5686 }
5671 } 5687 }
5672 tx_ring->total_bytes += total_bytes; 5688
5673 tx_ring->total_packets += total_packets; 5689 if (unlikely(total_packets &&
5674 u64_stats_update_begin(&tx_ring->tx_syncp); 5690 netif_carrier_ok(tx_ring->netdev) &&
5675 tx_ring->tx_stats.bytes += total_bytes; 5691 igb_desc_unused(tx_ring) >= IGB_TX_QUEUE_WAKE)) {
5676 tx_ring->tx_stats.packets += total_packets; 5692 /* Make sure that anybody stopping the queue after this
5677 u64_stats_update_end(&tx_ring->tx_syncp); 5693 * sees the new next_to_clean.
5678 return count < tx_ring->count; 5694 */
5695 smp_mb();
5696 if (__netif_subqueue_stopped(tx_ring->netdev,
5697 tx_ring->queue_index) &&
5698 !(test_bit(__IGB_DOWN, &adapter->state))) {
5699 netif_wake_subqueue(tx_ring->netdev,
5700 tx_ring->queue_index);
5701
5702 u64_stats_update_begin(&tx_ring->tx_syncp);
5703 tx_ring->tx_stats.restart_queue++;
5704 u64_stats_update_end(&tx_ring->tx_syncp);
5705 }
5706 }
5707
5708 return !!budget;
5679} 5709}
5680 5710
5681static inline void igb_rx_checksum(struct igb_ring *ring, 5711static inline void igb_rx_checksum(struct igb_ring *ring,