Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2dfbfc37 authored by Michael S. Tsirkin's avatar Michael S. Tsirkin Committed by Roland Dreier
Browse files

IPoIB/cm: Drain cq in ipoib_cm_dev_stop()



Since NAPI polling is disabled while ipoib_cm_dev_stop() is running,
ipoib_cm_dev_stop() must poll the CQ itself in order to see the
packets draining.

Signed-off-by: default avatarMichael S. Tsirkin <mst@dev.mellanox.co.il>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 8fd357a6
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -429,6 +429,7 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey);


void ipoib_pkey_poll(struct work_struct *work);
void ipoib_pkey_poll(struct work_struct *work);
int ipoib_pkey_dev_delay_open(struct net_device *dev);
int ipoib_pkey_dev_delay_open(struct net_device *dev);
void ipoib_drain_cq(struct net_device *dev);


#ifdef CONFIG_INFINIBAND_IPOIB_CM
#ifdef CONFIG_INFINIBAND_IPOIB_CM


+1 −0
Original line number Original line Diff line number Diff line
@@ -726,6 +726,7 @@ void ipoib_cm_dev_stop(struct net_device *dev)
		}
		}
		spin_unlock_irq(&priv->lock);
		spin_unlock_irq(&priv->lock);
		msleep(1);
		msleep(1);
		ipoib_drain_cq(dev);
		spin_lock_irq(&priv->lock);
		spin_lock_irq(&priv->lock);
	}
	}


+19 −12
Original line number Original line Diff line number Diff line
@@ -550,13 +550,30 @@ static int recvs_pending(struct net_device *dev)
	return pending;
	return pending;
}
}


void ipoib_drain_cq(struct net_device *dev)
{
	struct ipoib_dev_priv *priv = netdev_priv(dev);
	int i, n;
	do {
		n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc);
		for (i = 0; i < n; ++i) {
			if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ)
				ipoib_cm_handle_rx_wc(dev, priv->ibwc + i);
			else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV)
				ipoib_ib_handle_rx_wc(dev, priv->ibwc + i);
			else
				ipoib_ib_handle_tx_wc(dev, priv->ibwc + i);
		}
	} while (n == IPOIB_NUM_WC);
}

int ipoib_ib_dev_stop(struct net_device *dev, int flush)
int ipoib_ib_dev_stop(struct net_device *dev, int flush)
{
{
	struct ipoib_dev_priv *priv = netdev_priv(dev);
	struct ipoib_dev_priv *priv = netdev_priv(dev);
	struct ib_qp_attr qp_attr;
	struct ib_qp_attr qp_attr;
	unsigned long begin;
	unsigned long begin;
	struct ipoib_tx_buf *tx_req;
	struct ipoib_tx_buf *tx_req;
	int i, n;
	int i;


	clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
	clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
	netif_poll_disable(dev);
	netif_poll_disable(dev);
@@ -611,17 +628,7 @@ int ipoib_ib_dev_stop(struct net_device *dev, int flush)
			goto timeout;
			goto timeout;
		}
		}


		do {
		ipoib_drain_cq(dev);
			n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc);
			for (i = 0; i < n; ++i) {
				if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ)
					ipoib_cm_handle_rx_wc(dev, priv->ibwc + i);
				else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV)
					ipoib_ib_handle_rx_wc(dev, priv->ibwc + i);
				else
					ipoib_ib_handle_tx_wc(dev, priv->ibwc + i);
			}
		} while (n == IPOIB_NUM_WC);


		msleep(1);
		msleep(1);
	}
	}