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: Michael S. Tsirkin <mst@dev.mellanox.co.il> Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
parent
8fd357a6e3
commit
2dfbfc3712
3 changed files with 21 additions and 12 deletions
|
@ -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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue