aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/ipoib
diff options
context:
space:
mode:
authorDoug Ledford <dledford@redhat.com>2015-02-21 19:27:04 -0500
committerDoug Ledford <dledford@redhat.com>2015-04-15 16:06:18 -0400
commitefc82eeeae4ece716091d8540079b7f276ca1ad5 (patch)
tree541dfa13579f95f18e51ff5caee6f6d1fa34591d /drivers/infiniband/ulp/ipoib
parent0b39578bcde4298a392fb2df16235c316d932127 (diff)
IB/ipoib: No longer use flush as a parameter
Various places in the IPoIB code had a deadlock related to flushing the ipoib workqueue. Now that we have per device workqueues and a specific flush workqueue, there is no longer a deadlock issue with flushing the device specific workqueues and we can do so unilaterally. Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/infiniband/ulp/ipoib')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h8
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c35
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c8
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c18
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);
478void ipoib_pkey_event(struct work_struct *work); 478void ipoib_pkey_event(struct work_struct *work);
479void ipoib_ib_dev_cleanup(struct net_device *dev); 479void ipoib_ib_dev_cleanup(struct net_device *dev);
480 480
481int ipoib_ib_dev_open(struct net_device *dev, int flush); 481int ipoib_ib_dev_open(struct net_device *dev);
482int ipoib_ib_dev_up(struct net_device *dev); 482int ipoib_ib_dev_up(struct net_device *dev);
483int ipoib_ib_dev_down(struct net_device *dev, int flush); 483int ipoib_ib_dev_down(struct net_device *dev);
484int ipoib_ib_dev_stop(struct net_device *dev, int flush); 484int ipoib_ib_dev_stop(struct net_device *dev);
485void ipoib_pkey_dev_check_presence(struct net_device *dev); 485void ipoib_pkey_dev_check_presence(struct net_device *dev);
486 486
487int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port); 487int 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
494void ipoib_mcast_restart_task(struct work_struct *work); 494void ipoib_mcast_restart_task(struct work_struct *work);
495int ipoib_mcast_start_thread(struct net_device *dev); 495int ipoib_mcast_start_thread(struct net_device *dev);
496int ipoib_mcast_stop_thread(struct net_device *dev, int flush); 496int ipoib_mcast_stop_thread(struct net_device *dev);
497 497
498void ipoib_mcast_dev_down(struct net_device *dev); 498void ipoib_mcast_dev_down(struct net_device *dev);
499void ipoib_mcast_dev_flush(struct net_device *dev); 499void 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
662static void ipoib_flush_ah(struct net_device *dev, int flush) 662static 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
672static void ipoib_stop_ah(struct net_device *dev, int flush) 671static 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
680static void ipoib_ib_tx_timer_func(unsigned long ctx) 679static 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
685int ipoib_ib_dev_open(struct net_device *dev, int flush) 684int 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)
724dev_stop: 723dev_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
759int ipoib_ib_dev_down(struct net_device *dev, int flush) 758int 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
828int ipoib_ib_dev_stop(struct net_device *dev, int flush) 827int 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
141err_stop: 141err_stop:
142 ipoib_ib_dev_stop(dev, 1); 142 ipoib_ib_dev_stop(dev);
143 143
144err_disable: 144err_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
616int ipoib_mcast_stop_thread(struct net_device *dev, int flush) 616int 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);