aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-03-14 22:53:35 -0400
committerDavid S. Miller <davem@davemloft.net>2014-03-14 22:53:35 -0400
commite7ef085d0a9dc1cc72e7d8108ed3b4e1a5e8d938 (patch)
treef8ae35945d4100401117f32d27d776c16c0cd086
parent1c79a5a8f4faec88f9f4632d0ef9b0365bff8e28 (diff)
parent75363a4676cdb046242d06dca6e8a9c0a20d6c4a (diff)
Merge branch 'napi_budget_zero'
Eric W. Biederman says: ==================== Don't receive packets when the napi budget == 0 After reading through all 120 drivers supporting netpoll I have found 16 more that process at least received packet when the napi budget == 0. Processing more packets than your budget has always been a bug but we haven't cared before so it looks like these drivers slipped through, and need fixes. As netpoll will shortly be using a budget of 0 to get the tx queue processing with the rx queue processing we now care. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/amd/amd8111e.c3
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c2
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_main.c14
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c3
-rw-r--r--drivers/net/ethernet/ibm/ibmveth.c4
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.c3
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c4
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c4
-rw-r--r--drivers/net/ethernet/marvell/sky2.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_rx.c3
-rw-r--r--drivers/net/ethernet/neterion/s2io.c3
-rw-r--r--drivers/net/ethernet/neterion/vxge/vxge-main.c4
-rw-r--r--drivers/net/ethernet/sfc/ef10.c3
-rw-r--r--drivers/net/ethernet/sfc/farch.c3
-rw-r--r--drivers/net/ethernet/tile/tilegx.c3
-rw-r--r--drivers/net/ethernet/tile/tilepro.c3
-rw-r--r--drivers/net/ethernet/toshiba/tc35815.c3
17 files changed, 53 insertions, 12 deletions
diff --git a/drivers/net/ethernet/amd/amd8111e.c b/drivers/net/ethernet/amd/amd8111e.c
index 2061b471fd16..26efaaa5e73f 100644
--- a/drivers/net/ethernet/amd/amd8111e.c
+++ b/drivers/net/ethernet/amd/amd8111e.c
@@ -720,6 +720,9 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
720 int rx_pkt_limit = budget; 720 int rx_pkt_limit = budget;
721 unsigned long flags; 721 unsigned long flags;
722 722
723 if (rx_pkt_limit <= 0)
724 goto rx_not_empty;
725
723 do{ 726 do{
724 /* process receive packets until we use the quota*/ 727 /* process receive packets until we use the quota*/
725 /* If we own the next entry, it's a new packet. Send it up. */ 728 /* If we own the next entry, it's a new packet. Send it up. */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 117b5c7f8ac9..acd494647f25 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -872,6 +872,8 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
872 if (unlikely(bp->panic)) 872 if (unlikely(bp->panic))
873 return 0; 873 return 0;
874#endif 874#endif
875 if (budget <= 0)
876 return rx_pkt;
875 877
876 bd_cons = fp->rx_bd_cons; 878 bd_cons = fp->rx_bd_cons;
877 bd_prod = fp->rx_bd_prod; 879 bd_prod = fp->rx_bd_prod;
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index dcd58f23834a..4c35fc8fad99 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -1086,14 +1086,15 @@ static int enic_poll(struct napi_struct *napi, int budget)
1086 unsigned int intr = enic_legacy_io_intr(); 1086 unsigned int intr = enic_legacy_io_intr();
1087 unsigned int rq_work_to_do = budget; 1087 unsigned int rq_work_to_do = budget;
1088 unsigned int wq_work_to_do = -1; /* no limit */ 1088 unsigned int wq_work_to_do = -1; /* no limit */
1089 unsigned int work_done, rq_work_done, wq_work_done; 1089 unsigned int work_done, rq_work_done = 0, wq_work_done;
1090 int err; 1090 int err;
1091 1091
1092 /* Service RQ (first) and WQ 1092 /* Service RQ (first) and WQ
1093 */ 1093 */
1094 1094
1095 rq_work_done = vnic_cq_service(&enic->cq[cq_rq], 1095 if (budget > 0)
1096 rq_work_to_do, enic_rq_service, NULL); 1096 rq_work_done = vnic_cq_service(&enic->cq[cq_rq],
1097 rq_work_to_do, enic_rq_service, NULL);
1097 1098
1098 wq_work_done = vnic_cq_service(&enic->cq[cq_wq], 1099 wq_work_done = vnic_cq_service(&enic->cq[cq_wq],
1099 wq_work_to_do, enic_wq_service, NULL); 1100 wq_work_to_do, enic_wq_service, NULL);
@@ -1141,14 +1142,15 @@ static int enic_poll_msix(struct napi_struct *napi, int budget)
1141 unsigned int cq = enic_cq_rq(enic, rq); 1142 unsigned int cq = enic_cq_rq(enic, rq);
1142 unsigned int intr = enic_msix_rq_intr(enic, rq); 1143 unsigned int intr = enic_msix_rq_intr(enic, rq);
1143 unsigned int work_to_do = budget; 1144 unsigned int work_to_do = budget;
1144 unsigned int work_done; 1145 unsigned int work_done = 0;
1145 int err; 1146 int err;
1146 1147
1147 /* Service RQ 1148 /* Service RQ
1148 */ 1149 */
1149 1150
1150 work_done = vnic_cq_service(&enic->cq[cq], 1151 if (budget > 0)
1151 work_to_do, enic_rq_service, NULL); 1152 work_done = vnic_cq_service(&enic->cq[cq],
1153 work_to_do, enic_rq_service, NULL);
1152 1154
1153 /* Return intr event credits for this polling 1155 /* Return intr event credits for this polling
1154 * cycle. An intr event is the completion of a 1156 * cycle. An intr event is the completion of a
diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
index 62f042d4aaa9..dc80db41d6b3 100644
--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
+++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
@@ -91,6 +91,9 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
91 u16 pkt_len, sc; 91 u16 pkt_len, sc;
92 int curidx; 92 int curidx;
93 93
94 if (budget <= 0)
95 return received;
96
94 /* 97 /*
95 * First, grab all of the stats for the incoming packet. 98 * First, grab all of the stats for the incoming packet.
96 * These get messed up if we get called due to a busy condition. 99 * These get messed up if we get called due to a busy condition.
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index 1fc8334fc181..e75bdfcd1374 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -1072,7 +1072,7 @@ static int ibmveth_poll(struct napi_struct *napi, int budget)
1072 unsigned long lpar_rc; 1072 unsigned long lpar_rc;
1073 1073
1074restart_poll: 1074restart_poll:
1075 do { 1075 while (frames_processed < budget) {
1076 if (!ibmveth_rxq_pending_buffer(adapter)) 1076 if (!ibmveth_rxq_pending_buffer(adapter))
1077 break; 1077 break;
1078 1078
@@ -1121,7 +1121,7 @@ restart_poll:
1121 netdev->stats.rx_bytes += length; 1121 netdev->stats.rx_bytes += length;
1122 frames_processed++; 1122 frames_processed++;
1123 } 1123 }
1124 } while (frames_processed < budget); 1124 }
1125 1125
1126 ibmveth_replenish_task(adapter); 1126 ibmveth_replenish_task(adapter);
1127 1127
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index daa3b295ff3d..88666adb0743 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -1302,6 +1302,9 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
1302 u8 rx_ptype; 1302 u8 rx_ptype;
1303 u64 qword; 1303 u64 qword;
1304 1304
1305 if (budget <= 0)
1306 return 0;
1307
1305 rx_desc = I40E_RX_DESC(rx_ring, i); 1308 rx_desc = I40E_RX_DESC(rx_ring, i);
1306 qword = le64_to_cpu(rx_desc->wb.qword1.status_error_len); 1309 qword = le64_to_cpu(rx_desc->wb.qword1.status_error_len);
1307 rx_status = (qword & I40E_RXD_QW1_STATUS_MASK) >> 1310 rx_status = (qword & I40E_RXD_QW1_STATUS_MASK) >>
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index f81d87cfcc8d..d6b11522fed7 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -6946,7 +6946,7 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
6946 unsigned int total_bytes = 0, total_packets = 0; 6946 unsigned int total_bytes = 0, total_packets = 0;
6947 u16 cleaned_count = igb_desc_unused(rx_ring); 6947 u16 cleaned_count = igb_desc_unused(rx_ring);
6948 6948
6949 do { 6949 while (likely(total_packets < budget)) {
6950 union e1000_adv_rx_desc *rx_desc; 6950 union e1000_adv_rx_desc *rx_desc;
6951 6951
6952 /* return some buffers to hardware, one at a time is too slow */ 6952 /* return some buffers to hardware, one at a time is too slow */
@@ -6998,7 +6998,7 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
6998 6998
6999 /* update budget accounting */ 6999 /* update budget accounting */
7000 total_packets++; 7000 total_packets++;
7001 } while (likely(total_packets < budget)); 7001 }
7002 7002
7003 /* place incomplete frames back on ring for completion */ 7003 /* place incomplete frames back on ring for completion */
7004 rx_ring->skb = skb; 7004 rx_ring->skb = skb;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 5d314fe873bb..18cd8ca319ea 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -2076,7 +2076,7 @@ static int ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
2076#endif /* IXGBE_FCOE */ 2076#endif /* IXGBE_FCOE */
2077 u16 cleaned_count = ixgbe_desc_unused(rx_ring); 2077 u16 cleaned_count = ixgbe_desc_unused(rx_ring);
2078 2078
2079 do { 2079 while (likely(total_rx_packets < budget)) {
2080 union ixgbe_adv_rx_desc *rx_desc; 2080 union ixgbe_adv_rx_desc *rx_desc;
2081 struct sk_buff *skb; 2081 struct sk_buff *skb;
2082 2082
@@ -2151,7 +2151,7 @@ static int ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
2151 2151
2152 /* update budget accounting */ 2152 /* update budget accounting */
2153 total_rx_packets++; 2153 total_rx_packets++;
2154 } while (likely(total_rx_packets < budget)); 2154 }
2155 2155
2156 u64_stats_update_begin(&rx_ring->syncp); 2156 u64_stats_update_begin(&rx_ring->syncp);
2157 rx_ring->stats.packets += total_rx_packets; 2157 rx_ring->stats.packets += total_rx_packets;
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index 5a5b23741179..d524676fdff4 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -2735,6 +2735,9 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
2735 unsigned int total_bytes[2] = { 0 }; 2735 unsigned int total_bytes[2] = { 0 };
2736 unsigned int total_packets[2] = { 0 }; 2736 unsigned int total_packets[2] = { 0 };
2737 2737
2738 if (to_do <= 0)
2739 return work_done;
2740
2738 rmb(); 2741 rmb();
2739 do { 2742 do {
2740 struct sky2_port *sky2; 2743 struct sky2_port *sky2;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index 8afb72ec957d..ba049ae88749 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -661,6 +661,9 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
661 if (!priv->port_up) 661 if (!priv->port_up)
662 return 0; 662 return 0;
663 663
664 if (budget <= 0)
665 return polled;
666
664 /* We assume a 1:1 mapping between CQEs and Rx descriptors, so Rx 667 /* We assume a 1:1 mapping between CQEs and Rx descriptors, so Rx
665 * descriptor offset can be deduced from the CQE index instead of 668 * descriptor offset can be deduced from the CQE index instead of
666 * reading 'cqe->index' */ 669 * reading 'cqe->index' */
diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c
index 56e3a9d42bb2..d44fdb91808e 100644
--- a/drivers/net/ethernet/neterion/s2io.c
+++ b/drivers/net/ethernet/neterion/s2io.c
@@ -2914,6 +2914,9 @@ static int rx_intr_handler(struct ring_info *ring_data, int budget)
2914 struct RxD1 *rxdp1; 2914 struct RxD1 *rxdp1;
2915 struct RxD3 *rxdp3; 2915 struct RxD3 *rxdp3;
2916 2916
2917 if (budget <= 0)
2918 return napi_pkts;
2919
2917 get_info = ring_data->rx_curr_get_info; 2920 get_info = ring_data->rx_curr_get_info;
2918 get_block = get_info.block_index; 2921 get_block = get_info.block_index;
2919 memcpy(&put_info, &ring_data->rx_curr_put_info, sizeof(put_info)); 2922 memcpy(&put_info, &ring_data->rx_curr_put_info, sizeof(put_info));
diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c
index c5bb1ace4a74..11adc89959c1 100644
--- a/drivers/net/ethernet/neterion/vxge/vxge-main.c
+++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c
@@ -368,6 +368,9 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
368 vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d", 368 vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
369 ring->ndev->name, __func__, __LINE__); 369 ring->ndev->name, __func__, __LINE__);
370 370
371 if (ring->budget <= 0)
372 goto out;
373
371 do { 374 do {
372 prefetch((char *)dtr + L1_CACHE_BYTES); 375 prefetch((char *)dtr + L1_CACHE_BYTES);
373 rx_priv = vxge_hw_ring_rxd_private_get(dtr); 376 rx_priv = vxge_hw_ring_rxd_private_get(dtr);
@@ -525,6 +528,7 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
525 if (first_dtr) 528 if (first_dtr)
526 vxge_hw_ring_rxd_post_post_wmb(ringh, first_dtr); 529 vxge_hw_ring_rxd_post_post_wmb(ringh, first_dtr);
527 530
531out:
528 vxge_debug_entryexit(VXGE_TRACE, 532 vxge_debug_entryexit(VXGE_TRACE,
529 "%s:%d Exiting...", 533 "%s:%d Exiting...",
530 __func__, __LINE__); 534 __func__, __LINE__);
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index eb75675f6e32..651626e133f9 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -1955,6 +1955,9 @@ static int efx_ef10_ev_process(struct efx_channel *channel, int quota)
1955 int tx_descs = 0; 1955 int tx_descs = 0;
1956 int spent = 0; 1956 int spent = 0;
1957 1957
1958 if (quota <= 0)
1959 return spent;
1960
1958 read_ptr = channel->eventq_read_ptr; 1961 read_ptr = channel->eventq_read_ptr;
1959 1962
1960 for (;;) { 1963 for (;;) {
diff --git a/drivers/net/ethernet/sfc/farch.c b/drivers/net/ethernet/sfc/farch.c
index aa1b169f45ec..a08761360cdf 100644
--- a/drivers/net/ethernet/sfc/farch.c
+++ b/drivers/net/ethernet/sfc/farch.c
@@ -1248,6 +1248,9 @@ int efx_farch_ev_process(struct efx_channel *channel, int budget)
1248 int tx_packets = 0; 1248 int tx_packets = 0;
1249 int spent = 0; 1249 int spent = 0;
1250 1250
1251 if (budget <= 0)
1252 return spent;
1253
1251 read_ptr = channel->eventq_read_ptr; 1254 read_ptr = channel->eventq_read_ptr;
1252 1255
1253 for (;;) { 1256 for (;;) {
diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c
index 17503da9f7a5..b43f1b3b9632 100644
--- a/drivers/net/ethernet/tile/tilegx.c
+++ b/drivers/net/ethernet/tile/tilegx.c
@@ -659,6 +659,9 @@ static int tile_net_poll(struct napi_struct *napi, int budget)
659 struct info_mpipe *info_mpipe = 659 struct info_mpipe *info_mpipe =
660 container_of(napi, struct info_mpipe, napi); 660 container_of(napi, struct info_mpipe, napi);
661 661
662 if (budget <= 0)
663 goto done;
664
662 instance = info_mpipe->instance; 665 instance = info_mpipe->instance;
663 while ((n = gxio_mpipe_iqueue_try_peek( 666 while ((n = gxio_mpipe_iqueue_try_peek(
664 &info_mpipe->iqueue, 667 &info_mpipe->iqueue,
diff --git a/drivers/net/ethernet/tile/tilepro.c b/drivers/net/ethernet/tile/tilepro.c
index 7e33973487ee..b94449b4bd34 100644
--- a/drivers/net/ethernet/tile/tilepro.c
+++ b/drivers/net/ethernet/tile/tilepro.c
@@ -831,6 +831,9 @@ static int tile_net_poll(struct napi_struct *napi, int budget)
831 831
832 unsigned int work = 0; 832 unsigned int work = 0;
833 833
834 if (budget <= 0)
835 goto done;
836
834 while (priv->active) { 837 while (priv->active) {
835 int index = qup->__packet_receive_read; 838 int index = qup->__packet_receive_read;
836 if (index == qsp->__packet_receive_queue.__packet_write) 839 if (index == qsp->__packet_receive_queue.__packet_write)
diff --git a/drivers/net/ethernet/toshiba/tc35815.c b/drivers/net/ethernet/toshiba/tc35815.c
index 88e9c73cebc0..fef5573dbfca 100644
--- a/drivers/net/ethernet/toshiba/tc35815.c
+++ b/drivers/net/ethernet/toshiba/tc35815.c
@@ -1645,6 +1645,9 @@ static int tc35815_poll(struct napi_struct *napi, int budget)
1645 int received = 0, handled; 1645 int received = 0, handled;
1646 u32 status; 1646 u32 status;
1647 1647
1648 if (budget <= 0)
1649 return received;
1650
1648 spin_lock(&lp->rx_lock); 1651 spin_lock(&lp->rx_lock);
1649 status = tc_readl(&tr->Int_Src); 1652 status = tc_readl(&tr->Int_Src);
1650 do { 1653 do {