aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Duyck <aduyck@mirantis.com>2016-03-07 12:30:03 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2016-04-05 04:58:53 -0400
commita619afe814453300684f1d5a6478d67f791bc723 (patch)
treea94b271a6360b3837990f6eba1780ddad28cdae7
parentf2edaaaa392bc21c24f532ea9bcc952a54a22367 (diff)
i40e/i40evf: Add support for bulk free in Tx cleanup
This patch enables bulk Tx clean for skbs. In order to enable it we need to pass the napi_budget value as that is used to determine if we are truly running in NAPI mode or if we are simply calling the routine from netpoll with a budget of 0. In order to avoid adding too many more variables I thought it best to pass the VSI directly in a fashion similar to what we do on igb and ixgbe with the q_vector. Signed-off-by: Alexander Duyck <aduyck@mirantis.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.c20
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_txrx.c20
2 files changed, 22 insertions, 18 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index 8fb2a966d70e..01cff073f8db 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -636,19 +636,21 @@ u32 i40e_get_tx_pending(struct i40e_ring *ring, bool in_sw)
636 636
637/** 637/**
638 * i40e_clean_tx_irq - Reclaim resources after transmit completes 638 * i40e_clean_tx_irq - Reclaim resources after transmit completes
639 * @tx_ring: tx ring to clean 639 * @vsi: the VSI we care about
640 * @budget: how many cleans we're allowed 640 * @tx_ring: Tx ring to clean
641 * @napi_budget: Used to determine if we are in netpoll
641 * 642 *
642 * Returns true if there's any budget left (e.g. the clean is finished) 643 * Returns true if there's any budget left (e.g. the clean is finished)
643 **/ 644 **/
644static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget) 645static bool i40e_clean_tx_irq(struct i40e_vsi *vsi,
646 struct i40e_ring *tx_ring, int napi_budget)
645{ 647{
646 u16 i = tx_ring->next_to_clean; 648 u16 i = tx_ring->next_to_clean;
647 struct i40e_tx_buffer *tx_buf; 649 struct i40e_tx_buffer *tx_buf;
648 struct i40e_tx_desc *tx_head; 650 struct i40e_tx_desc *tx_head;
649 struct i40e_tx_desc *tx_desc; 651 struct i40e_tx_desc *tx_desc;
650 unsigned int total_packets = 0; 652 unsigned int total_bytes = 0, total_packets = 0;
651 unsigned int total_bytes = 0; 653 unsigned int budget = vsi->work_limit;
652 654
653 tx_buf = &tx_ring->tx_bi[i]; 655 tx_buf = &tx_ring->tx_bi[i];
654 tx_desc = I40E_TX_DESC(tx_ring, i); 656 tx_desc = I40E_TX_DESC(tx_ring, i);
@@ -678,7 +680,7 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget)
678 total_packets += tx_buf->gso_segs; 680 total_packets += tx_buf->gso_segs;
679 681
680 /* free the skb */ 682 /* free the skb */
681 dev_consume_skb_any(tx_buf->skb); 683 napi_consume_skb(tx_buf->skb, napi_budget);
682 684
683 /* unmap skb header data */ 685 /* unmap skb header data */
684 dma_unmap_single(tx_ring->dev, 686 dma_unmap_single(tx_ring->dev,
@@ -749,7 +751,7 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget)
749 751
750 if (budget && 752 if (budget &&
751 ((j / (WB_STRIDE + 1)) == 0) && (j != 0) && 753 ((j / (WB_STRIDE + 1)) == 0) && (j != 0) &&
752 !test_bit(__I40E_DOWN, &tx_ring->vsi->state) && 754 !test_bit(__I40E_DOWN, &vsi->state) &&
753 (I40E_DESC_UNUSED(tx_ring) != tx_ring->count)) 755 (I40E_DESC_UNUSED(tx_ring) != tx_ring->count))
754 tx_ring->arm_wb = true; 756 tx_ring->arm_wb = true;
755 } 757 }
@@ -767,7 +769,7 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget)
767 smp_mb(); 769 smp_mb();
768 if (__netif_subqueue_stopped(tx_ring->netdev, 770 if (__netif_subqueue_stopped(tx_ring->netdev,
769 tx_ring->queue_index) && 771 tx_ring->queue_index) &&
770 !test_bit(__I40E_DOWN, &tx_ring->vsi->state)) { 772 !test_bit(__I40E_DOWN, &vsi->state)) {
771 netif_wake_subqueue(tx_ring->netdev, 773 netif_wake_subqueue(tx_ring->netdev,
772 tx_ring->queue_index); 774 tx_ring->queue_index);
773 ++tx_ring->tx_stats.restart_queue; 775 ++tx_ring->tx_stats.restart_queue;
@@ -1975,7 +1977,7 @@ int i40e_napi_poll(struct napi_struct *napi, int budget)
1975 * budget and be more aggressive about cleaning up the Tx descriptors. 1977 * budget and be more aggressive about cleaning up the Tx descriptors.
1976 */ 1978 */
1977 i40e_for_each_ring(ring, q_vector->tx) { 1979 i40e_for_each_ring(ring, q_vector->tx) {
1978 if (!i40e_clean_tx_irq(ring, vsi->work_limit)) { 1980 if (!i40e_clean_tx_irq(vsi, ring, budget)) {
1979 clean_complete = false; 1981 clean_complete = false;
1980 continue; 1982 continue;
1981 } 1983 }
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
index 839a6df62f72..9e911363c11b 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
@@ -155,19 +155,21 @@ u32 i40evf_get_tx_pending(struct i40e_ring *ring, bool in_sw)
155 155
156/** 156/**
157 * i40e_clean_tx_irq - Reclaim resources after transmit completes 157 * i40e_clean_tx_irq - Reclaim resources after transmit completes
158 * @tx_ring: tx ring to clean 158 * @vsi: the VSI we care about
159 * @budget: how many cleans we're allowed 159 * @tx_ring: Tx ring to clean
160 * @napi_budget: Used to determine if we are in netpoll
160 * 161 *
161 * Returns true if there's any budget left (e.g. the clean is finished) 162 * Returns true if there's any budget left (e.g. the clean is finished)
162 **/ 163 **/
163static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget) 164static bool i40e_clean_tx_irq(struct i40e_vsi *vsi,
165 struct i40e_ring *tx_ring, int napi_budget)
164{ 166{
165 u16 i = tx_ring->next_to_clean; 167 u16 i = tx_ring->next_to_clean;
166 struct i40e_tx_buffer *tx_buf; 168 struct i40e_tx_buffer *tx_buf;
167 struct i40e_tx_desc *tx_head; 169 struct i40e_tx_desc *tx_head;
168 struct i40e_tx_desc *tx_desc; 170 struct i40e_tx_desc *tx_desc;
169 unsigned int total_packets = 0; 171 unsigned int total_bytes = 0, total_packets = 0;
170 unsigned int total_bytes = 0; 172 unsigned int budget = vsi->work_limit;
171 173
172 tx_buf = &tx_ring->tx_bi[i]; 174 tx_buf = &tx_ring->tx_bi[i];
173 tx_desc = I40E_TX_DESC(tx_ring, i); 175 tx_desc = I40E_TX_DESC(tx_ring, i);
@@ -197,7 +199,7 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget)
197 total_packets += tx_buf->gso_segs; 199 total_packets += tx_buf->gso_segs;
198 200
199 /* free the skb */ 201 /* free the skb */
200 dev_kfree_skb_any(tx_buf->skb); 202 napi_consume_skb(tx_buf->skb, napi_budget);
201 203
202 /* unmap skb header data */ 204 /* unmap skb header data */
203 dma_unmap_single(tx_ring->dev, 205 dma_unmap_single(tx_ring->dev,
@@ -267,7 +269,7 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget)
267 269
268 if (budget && 270 if (budget &&
269 ((j / (WB_STRIDE + 1)) == 0) && (j > 0) && 271 ((j / (WB_STRIDE + 1)) == 0) && (j > 0) &&
270 !test_bit(__I40E_DOWN, &tx_ring->vsi->state) && 272 !test_bit(__I40E_DOWN, &vsi->state) &&
271 (I40E_DESC_UNUSED(tx_ring) != tx_ring->count)) 273 (I40E_DESC_UNUSED(tx_ring) != tx_ring->count))
272 tx_ring->arm_wb = true; 274 tx_ring->arm_wb = true;
273 } 275 }
@@ -285,7 +287,7 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget)
285 smp_mb(); 287 smp_mb();
286 if (__netif_subqueue_stopped(tx_ring->netdev, 288 if (__netif_subqueue_stopped(tx_ring->netdev,
287 tx_ring->queue_index) && 289 tx_ring->queue_index) &&
288 !test_bit(__I40E_DOWN, &tx_ring->vsi->state)) { 290 !test_bit(__I40E_DOWN, &vsi->state)) {
289 netif_wake_subqueue(tx_ring->netdev, 291 netif_wake_subqueue(tx_ring->netdev,
290 tx_ring->queue_index); 292 tx_ring->queue_index);
291 ++tx_ring->tx_stats.restart_queue; 293 ++tx_ring->tx_stats.restart_queue;
@@ -1411,7 +1413,7 @@ int i40evf_napi_poll(struct napi_struct *napi, int budget)
1411 * budget and be more aggressive about cleaning up the Tx descriptors. 1413 * budget and be more aggressive about cleaning up the Tx descriptors.
1412 */ 1414 */
1413 i40e_for_each_ring(ring, q_vector->tx) { 1415 i40e_for_each_ring(ring, q_vector->tx) {
1414 if (!i40e_clean_tx_irq(ring, vsi->work_limit)) { 1416 if (!i40e_clean_tx_irq(vsi, ring, budget)) {
1415 clean_complete = false; 1417 clean_complete = false;
1416 continue; 1418 continue;
1417 } 1419 }