diff options
| -rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib.h | 8 | ||||
| -rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_ib.c | 35 | ||||
| -rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_main.c | 8 | ||||
| -rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 18 |
4 files changed, 39 insertions, 30 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index e940cd9f8471..9ef432ae72e8 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
| @@ -478,10 +478,10 @@ void ipoib_ib_dev_flush_heavy(struct work_struct *work); | |||
| 478 | void ipoib_pkey_event(struct work_struct *work); | 478 | void ipoib_pkey_event(struct work_struct *work); |
| 479 | void ipoib_ib_dev_cleanup(struct net_device *dev); | 479 | void ipoib_ib_dev_cleanup(struct net_device *dev); |
| 480 | 480 | ||
| 481 | int ipoib_ib_dev_open(struct net_device *dev, int flush); | 481 | int ipoib_ib_dev_open(struct net_device *dev); |
| 482 | int ipoib_ib_dev_up(struct net_device *dev); | 482 | int ipoib_ib_dev_up(struct net_device *dev); |
| 483 | int ipoib_ib_dev_down(struct net_device *dev, int flush); | 483 | int ipoib_ib_dev_down(struct net_device *dev); |
| 484 | int ipoib_ib_dev_stop(struct net_device *dev, int flush); | 484 | int ipoib_ib_dev_stop(struct net_device *dev); |
| 485 | void ipoib_pkey_dev_check_presence(struct net_device *dev); | 485 | void ipoib_pkey_dev_check_presence(struct net_device *dev); |
| 486 | 486 | ||
| 487 | int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port); | 487 | int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port); |
| @@ -493,7 +493,7 @@ void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb); | |||
| 493 | 493 | ||
| 494 | void ipoib_mcast_restart_task(struct work_struct *work); | 494 | void ipoib_mcast_restart_task(struct work_struct *work); |
| 495 | int ipoib_mcast_start_thread(struct net_device *dev); | 495 | int ipoib_mcast_start_thread(struct net_device *dev); |
| 496 | int ipoib_mcast_stop_thread(struct net_device *dev, int flush); | 496 | int ipoib_mcast_stop_thread(struct net_device *dev); |
| 497 | 497 | ||
| 498 | void ipoib_mcast_dev_down(struct net_device *dev); | 498 | void ipoib_mcast_dev_down(struct net_device *dev); |
| 499 | void ipoib_mcast_dev_flush(struct net_device *dev); | 499 | void ipoib_mcast_dev_flush(struct net_device *dev); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 2a56b7a11a92..e144d07d53cc 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
| @@ -659,22 +659,21 @@ void ipoib_reap_ah(struct work_struct *work) | |||
| 659 | round_jiffies_relative(HZ)); | 659 | round_jiffies_relative(HZ)); |
| 660 | } | 660 | } |
| 661 | 661 | ||
| 662 | static void ipoib_flush_ah(struct net_device *dev, int flush) | 662 | static void ipoib_flush_ah(struct net_device *dev) |
| 663 | { | 663 | { |
| 664 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 664 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 665 | 665 | ||
| 666 | cancel_delayed_work(&priv->ah_reap_task); | 666 | cancel_delayed_work(&priv->ah_reap_task); |
| 667 | if (flush) | 667 | flush_workqueue(priv->wq); |
| 668 | flush_workqueue(priv->wq); | ||
| 669 | ipoib_reap_ah(&priv->ah_reap_task.work); | 668 | ipoib_reap_ah(&priv->ah_reap_task.work); |
| 670 | } | 669 | } |
| 671 | 670 | ||
| 672 | static void ipoib_stop_ah(struct net_device *dev, int flush) | 671 | static void ipoib_stop_ah(struct net_device *dev) |
| 673 | { | 672 | { |
| 674 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 673 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 675 | 674 | ||
| 676 | set_bit(IPOIB_STOP_REAPER, &priv->flags); | 675 | set_bit(IPOIB_STOP_REAPER, &priv->flags); |
| 677 | ipoib_flush_ah(dev, flush); | 676 | ipoib_flush_ah(dev); |
| 678 | } | 677 | } |
| 679 | 678 | ||
| 680 | static void ipoib_ib_tx_timer_func(unsigned long ctx) | 679 | static void ipoib_ib_tx_timer_func(unsigned long ctx) |
| @@ -682,7 +681,7 @@ static void ipoib_ib_tx_timer_func(unsigned long ctx) | |||
| 682 | drain_tx_cq((struct net_device *)ctx); | 681 | drain_tx_cq((struct net_device *)ctx); |
| 683 | } | 682 | } |
| 684 | 683 | ||
| 685 | int ipoib_ib_dev_open(struct net_device *dev, int flush) | 684 | int ipoib_ib_dev_open(struct net_device *dev) |
| 686 | { | 685 | { |
| 687 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 686 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 688 | int ret; | 687 | int ret; |
| @@ -724,7 +723,7 @@ int ipoib_ib_dev_open(struct net_device *dev, int flush) | |||
| 724 | dev_stop: | 723 | dev_stop: |
| 725 | if (!test_and_set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) | 724 | if (!test_and_set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) |
| 726 | napi_enable(&priv->napi); | 725 | napi_enable(&priv->napi); |
| 727 | ipoib_ib_dev_stop(dev, flush); | 726 | ipoib_ib_dev_stop(dev); |
| 728 | return -1; | 727 | return -1; |
| 729 | } | 728 | } |
| 730 | 729 | ||
| @@ -756,7 +755,7 @@ int ipoib_ib_dev_up(struct net_device *dev) | |||
| 756 | return ipoib_mcast_start_thread(dev); | 755 | return ipoib_mcast_start_thread(dev); |
| 757 | } | 756 | } |
| 758 | 757 | ||
| 759 | int ipoib_ib_dev_down(struct net_device *dev, int flush) | 758 | int ipoib_ib_dev_down(struct net_device *dev) |
| 760 | { | 759 | { |
| 761 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 760 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 762 | 761 | ||
| @@ -765,7 +764,7 @@ int ipoib_ib_dev_down(struct net_device *dev, int flush) | |||
| 765 | clear_bit(IPOIB_FLAG_OPER_UP, &priv->flags); | 764 | clear_bit(IPOIB_FLAG_OPER_UP, &priv->flags); |
| 766 | netif_carrier_off(dev); | 765 | netif_carrier_off(dev); |
| 767 | 766 | ||
| 768 | ipoib_mcast_stop_thread(dev, flush); | 767 | ipoib_mcast_stop_thread(dev); |
| 769 | ipoib_mcast_dev_flush(dev); | 768 | ipoib_mcast_dev_flush(dev); |
| 770 | 769 | ||
| 771 | ipoib_flush_paths(dev); | 770 | ipoib_flush_paths(dev); |
| @@ -825,7 +824,7 @@ void ipoib_drain_cq(struct net_device *dev) | |||
| 825 | local_bh_enable(); | 824 | local_bh_enable(); |
| 826 | } | 825 | } |
| 827 | 826 | ||
| 828 | int ipoib_ib_dev_stop(struct net_device *dev, int flush) | 827 | int ipoib_ib_dev_stop(struct net_device *dev) |
| 829 | { | 828 | { |
| 830 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 829 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 831 | struct ib_qp_attr qp_attr; | 830 | struct ib_qp_attr qp_attr; |
| @@ -895,7 +894,7 @@ timeout: | |||
| 895 | if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE)) | 894 | if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE)) |
| 896 | ipoib_warn(priv, "Failed to modify QP to RESET state\n"); | 895 | ipoib_warn(priv, "Failed to modify QP to RESET state\n"); |
| 897 | 896 | ||
| 898 | ipoib_flush_ah(dev, flush); | 897 | ipoib_flush_ah(dev); |
| 899 | 898 | ||
| 900 | ib_req_notify_cq(priv->recv_cq, IB_CQ_NEXT_COMP); | 899 | ib_req_notify_cq(priv->recv_cq, IB_CQ_NEXT_COMP); |
| 901 | 900 | ||
| @@ -919,7 +918,7 @@ int ipoib_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port) | |||
| 919 | (unsigned long) dev); | 918 | (unsigned long) dev); |
| 920 | 919 | ||
| 921 | if (dev->flags & IFF_UP) { | 920 | if (dev->flags & IFF_UP) { |
| 922 | if (ipoib_ib_dev_open(dev, 1)) { | 921 | if (ipoib_ib_dev_open(dev)) { |
| 923 | ipoib_transport_dev_cleanup(dev); | 922 | ipoib_transport_dev_cleanup(dev); |
| 924 | return -ENODEV; | 923 | return -ENODEV; |
| 925 | } | 924 | } |
| @@ -1038,16 +1037,16 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, | |||
| 1038 | if (level == IPOIB_FLUSH_LIGHT) { | 1037 | if (level == IPOIB_FLUSH_LIGHT) { |
| 1039 | ipoib_mark_paths_invalid(dev); | 1038 | ipoib_mark_paths_invalid(dev); |
| 1040 | ipoib_mcast_dev_flush(dev); | 1039 | ipoib_mcast_dev_flush(dev); |
| 1041 | ipoib_flush_ah(dev, 0); | 1040 | ipoib_flush_ah(dev); |
| 1042 | } | 1041 | } |
| 1043 | 1042 | ||
| 1044 | if (level >= IPOIB_FLUSH_NORMAL) | 1043 | if (level >= IPOIB_FLUSH_NORMAL) |
| 1045 | ipoib_ib_dev_down(dev, 0); | 1044 | ipoib_ib_dev_down(dev); |
| 1046 | 1045 | ||
| 1047 | if (level == IPOIB_FLUSH_HEAVY) { | 1046 | if (level == IPOIB_FLUSH_HEAVY) { |
| 1048 | if (test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) | 1047 | if (test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) |
| 1049 | ipoib_ib_dev_stop(dev, 0); | 1048 | ipoib_ib_dev_stop(dev); |
| 1050 | if (ipoib_ib_dev_open(dev, 0) != 0) | 1049 | if (ipoib_ib_dev_open(dev) != 0) |
| 1051 | return; | 1050 | return; |
| 1052 | if (netif_queue_stopped(dev)) | 1051 | if (netif_queue_stopped(dev)) |
| 1053 | netif_start_queue(dev); | 1052 | netif_start_queue(dev); |
| @@ -1099,7 +1098,7 @@ void ipoib_ib_dev_cleanup(struct net_device *dev) | |||
| 1099 | */ | 1098 | */ |
| 1100 | ipoib_flush_paths(dev); | 1099 | ipoib_flush_paths(dev); |
| 1101 | 1100 | ||
| 1102 | ipoib_mcast_stop_thread(dev, 1); | 1101 | ipoib_mcast_stop_thread(dev); |
| 1103 | ipoib_mcast_dev_flush(dev); | 1102 | ipoib_mcast_dev_flush(dev); |
| 1104 | 1103 | ||
| 1105 | /* | 1104 | /* |
| @@ -1108,7 +1107,7 @@ void ipoib_ib_dev_cleanup(struct net_device *dev) | |||
| 1108 | * the neighbor garbage collection is stopped and reaped. | 1107 | * the neighbor garbage collection is stopped and reaped. |
| 1109 | * That should all be done now, so make a final ah flush. | 1108 | * That should all be done now, so make a final ah flush. |
| 1110 | */ | 1109 | */ |
| 1111 | ipoib_stop_ah(dev, 1); | 1110 | ipoib_stop_ah(dev); |
| 1112 | 1111 | ||
| 1113 | ipoib_transport_dev_cleanup(dev); | 1112 | ipoib_transport_dev_cleanup(dev); |
| 1114 | } | 1113 | } |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 4be80bec93ca..176b3dfb49c3 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
| @@ -108,7 +108,7 @@ int ipoib_open(struct net_device *dev) | |||
| 108 | 108 | ||
| 109 | set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); | 109 | set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); |
| 110 | 110 | ||
| 111 | if (ipoib_ib_dev_open(dev, 1)) { | 111 | if (ipoib_ib_dev_open(dev)) { |
| 112 | if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) | 112 | if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) |
| 113 | return 0; | 113 | return 0; |
| 114 | goto err_disable; | 114 | goto err_disable; |
| @@ -139,7 +139,7 @@ int ipoib_open(struct net_device *dev) | |||
| 139 | return 0; | 139 | return 0; |
| 140 | 140 | ||
| 141 | err_stop: | 141 | err_stop: |
| 142 | ipoib_ib_dev_stop(dev, 1); | 142 | ipoib_ib_dev_stop(dev); |
| 143 | 143 | ||
| 144 | err_disable: | 144 | err_disable: |
| 145 | clear_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); | 145 | clear_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); |
| @@ -157,8 +157,8 @@ static int ipoib_stop(struct net_device *dev) | |||
| 157 | 157 | ||
| 158 | netif_stop_queue(dev); | 158 | netif_stop_queue(dev); |
| 159 | 159 | ||
| 160 | ipoib_ib_dev_down(dev, 1); | 160 | ipoib_ib_dev_down(dev); |
| 161 | ipoib_ib_dev_stop(dev, 0); | 161 | ipoib_ib_dev_stop(dev); |
| 162 | 162 | ||
| 163 | if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) { | 163 | if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) { |
| 164 | struct ipoib_dev_priv *cpriv; | 164 | struct ipoib_dev_priv *cpriv; |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 9d3c1ed576ea..bb1b69904f96 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
| @@ -613,7 +613,7 @@ int ipoib_mcast_start_thread(struct net_device *dev) | |||
| 613 | return 0; | 613 | return 0; |
| 614 | } | 614 | } |
| 615 | 615 | ||
| 616 | int ipoib_mcast_stop_thread(struct net_device *dev, int flush) | 616 | int ipoib_mcast_stop_thread(struct net_device *dev) |
| 617 | { | 617 | { |
| 618 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 618 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 619 | 619 | ||
| @@ -624,8 +624,7 @@ int ipoib_mcast_stop_thread(struct net_device *dev, int flush) | |||
| 624 | cancel_delayed_work(&priv->mcast_task); | 624 | cancel_delayed_work(&priv->mcast_task); |
| 625 | mutex_unlock(&mcast_mutex); | 625 | mutex_unlock(&mcast_mutex); |
| 626 | 626 | ||
| 627 | if (flush) | 627 | flush_workqueue(priv->wq); |
| 628 | flush_workqueue(priv->wq); | ||
| 629 | 628 | ||
| 630 | return 0; | 629 | return 0; |
| 631 | } | 630 | } |
| @@ -797,7 +796,18 @@ void ipoib_mcast_restart_task(struct work_struct *work) | |||
| 797 | 796 | ||
| 798 | ipoib_dbg_mcast(priv, "restarting multicast task\n"); | 797 | ipoib_dbg_mcast(priv, "restarting multicast task\n"); |
| 799 | 798 | ||
| 800 | ipoib_mcast_stop_thread(dev, 0); | 799 | /* |
| 800 | * We're running on the priv->wq right now, so we can't call | ||
| 801 | * mcast_stop_thread as it wants to flush the wq and that | ||
| 802 | * will deadlock. We don't actually *need* to stop the | ||
| 803 | * thread here anyway, so just clear the run flag, cancel | ||
| 804 | * any delayed work, do our work, remove the old entries, | ||
| 805 | * then restart the thread. | ||
| 806 | */ | ||
| 807 | mutex_lock(&mcast_mutex); | ||
| 808 | clear_bit(IPOIB_MCAST_RUN, &priv->flags); | ||
| 809 | cancel_delayed_work(&priv->mcast_task); | ||
| 810 | mutex_unlock(&mcast_mutex); | ||
| 801 | 811 | ||
| 802 | local_irq_save(flags); | 812 | local_irq_save(flags); |
| 803 | netif_addr_lock(dev); | 813 | netif_addr_lock(dev); |
