ibmvnic: Correctly re-enable interrupts in NAPI polling routine
authorDwip N. Banerjee <dnbanerg@us.ibm.com>
Thu, 19 Nov 2020 01:12:23 +0000 (19:12 -0600)
committerJakub Kicinski <kuba@kernel.org>
Sat, 21 Nov 2020 03:50:34 +0000 (19:50 -0800)
If the current NAPI polling loop exits without completing it's
budget, only re-enable interrupts if there are no entries remaining
in the queue and napi_complete_done is successful. If there are entries
remaining on the queue that were missed, restart the polling loop.

Signed-off-by: Dwip N. Banerjee <dnbanerg@us.ibm.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/ibm/ibmvnic.c

index 85df91c..596546f 100644 (file)
@@ -2450,10 +2450,17 @@ static void remove_buff_from_pool(struct ibmvnic_adapter *adapter,
 
 static int ibmvnic_poll(struct napi_struct *napi, int budget)
 {
-       struct net_device *netdev = napi->dev;
-       struct ibmvnic_adapter *adapter = netdev_priv(netdev);
-       int scrq_num = (int)(napi - adapter->napi);
-       int frames_processed = 0;
+       struct ibmvnic_sub_crq_queue *rx_scrq;
+       struct ibmvnic_adapter *adapter;
+       struct net_device *netdev;
+       int frames_processed;
+       int scrq_num;
+
+       netdev = napi->dev;
+       adapter = netdev_priv(netdev);
+       scrq_num = (int)(napi - adapter->napi);
+       frames_processed = 0;
+       rx_scrq = adapter->rx_scrq[scrq_num];
 
 restart_poll:
        while (frames_processed < budget) {
@@ -2466,14 +2473,14 @@ restart_poll:
 
                if (unlikely(test_bit(0, &adapter->resetting) &&
                             adapter->reset_reason != VNIC_RESET_NON_FATAL)) {
-                       enable_scrq_irq(adapter, adapter->rx_scrq[scrq_num]);
+                       enable_scrq_irq(adapter, rx_scrq);
                        napi_complete_done(napi, frames_processed);
                        return frames_processed;
                }
 
-               if (!pending_scrq(adapter, adapter->rx_scrq[scrq_num]))
+               if (!pending_scrq(adapter, rx_scrq))
                        break;
-               next = ibmvnic_next_scrq(adapter, adapter->rx_scrq[scrq_num]);
+               next = ibmvnic_next_scrq(adapter, rx_scrq);
                rx_buff =
                    (struct ibmvnic_rx_buff *)be64_to_cpu(next->
                                                          rx_comp.correlator);
@@ -2532,14 +2539,16 @@ restart_poll:
 
        if (adapter->state != VNIC_CLOSING)
                replenish_rx_pool(adapter, &adapter->rx_pool[scrq_num]);
-
        if (frames_processed < budget) {
-               enable_scrq_irq(adapter, adapter->rx_scrq[scrq_num]);
-               napi_complete_done(napi, frames_processed);
-               if (pending_scrq(adapter, adapter->rx_scrq[scrq_num]) &&
-                   napi_reschedule(napi)) {
-                       disable_scrq_irq(adapter, adapter->rx_scrq[scrq_num]);
-                       goto restart_poll;
+               if (napi_complete_done(napi, frames_processed)) {
+                       enable_scrq_irq(adapter, rx_scrq);
+                       if (pending_scrq(adapter, rx_scrq)) {
+                               rmb();
+                               if (napi_reschedule(napi)) {
+                                       disable_scrq_irq(adapter, rx_scrq);
+                                       goto restart_poll;
+                               }
+                       }
                }
        }
        return frames_processed;