Commit ec20f36b authored by Dwip N. Banerjee's avatar Dwip N. Banerjee Committed by Jakub Kicinski
Browse files

ibmvnic: Correctly re-enable interrupts in NAPI polling routine



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: default avatarDwip N. Banerjee <dnbanerg@us.ibm.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 9a87c3fc
Loading
Loading
Loading
Loading
+23 −14
Original line number Diff line number Diff line
@@ -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,16 +2539,18 @@ 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]);
		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;
}