diff options
author | Jesse Brandeburg <jesse.brandeburg@intel.com> | 2015-09-24 19:35:47 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2015-10-16 07:33:46 -0400 |
commit | 32b3e08fff60494cd1d281a39b51583edfd2b18f (patch) | |
tree | 919cabae884fcd622013afc26c4695712576a4da | |
parent | 7709b4c1fff39972b6a1b6183b593c43f1a555fb (diff) |
drivers/net/intel: use napi_complete_done()
As per Eric Dumazet's previous patches:
(see commit (24d2e4a50737) - tg3: use napi_complete_done())
Quoting verbatim:
Using napi_complete_done() instead of napi_complete() allows
us to use /sys/class/net/ethX/gro_flush_timeout
GRO layer can aggregate more packets if the flush is delayed a bit,
without having to set too big coalescing parameters that impact
latencies.
</end quote>
Tested
configuration: low latency via ethtool -C ethx adaptive-rx off
rx-usecs 10 adaptive-tx off tx-usecs 15
workload: streaming rx using netperf TCP_MAERTS
igb:
MIGRATED TCP MAERTS TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.0.0.1 () port 0 AF_INET : demo
...
Interim result: 941.48 10^6bits/s over 1.000 seconds ending at 1440193171.589
Alignment Offset Bytes Bytes Recvs Bytes Sends
Local Remote Local Remote Xfered Per Per
Recv Send Recv Send Recv (avg) Send (avg)
8 8 0 0 1176930056 1475.36 797726 16384.00 71905
MIGRATED TCP MAERTS TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.0.0.1 () port 0 AF_INET : demo
...
Interim result: 941.49 10^6bits/s over 0.997 seconds ending at 1440193142.763
Alignment Offset Bytes Bytes Recvs Bytes Sends
Local Remote Local Remote Xfered Per Per
Recv Send Recv Send Recv (avg) Send (avg)
8 8 0 0 1175182320 50476.00 23282 16384.00 71816
i40e:
Hard to test because the traffic is incoming so fast (24Gb/s) that GRO
always receives 87kB, even at the highest interrupt rate.
Other drivers were only compile tested.
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.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/e1000/e1000_main.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/netdev.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/fm10k/fm10k_main.c | 21 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_txrx.c | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb_main.c | 17 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/igbvf/netdev.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 14 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 14 |
9 files changed, 55 insertions, 33 deletions
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 74dc15055971..fd7be860c201 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c | |||
@@ -3820,7 +3820,7 @@ static int e1000_clean(struct napi_struct *napi, int budget) | |||
3820 | if (work_done < budget) { | 3820 | if (work_done < budget) { |
3821 | if (likely(adapter->itr_setting & 3)) | 3821 | if (likely(adapter->itr_setting & 3)) |
3822 | e1000_set_itr(adapter); | 3822 | e1000_set_itr(adapter); |
3823 | napi_complete(napi); | 3823 | napi_complete_done(napi, work_done); |
3824 | if (!test_bit(__E1000_DOWN, &adapter->flags)) | 3824 | if (!test_bit(__E1000_DOWN, &adapter->flags)) |
3825 | e1000_irq_enable(adapter); | 3825 | e1000_irq_enable(adapter); |
3826 | } | 3826 | } |
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 2e2ddec04a50..0a854a47d31a 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c | |||
@@ -2693,7 +2693,7 @@ static int e1000e_poll(struct napi_struct *napi, int weight) | |||
2693 | if (work_done < weight) { | 2693 | if (work_done < weight) { |
2694 | if (adapter->itr_setting & 3) | 2694 | if (adapter->itr_setting & 3) |
2695 | e1000_set_itr(adapter); | 2695 | e1000_set_itr(adapter); |
2696 | napi_complete(napi); | 2696 | napi_complete_done(napi, work_done); |
2697 | if (!test_bit(__E1000_DOWN, &adapter->state)) { | 2697 | if (!test_bit(__E1000_DOWN, &adapter->state)) { |
2698 | if (adapter->msix_entries) | 2698 | if (adapter->msix_entries) |
2699 | ew32(IMS, adapter->rx_ring->ims_val); | 2699 | ew32(IMS, adapter->rx_ring->ims_val); |
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_main.c b/drivers/net/ethernet/intel/fm10k/fm10k_main.c index 537d81a6d738..e76a44cf330c 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c | |||
@@ -593,9 +593,9 @@ static void fm10k_receive_skb(struct fm10k_q_vector *q_vector, | |||
593 | napi_gro_receive(&q_vector->napi, skb); | 593 | napi_gro_receive(&q_vector->napi, skb); |
594 | } | 594 | } |
595 | 595 | ||
596 | static bool fm10k_clean_rx_irq(struct fm10k_q_vector *q_vector, | 596 | static int fm10k_clean_rx_irq(struct fm10k_q_vector *q_vector, |
597 | struct fm10k_ring *rx_ring, | 597 | struct fm10k_ring *rx_ring, |
598 | int budget) | 598 | int budget) |
599 | { | 599 | { |
600 | struct sk_buff *skb = rx_ring->skb; | 600 | struct sk_buff *skb = rx_ring->skb; |
601 | unsigned int total_bytes = 0, total_packets = 0; | 601 | unsigned int total_bytes = 0, total_packets = 0; |
@@ -662,7 +662,7 @@ static bool fm10k_clean_rx_irq(struct fm10k_q_vector *q_vector, | |||
662 | q_vector->rx.total_packets += total_packets; | 662 | q_vector->rx.total_packets += total_packets; |
663 | q_vector->rx.total_bytes += total_bytes; | 663 | q_vector->rx.total_bytes += total_bytes; |
664 | 664 | ||
665 | return total_packets < budget; | 665 | return total_packets; |
666 | } | 666 | } |
667 | 667 | ||
668 | #define VXLAN_HLEN (sizeof(struct udphdr) + 8) | 668 | #define VXLAN_HLEN (sizeof(struct udphdr) + 8) |
@@ -1422,7 +1422,7 @@ static int fm10k_poll(struct napi_struct *napi, int budget) | |||
1422 | struct fm10k_q_vector *q_vector = | 1422 | struct fm10k_q_vector *q_vector = |
1423 | container_of(napi, struct fm10k_q_vector, napi); | 1423 | container_of(napi, struct fm10k_q_vector, napi); |
1424 | struct fm10k_ring *ring; | 1424 | struct fm10k_ring *ring; |
1425 | int per_ring_budget; | 1425 | int per_ring_budget, work_done = 0; |
1426 | bool clean_complete = true; | 1426 | bool clean_complete = true; |
1427 | 1427 | ||
1428 | fm10k_for_each_ring(ring, q_vector->tx) | 1428 | fm10k_for_each_ring(ring, q_vector->tx) |
@@ -1436,16 +1436,19 @@ static int fm10k_poll(struct napi_struct *napi, int budget) | |||
1436 | else | 1436 | else |
1437 | per_ring_budget = budget; | 1437 | per_ring_budget = budget; |
1438 | 1438 | ||
1439 | fm10k_for_each_ring(ring, q_vector->rx) | 1439 | fm10k_for_each_ring(ring, q_vector->rx) { |
1440 | clean_complete &= fm10k_clean_rx_irq(q_vector, ring, | 1440 | int work = fm10k_clean_rx_irq(q_vector, ring, per_ring_budget); |
1441 | per_ring_budget); | 1441 | |
1442 | work_done += work; | ||
1443 | clean_complete &= !!(work < per_ring_budget); | ||
1444 | } | ||
1442 | 1445 | ||
1443 | /* If all work not completed, return budget and keep polling */ | 1446 | /* If all work not completed, return budget and keep polling */ |
1444 | if (!clean_complete) | 1447 | if (!clean_complete) |
1445 | return budget; | 1448 | return budget; |
1446 | 1449 | ||
1447 | /* all work done, exit the polling mode */ | 1450 | /* all work done, exit the polling mode */ |
1448 | napi_complete(napi); | 1451 | napi_complete_done(napi, work_done); |
1449 | 1452 | ||
1450 | /* re-enable the q_vector */ | 1453 | /* re-enable the q_vector */ |
1451 | fm10k_qv_enable(q_vector); | 1454 | fm10k_qv_enable(q_vector); |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index e1fac3b1e088..512707c2898e 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c | |||
@@ -1825,7 +1825,7 @@ int i40e_napi_poll(struct napi_struct *napi, int budget) | |||
1825 | bool clean_complete = true; | 1825 | bool clean_complete = true; |
1826 | bool arm_wb = false; | 1826 | bool arm_wb = false; |
1827 | int budget_per_ring; | 1827 | int budget_per_ring; |
1828 | int cleaned; | 1828 | int work_done = 0; |
1829 | 1829 | ||
1830 | if (test_bit(__I40E_DOWN, &vsi->state)) { | 1830 | if (test_bit(__I40E_DOWN, &vsi->state)) { |
1831 | napi_complete(napi); | 1831 | napi_complete(napi); |
@@ -1851,10 +1851,14 @@ int i40e_napi_poll(struct napi_struct *napi, int budget) | |||
1851 | budget_per_ring = max(budget/q_vector->num_ringpairs, 1); | 1851 | budget_per_ring = max(budget/q_vector->num_ringpairs, 1); |
1852 | 1852 | ||
1853 | i40e_for_each_ring(ring, q_vector->rx) { | 1853 | i40e_for_each_ring(ring, q_vector->rx) { |
1854 | int cleaned; | ||
1855 | |||
1854 | if (ring_is_ps_enabled(ring)) | 1856 | if (ring_is_ps_enabled(ring)) |
1855 | cleaned = i40e_clean_rx_irq_ps(ring, budget_per_ring); | 1857 | cleaned = i40e_clean_rx_irq_ps(ring, budget_per_ring); |
1856 | else | 1858 | else |
1857 | cleaned = i40e_clean_rx_irq_1buf(ring, budget_per_ring); | 1859 | cleaned = i40e_clean_rx_irq_1buf(ring, budget_per_ring); |
1860 | |||
1861 | work_done += cleaned; | ||
1858 | /* if we didn't clean as many as budgeted, we must be done */ | 1862 | /* if we didn't clean as many as budgeted, we must be done */ |
1859 | clean_complete &= (budget_per_ring != cleaned); | 1863 | clean_complete &= (budget_per_ring != cleaned); |
1860 | } | 1864 | } |
@@ -1871,7 +1875,7 @@ tx_only: | |||
1871 | q_vector->arm_wb_state = false; | 1875 | q_vector->arm_wb_state = false; |
1872 | 1876 | ||
1873 | /* Work is done so exit the polling mode and re-enable the interrupt */ | 1877 | /* Work is done so exit the polling mode and re-enable the interrupt */ |
1874 | napi_complete(napi); | 1878 | napi_complete_done(napi, work_done); |
1875 | if (vsi->back->flags & I40E_FLAG_MSIX_ENABLED) { | 1879 | if (vsi->back->flags & I40E_FLAG_MSIX_ENABLED) { |
1876 | i40e_update_enable_itr(vsi, q_vector); | 1880 | i40e_update_enable_itr(vsi, q_vector); |
1877 | } else { /* Legacy mode */ | 1881 | } else { /* Legacy mode */ |
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c index 5d3a8bd91abf..97493a4164eb 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c | |||
@@ -1266,7 +1266,7 @@ int i40evf_napi_poll(struct napi_struct *napi, int budget) | |||
1266 | bool clean_complete = true; | 1266 | bool clean_complete = true; |
1267 | bool arm_wb = false; | 1267 | bool arm_wb = false; |
1268 | int budget_per_ring; | 1268 | int budget_per_ring; |
1269 | int cleaned; | 1269 | int work_done = 0; |
1270 | 1270 | ||
1271 | if (test_bit(__I40E_DOWN, &vsi->state)) { | 1271 | if (test_bit(__I40E_DOWN, &vsi->state)) { |
1272 | napi_complete(napi); | 1272 | napi_complete(napi); |
@@ -1292,10 +1292,14 @@ int i40evf_napi_poll(struct napi_struct *napi, int budget) | |||
1292 | budget_per_ring = max(budget/q_vector->num_ringpairs, 1); | 1292 | budget_per_ring = max(budget/q_vector->num_ringpairs, 1); |
1293 | 1293 | ||
1294 | i40e_for_each_ring(ring, q_vector->rx) { | 1294 | i40e_for_each_ring(ring, q_vector->rx) { |
1295 | int cleaned; | ||
1296 | |||
1295 | if (ring_is_ps_enabled(ring)) | 1297 | if (ring_is_ps_enabled(ring)) |
1296 | cleaned = i40e_clean_rx_irq_ps(ring, budget_per_ring); | 1298 | cleaned = i40e_clean_rx_irq_ps(ring, budget_per_ring); |
1297 | else | 1299 | else |
1298 | cleaned = i40e_clean_rx_irq_1buf(ring, budget_per_ring); | 1300 | cleaned = i40e_clean_rx_irq_1buf(ring, budget_per_ring); |
1301 | |||
1302 | work_done += cleaned; | ||
1299 | /* if we didn't clean as many as budgeted, we must be done */ | 1303 | /* if we didn't clean as many as budgeted, we must be done */ |
1300 | clean_complete &= (budget_per_ring != cleaned); | 1304 | clean_complete &= (budget_per_ring != cleaned); |
1301 | } | 1305 | } |
@@ -1312,7 +1316,7 @@ tx_only: | |||
1312 | q_vector->arm_wb_state = false; | 1316 | q_vector->arm_wb_state = false; |
1313 | 1317 | ||
1314 | /* Work is done so exit the polling mode and re-enable the interrupt */ | 1318 | /* Work is done so exit the polling mode and re-enable the interrupt */ |
1315 | napi_complete(napi); | 1319 | napi_complete_done(napi, work_done); |
1316 | i40e_update_enable_itr(vsi, q_vector); | 1320 | i40e_update_enable_itr(vsi, q_vector); |
1317 | return 0; | 1321 | return 0; |
1318 | } | 1322 | } |
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 7e6267503790..ea7b09887245 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c | |||
@@ -151,7 +151,7 @@ static void igb_setup_dca(struct igb_adapter *); | |||
151 | #endif /* CONFIG_IGB_DCA */ | 151 | #endif /* CONFIG_IGB_DCA */ |
152 | static int igb_poll(struct napi_struct *, int); | 152 | static int igb_poll(struct napi_struct *, int); |
153 | static bool igb_clean_tx_irq(struct igb_q_vector *); | 153 | static bool igb_clean_tx_irq(struct igb_q_vector *); |
154 | static bool igb_clean_rx_irq(struct igb_q_vector *, int); | 154 | static int igb_clean_rx_irq(struct igb_q_vector *, int); |
155 | static int igb_ioctl(struct net_device *, struct ifreq *, int cmd); | 155 | static int igb_ioctl(struct net_device *, struct ifreq *, int cmd); |
156 | static void igb_tx_timeout(struct net_device *); | 156 | static void igb_tx_timeout(struct net_device *); |
157 | static void igb_reset_task(struct work_struct *); | 157 | static void igb_reset_task(struct work_struct *); |
@@ -6364,6 +6364,7 @@ static int igb_poll(struct napi_struct *napi, int budget) | |||
6364 | struct igb_q_vector, | 6364 | struct igb_q_vector, |
6365 | napi); | 6365 | napi); |
6366 | bool clean_complete = true; | 6366 | bool clean_complete = true; |
6367 | int work_done = 0; | ||
6367 | 6368 | ||
6368 | #ifdef CONFIG_IGB_DCA | 6369 | #ifdef CONFIG_IGB_DCA |
6369 | if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED) | 6370 | if (q_vector->adapter->flags & IGB_FLAG_DCA_ENABLED) |
@@ -6372,15 +6373,19 @@ static int igb_poll(struct napi_struct *napi, int budget) | |||
6372 | if (q_vector->tx.ring) | 6373 | if (q_vector->tx.ring) |
6373 | clean_complete = igb_clean_tx_irq(q_vector); | 6374 | clean_complete = igb_clean_tx_irq(q_vector); |
6374 | 6375 | ||
6375 | if (q_vector->rx.ring) | 6376 | if (q_vector->rx.ring) { |
6376 | clean_complete &= igb_clean_rx_irq(q_vector, budget); | 6377 | int cleaned = igb_clean_rx_irq(q_vector, budget); |
6378 | |||
6379 | work_done += cleaned; | ||
6380 | clean_complete &= (cleaned < budget); | ||
6381 | } | ||
6377 | 6382 | ||
6378 | /* If all work not completed, return budget and keep polling */ | 6383 | /* If all work not completed, return budget and keep polling */ |
6379 | if (!clean_complete) | 6384 | if (!clean_complete) |
6380 | return budget; | 6385 | return budget; |
6381 | 6386 | ||
6382 | /* If not enough Rx work done, exit the polling mode */ | 6387 | /* If not enough Rx work done, exit the polling mode */ |
6383 | napi_complete(napi); | 6388 | napi_complete_done(napi, work_done); |
6384 | igb_ring_irq_enable(q_vector); | 6389 | igb_ring_irq_enable(q_vector); |
6385 | 6390 | ||
6386 | return 0; | 6391 | return 0; |
@@ -6904,7 +6909,7 @@ static void igb_process_skb_fields(struct igb_ring *rx_ring, | |||
6904 | skb->protocol = eth_type_trans(skb, rx_ring->netdev); | 6909 | skb->protocol = eth_type_trans(skb, rx_ring->netdev); |
6905 | } | 6910 | } |
6906 | 6911 | ||
6907 | static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget) | 6912 | static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget) |
6908 | { | 6913 | { |
6909 | struct igb_ring *rx_ring = q_vector->rx.ring; | 6914 | struct igb_ring *rx_ring = q_vector->rx.ring; |
6910 | struct sk_buff *skb = rx_ring->skb; | 6915 | struct sk_buff *skb = rx_ring->skb; |
@@ -6978,7 +6983,7 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget) | |||
6978 | if (cleaned_count) | 6983 | if (cleaned_count) |
6979 | igb_alloc_rx_buffers(rx_ring, cleaned_count); | 6984 | igb_alloc_rx_buffers(rx_ring, cleaned_count); |
6980 | 6985 | ||
6981 | return total_packets < budget; | 6986 | return total_packets; |
6982 | } | 6987 | } |
6983 | 6988 | ||
6984 | static bool igb_alloc_mapped_page(struct igb_ring *rx_ring, | 6989 | static bool igb_alloc_mapped_page(struct igb_ring *rx_ring, |
diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c index e86d41ed9260..297af801f051 100644 --- a/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/drivers/net/ethernet/intel/igbvf/netdev.c | |||
@@ -1211,7 +1211,7 @@ static int igbvf_poll(struct napi_struct *napi, int budget) | |||
1211 | 1211 | ||
1212 | /* If not enough Rx work done, exit the polling mode */ | 1212 | /* If not enough Rx work done, exit the polling mode */ |
1213 | if (work_done < budget) { | 1213 | if (work_done < budget) { |
1214 | napi_complete(napi); | 1214 | napi_complete_done(napi, work_done); |
1215 | 1215 | ||
1216 | if (adapter->requested_itr & 3) | 1216 | if (adapter->requested_itr & 3) |
1217 | igbvf_set_itr(adapter); | 1217 | igbvf_set_itr(adapter); |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 1b2ad39bbfb5..9f8a7fd7a195 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |||
@@ -2775,7 +2775,7 @@ int ixgbe_poll(struct napi_struct *napi, int budget) | |||
2775 | container_of(napi, struct ixgbe_q_vector, napi); | 2775 | container_of(napi, struct ixgbe_q_vector, napi); |
2776 | struct ixgbe_adapter *adapter = q_vector->adapter; | 2776 | struct ixgbe_adapter *adapter = q_vector->adapter; |
2777 | struct ixgbe_ring *ring; | 2777 | struct ixgbe_ring *ring; |
2778 | int per_ring_budget; | 2778 | int per_ring_budget, work_done = 0; |
2779 | bool clean_complete = true; | 2779 | bool clean_complete = true; |
2780 | 2780 | ||
2781 | #ifdef CONFIG_IXGBE_DCA | 2781 | #ifdef CONFIG_IXGBE_DCA |
@@ -2796,9 +2796,13 @@ int ixgbe_poll(struct napi_struct *napi, int budget) | |||
2796 | else | 2796 | else |
2797 | per_ring_budget = budget; | 2797 | per_ring_budget = budget; |
2798 | 2798 | ||
2799 | ixgbe_for_each_ring(ring, q_vector->rx) | 2799 | ixgbe_for_each_ring(ring, q_vector->rx) { |
2800 | clean_complete &= (ixgbe_clean_rx_irq(q_vector, ring, | 2800 | int cleaned = ixgbe_clean_rx_irq(q_vector, ring, |
2801 | per_ring_budget) < per_ring_budget); | 2801 | per_ring_budget); |
2802 | |||
2803 | work_done += cleaned; | ||
2804 | clean_complete &= (cleaned < per_ring_budget); | ||
2805 | } | ||
2802 | 2806 | ||
2803 | ixgbe_qv_unlock_napi(q_vector); | 2807 | ixgbe_qv_unlock_napi(q_vector); |
2804 | /* If all work not completed, return budget and keep polling */ | 2808 | /* If all work not completed, return budget and keep polling */ |
@@ -2806,7 +2810,7 @@ int ixgbe_poll(struct napi_struct *napi, int budget) | |||
2806 | return budget; | 2810 | return budget; |
2807 | 2811 | ||
2808 | /* all work done, exit the polling mode */ | 2812 | /* all work done, exit the polling mode */ |
2809 | napi_complete(napi); | 2813 | napi_complete_done(napi, work_done); |
2810 | if (adapter->rx_itr_setting & 1) | 2814 | if (adapter->rx_itr_setting & 1) |
2811 | ixgbe_set_itr(q_vector); | 2815 | ixgbe_set_itr(q_vector); |
2812 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) | 2816 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) |
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 35da2d74e73e..7570b5c7ccd8 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | |||
@@ -1008,7 +1008,7 @@ static int ixgbevf_poll(struct napi_struct *napi, int budget) | |||
1008 | container_of(napi, struct ixgbevf_q_vector, napi); | 1008 | container_of(napi, struct ixgbevf_q_vector, napi); |
1009 | struct ixgbevf_adapter *adapter = q_vector->adapter; | 1009 | struct ixgbevf_adapter *adapter = q_vector->adapter; |
1010 | struct ixgbevf_ring *ring; | 1010 | struct ixgbevf_ring *ring; |
1011 | int per_ring_budget; | 1011 | int per_ring_budget, work_done = 0; |
1012 | bool clean_complete = true; | 1012 | bool clean_complete = true; |
1013 | 1013 | ||
1014 | ixgbevf_for_each_ring(ring, q_vector->tx) | 1014 | ixgbevf_for_each_ring(ring, q_vector->tx) |
@@ -1027,10 +1027,12 @@ static int ixgbevf_poll(struct napi_struct *napi, int budget) | |||
1027 | else | 1027 | else |
1028 | per_ring_budget = budget; | 1028 | per_ring_budget = budget; |
1029 | 1029 | ||
1030 | ixgbevf_for_each_ring(ring, q_vector->rx) | 1030 | ixgbevf_for_each_ring(ring, q_vector->rx) { |
1031 | clean_complete &= (ixgbevf_clean_rx_irq(q_vector, ring, | 1031 | int cleaned = ixgbevf_clean_rx_irq(q_vector, ring, |
1032 | per_ring_budget) | 1032 | per_ring_budget); |
1033 | < per_ring_budget); | 1033 | work_done += cleaned; |
1034 | clean_complete &= (cleaned < per_ring_budget); | ||
1035 | } | ||
1034 | 1036 | ||
1035 | #ifdef CONFIG_NET_RX_BUSY_POLL | 1037 | #ifdef CONFIG_NET_RX_BUSY_POLL |
1036 | ixgbevf_qv_unlock_napi(q_vector); | 1038 | ixgbevf_qv_unlock_napi(q_vector); |
@@ -1040,7 +1042,7 @@ static int ixgbevf_poll(struct napi_struct *napi, int budget) | |||
1040 | if (!clean_complete) | 1042 | if (!clean_complete) |
1041 | return budget; | 1043 | return budget; |
1042 | /* all work done, exit the polling mode */ | 1044 | /* all work done, exit the polling mode */ |
1043 | napi_complete(napi); | 1045 | napi_complete_done(napi, work_done); |
1044 | if (adapter->rx_itr_setting & 1) | 1046 | if (adapter->rx_itr_setting & 1) |
1045 | ixgbevf_set_itr(q_vector); | 1047 | ixgbevf_set_itr(q_vector); |
1046 | if (!test_bit(__IXGBEVF_DOWN, &adapter->state) && | 1048 | if (!test_bit(__IXGBEVF_DOWN, &adapter->state) && |