diff options
Diffstat (limited to 'drivers/infiniband/ulp/ipoib/ipoib_ib.c')
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_ib.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 66cafa20c246..0e748aeeae99 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
@@ -468,21 +468,22 @@ void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr) | |||
468 | static void drain_tx_cq(struct net_device *dev) | 468 | static void drain_tx_cq(struct net_device *dev) |
469 | { | 469 | { |
470 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 470 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
471 | unsigned long flags; | ||
472 | 471 | ||
473 | spin_lock_irqsave(&priv->tx_lock, flags); | 472 | netif_tx_lock(dev); |
474 | while (poll_tx(priv)) | 473 | while (poll_tx(priv)) |
475 | ; /* nothing */ | 474 | ; /* nothing */ |
476 | 475 | ||
477 | if (netif_queue_stopped(dev)) | 476 | if (netif_queue_stopped(dev)) |
478 | mod_timer(&priv->poll_timer, jiffies + 1); | 477 | mod_timer(&priv->poll_timer, jiffies + 1); |
479 | 478 | ||
480 | spin_unlock_irqrestore(&priv->tx_lock, flags); | 479 | netif_tx_unlock(dev); |
481 | } | 480 | } |
482 | 481 | ||
483 | void ipoib_send_comp_handler(struct ib_cq *cq, void *dev_ptr) | 482 | void ipoib_send_comp_handler(struct ib_cq *cq, void *dev_ptr) |
484 | { | 483 | { |
485 | drain_tx_cq((struct net_device *)dev_ptr); | 484 | struct ipoib_dev_priv *priv = netdev_priv(dev_ptr); |
485 | |||
486 | mod_timer(&priv->poll_timer, jiffies); | ||
486 | } | 487 | } |
487 | 488 | ||
488 | static inline int post_send(struct ipoib_dev_priv *priv, | 489 | static inline int post_send(struct ipoib_dev_priv *priv, |
@@ -614,17 +615,20 @@ static void __ipoib_reap_ah(struct net_device *dev) | |||
614 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 615 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
615 | struct ipoib_ah *ah, *tah; | 616 | struct ipoib_ah *ah, *tah; |
616 | LIST_HEAD(remove_list); | 617 | LIST_HEAD(remove_list); |
618 | unsigned long flags; | ||
619 | |||
620 | netif_tx_lock_bh(dev); | ||
621 | spin_lock_irqsave(&priv->lock, flags); | ||
617 | 622 | ||
618 | spin_lock_irq(&priv->tx_lock); | ||
619 | spin_lock(&priv->lock); | ||
620 | list_for_each_entry_safe(ah, tah, &priv->dead_ahs, list) | 623 | list_for_each_entry_safe(ah, tah, &priv->dead_ahs, list) |
621 | if ((int) priv->tx_tail - (int) ah->last_send >= 0) { | 624 | if ((int) priv->tx_tail - (int) ah->last_send >= 0) { |
622 | list_del(&ah->list); | 625 | list_del(&ah->list); |
623 | ib_destroy_ah(ah->ah); | 626 | ib_destroy_ah(ah->ah); |
624 | kfree(ah); | 627 | kfree(ah); |
625 | } | 628 | } |
626 | spin_unlock(&priv->lock); | 629 | |
627 | spin_unlock_irq(&priv->tx_lock); | 630 | spin_unlock_irqrestore(&priv->lock, flags); |
631 | netif_tx_unlock_bh(dev); | ||
628 | } | 632 | } |
629 | 633 | ||
630 | void ipoib_reap_ah(struct work_struct *work) | 634 | void ipoib_reap_ah(struct work_struct *work) |
@@ -761,6 +765,14 @@ void ipoib_drain_cq(struct net_device *dev) | |||
761 | { | 765 | { |
762 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 766 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
763 | int i, n; | 767 | int i, n; |
768 | |||
769 | /* | ||
770 | * We call completion handling routines that expect to be | ||
771 | * called from the BH-disabled NAPI poll context, so disable | ||
772 | * BHs here too. | ||
773 | */ | ||
774 | local_bh_disable(); | ||
775 | |||
764 | do { | 776 | do { |
765 | n = ib_poll_cq(priv->recv_cq, IPOIB_NUM_WC, priv->ibwc); | 777 | n = ib_poll_cq(priv->recv_cq, IPOIB_NUM_WC, priv->ibwc); |
766 | for (i = 0; i < n; ++i) { | 778 | for (i = 0; i < n; ++i) { |
@@ -784,6 +796,8 @@ void ipoib_drain_cq(struct net_device *dev) | |||
784 | 796 | ||
785 | while (poll_tx(priv)) | 797 | while (poll_tx(priv)) |
786 | ; /* nothing */ | 798 | ; /* nothing */ |
799 | |||
800 | local_bh_enable(); | ||
787 | } | 801 | } |
788 | 802 | ||
789 | int ipoib_ib_dev_stop(struct net_device *dev, int flush) | 803 | int ipoib_ib_dev_stop(struct net_device *dev, int flush) |