diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2011-10-05 09:35:24 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-10-07 01:46:55 -0400 |
commit | 13fde97a48b622a192ae7d0a8011248be891cdd4 (patch) | |
tree | 99be7848bab986104caa2221ba3abfc59e46da57 /drivers | |
parent | b64e9dd5d04561c2cee7e9d9d70bd6d45cc01e7c (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.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb_ethtool.c | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb_main.c | 136 |
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 *); | |||
136 | static void igb_update_dca(struct igb_q_vector *); | 136 | static void igb_update_dca(struct igb_q_vector *); |
137 | static void igb_setup_dca(struct igb_adapter *); | 137 | static void igb_setup_dca(struct igb_adapter *); |
138 | #endif /* CONFIG_IGB_DCA */ | 138 | #endif /* CONFIG_IGB_DCA */ |
139 | static bool igb_clean_tx_irq(struct igb_q_vector *); | ||
140 | static int igb_poll(struct napi_struct *, int); | 139 | static int igb_poll(struct napi_struct *, int); |
140 | static bool igb_clean_tx_irq(struct igb_q_vector *); | ||
141 | static bool igb_clean_rx_irq(struct igb_q_vector *, int); | 141 | static bool igb_clean_rx_irq(struct igb_q_vector *, int); |
142 | static int igb_ioctl(struct net_device *, struct ifreq *, int cmd); | 142 | static int igb_ioctl(struct net_device *, struct ifreq *, int cmd); |
143 | static void igb_tx_timeout(struct net_device *); | 143 | static 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 | ||
5681 | static inline void igb_rx_checksum(struct igb_ring *ring, | 5711 | static inline void igb_rx_checksum(struct igb_ring *ring, |