aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@dev.mellanox.co.il>2007-05-24 11:32:46 -0400
committerRoland Dreier <rolandd@cisco.com>2007-05-24 17:02:40 -0400
commit2dfbfc37121d307e1f1d24c2979382cb17b19347 (patch)
treeb301f2f55738bb6ec9621fbe81161d93701c6bcf /drivers/infiniband
parent8fd357a6e3375083f7d321413eb8f6739491f342 (diff)
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>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h1
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c1
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c31
3 files changed, 21 insertions, 12 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index a0b3782c7625..158759e28a5b 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -429,6 +429,7 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey);
429 429
430void ipoib_pkey_poll(struct work_struct *work); 430void ipoib_pkey_poll(struct work_struct *work);
431int ipoib_pkey_dev_delay_open(struct net_device *dev); 431int ipoib_pkey_dev_delay_open(struct net_device *dev);
432void ipoib_drain_cq(struct net_device *dev);
432 433
433#ifdef CONFIG_INFINIBAND_IPOIB_CM 434#ifdef CONFIG_INFINIBAND_IPOIB_CM
434 435
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index e8fcd628be73..f133b56fd978 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -726,6 +726,7 @@ void ipoib_cm_dev_stop(struct net_device *dev)
726 } 726 }
727 spin_unlock_irq(&priv->lock); 727 spin_unlock_irq(&priv->lock);
728 msleep(1); 728 msleep(1);
729 ipoib_drain_cq(dev);
729 spin_lock_irq(&priv->lock); 730 spin_lock_irq(&priv->lock);
730 } 731 }
731 732
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index c1aad06eb4e9..8404f05b2b6e 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -550,13 +550,30 @@ static int recvs_pending(struct net_device *dev)
550 return pending; 550 return pending;
551} 551}
552 552
553void ipoib_drain_cq(struct net_device *dev)
554{
555 struct ipoib_dev_priv *priv = netdev_priv(dev);
556 int i, n;
557 do {
558 n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc);
559 for (i = 0; i < n; ++i) {
560 if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ)
561 ipoib_cm_handle_rx_wc(dev, priv->ibwc + i);
562 else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV)
563 ipoib_ib_handle_rx_wc(dev, priv->ibwc + i);
564 else
565 ipoib_ib_handle_tx_wc(dev, priv->ibwc + i);
566 }
567 } while (n == IPOIB_NUM_WC);
568}
569
553int ipoib_ib_dev_stop(struct net_device *dev, int flush) 570int ipoib_ib_dev_stop(struct net_device *dev, int flush)
554{ 571{
555 struct ipoib_dev_priv *priv = netdev_priv(dev); 572 struct ipoib_dev_priv *priv = netdev_priv(dev);
556 struct ib_qp_attr qp_attr; 573 struct ib_qp_attr qp_attr;
557 unsigned long begin; 574 unsigned long begin;
558 struct ipoib_tx_buf *tx_req; 575 struct ipoib_tx_buf *tx_req;
559 int i, n; 576 int i;
560 577
561 clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags); 578 clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
562 netif_poll_disable(dev); 579 netif_poll_disable(dev);
@@ -611,17 +628,7 @@ int ipoib_ib_dev_stop(struct net_device *dev, int flush)
611 goto timeout; 628 goto timeout;
612 } 629 }
613 630
614 do { 631 ipoib_drain_cq(dev);
615 n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc);
616 for (i = 0; i < n; ++i) {
617 if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ)
618 ipoib_cm_handle_rx_wc(dev, priv->ibwc + i);
619 else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV)
620 ipoib_ib_handle_rx_wc(dev, priv->ibwc + i);
621 else
622 ipoib_ib_handle_tx_wc(dev, priv->ibwc + i);
623 }
624 } while (n == IPOIB_NUM_WC);
625 632
626 msleep(1); 633 msleep(1);
627 } 634 }