aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2012-09-13 02:28:01 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2012-09-22 05:50:24 -0400
commitf4128785b8f3f1fd7dc81b972661003d639a4676 (patch)
tree8d34f8c4b12cf6032fe135d073319c94af96c79c /drivers
parentf33005a637bffca72fe373d1e91f2dfbc8fae157 (diff)
igb: Change Tx cleanup loop to do/while instead of for
This change makes it so that Tx cleanup is done in a do/while loop instead of a for loop. The main motivation behind this is the fact that we should never be invoked with a budget less than 1 so we can skip checking the budget before processing the first descriptor. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index c9997d83de07..91f542c50f61 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -5690,7 +5690,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
5690 struct igb_adapter *adapter = q_vector->adapter; 5690 struct igb_adapter *adapter = q_vector->adapter;
5691 struct igb_ring *tx_ring = q_vector->tx.ring; 5691 struct igb_ring *tx_ring = q_vector->tx.ring;
5692 struct igb_tx_buffer *tx_buffer; 5692 struct igb_tx_buffer *tx_buffer;
5693 union e1000_adv_tx_desc *tx_desc, *eop_desc; 5693 union e1000_adv_tx_desc *tx_desc;
5694 unsigned int total_bytes = 0, total_packets = 0; 5694 unsigned int total_bytes = 0, total_packets = 0;
5695 unsigned int budget = q_vector->tx.work_limit; 5695 unsigned int budget = q_vector->tx.work_limit;
5696 unsigned int i = tx_ring->next_to_clean; 5696 unsigned int i = tx_ring->next_to_clean;
@@ -5702,16 +5702,16 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
5702 tx_desc = IGB_TX_DESC(tx_ring, i); 5702 tx_desc = IGB_TX_DESC(tx_ring, i);
5703 i -= tx_ring->count; 5703 i -= tx_ring->count;
5704 5704
5705 for (; budget; budget--) { 5705 do {
5706 eop_desc = tx_buffer->next_to_watch; 5706 union e1000_adv_tx_desc *eop_desc = tx_buffer->next_to_watch;
5707
5708 /* prevent any other reads prior to eop_desc */
5709 rmb();
5710 5707
5711 /* if next_to_watch is not set then there is no work pending */ 5708 /* if next_to_watch is not set then there is no work pending */
5712 if (!eop_desc) 5709 if (!eop_desc)
5713 break; 5710 break;
5714 5711
5712 /* prevent any other reads prior to eop_desc */
5713 rmb();
5714
5715 /* if DD is not set pending work has not been completed */ 5715 /* if DD is not set pending work has not been completed */
5716 if (!(eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD))) 5716 if (!(eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)))
5717 break; 5717 break;
@@ -5767,7 +5767,13 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
5767 tx_buffer = tx_ring->tx_buffer_info; 5767 tx_buffer = tx_ring->tx_buffer_info;
5768 tx_desc = IGB_TX_DESC(tx_ring, 0); 5768 tx_desc = IGB_TX_DESC(tx_ring, 0);
5769 } 5769 }
5770 } 5770
5771 /* issue prefetch for next Tx descriptor */
5772 prefetch(tx_desc);
5773
5774 /* update budget accounting */
5775 budget--;
5776 } while (likely(budget));
5771 5777
5772 netdev_tx_completed_queue(txring_txq(tx_ring), 5778 netdev_tx_completed_queue(txring_txq(tx_ring),
5773 total_packets, total_bytes); 5779 total_packets, total_bytes);
@@ -5783,12 +5789,10 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
5783 if (test_bit(IGB_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) { 5789 if (test_bit(IGB_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags)) {
5784 struct e1000_hw *hw = &adapter->hw; 5790 struct e1000_hw *hw = &adapter->hw;
5785 5791
5786 eop_desc = tx_buffer->next_to_watch;
5787
5788 /* Detect a transmit hang in hardware, this serializes the 5792 /* Detect a transmit hang in hardware, this serializes the
5789 * check with the clearing of time_stamp and movement of i */ 5793 * check with the clearing of time_stamp and movement of i */
5790 clear_bit(IGB_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags); 5794 clear_bit(IGB_RING_FLAG_TX_DETECT_HANG, &tx_ring->flags);
5791 if (eop_desc && 5795 if (tx_buffer->next_to_watch &&
5792 time_after(jiffies, tx_buffer->time_stamp + 5796 time_after(jiffies, tx_buffer->time_stamp +
5793 (adapter->tx_timeout_factor * HZ)) && 5797 (adapter->tx_timeout_factor * HZ)) &&
5794 !(rd32(E1000_STATUS) & E1000_STATUS_TXOFF)) { 5798 !(rd32(E1000_STATUS) & E1000_STATUS_TXOFF)) {
@@ -5812,9 +5816,9 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
5812 tx_ring->next_to_use, 5816 tx_ring->next_to_use,
5813 tx_ring->next_to_clean, 5817 tx_ring->next_to_clean,
5814 tx_buffer->time_stamp, 5818 tx_buffer->time_stamp,
5815 eop_desc, 5819 tx_buffer->next_to_watch,
5816 jiffies, 5820 jiffies,
5817 eop_desc->wb.status); 5821 tx_buffer->next_to_watch->wb.status);
5818 netif_stop_subqueue(tx_ring->netdev, 5822 netif_stop_subqueue(tx_ring->netdev,
5819 tx_ring->queue_index); 5823 tx_ring->queue_index);
5820 5824