diff options
| author | Michael S. Tsirkin <mst@dev.mellanox.co.il> | 2007-05-24 11:32:46 -0400 |
|---|---|---|
| committer | Roland Dreier <rolandd@cisco.com> | 2007-05-24 17:02:40 -0400 |
| commit | 2dfbfc37121d307e1f1d24c2979382cb17b19347 (patch) | |
| tree | b301f2f55738bb6ec9621fbe81161d93701c6bcf /drivers | |
| parent | 8fd357a6e3375083f7d321413eb8f6739491f342 (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')
| -rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib.h | 1 | ||||
| -rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_cm.c | 1 | ||||
| -rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_ib.c | 31 |
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 | ||
| 430 | void ipoib_pkey_poll(struct work_struct *work); | 430 | void ipoib_pkey_poll(struct work_struct *work); |
| 431 | int ipoib_pkey_dev_delay_open(struct net_device *dev); | 431 | int ipoib_pkey_dev_delay_open(struct net_device *dev); |
| 432 | void 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 | ||
| 553 | void 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 | |||
| 553 | int ipoib_ib_dev_stop(struct net_device *dev, int flush) | 570 | int 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 | } |
