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

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
...@@ -429,6 +429,7 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey); ...@@ -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
......
...@@ -726,6 +726,7 @@ void ipoib_cm_dev_stop(struct net_device *dev) ...@@ -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);
} }
......
...@@ -550,13 +550,30 @@ static int recvs_pending(struct net_device *dev) ...@@ -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) ...@@ -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);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment