Browse Source

IB/ipoib: Use P_Key change event instead of P_Key polling mechanism

The current code use a dedicated polling logic to determine when the P_Key
assigned to the ipoib device is present in HCA port table and act accordingly.

Move to use the code which acts upon getting PKEY_CHANGE event to handle this
task and remove the P_Key polling logic/thread as they add extra complexity
which isn't needed.

Signed-off-by: Erez Shitrit <erezsh@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Acked-by: Alex Estrin <alex.estrin@intel.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Erez Shitrit 11 năm trước cách đây
mục cha
commit
db84f88037

+ 2 - 4
drivers/infiniband/ulp/ipoib/ipoib.h

@@ -86,7 +86,6 @@ enum {
 	IPOIB_FLAG_INITIALIZED	  = 1,
 	IPOIB_FLAG_INITIALIZED	  = 1,
 	IPOIB_FLAG_ADMIN_UP	  = 2,
 	IPOIB_FLAG_ADMIN_UP	  = 2,
 	IPOIB_PKEY_ASSIGNED	  = 3,
 	IPOIB_PKEY_ASSIGNED	  = 3,
-	IPOIB_PKEY_STOP		  = 4,
 	IPOIB_FLAG_SUBINTERFACE	  = 5,
 	IPOIB_FLAG_SUBINTERFACE	  = 5,
 	IPOIB_MCAST_RUN		  = 6,
 	IPOIB_MCAST_RUN		  = 6,
 	IPOIB_STOP_REAPER	  = 7,
 	IPOIB_STOP_REAPER	  = 7,
@@ -312,7 +311,6 @@ struct ipoib_dev_priv {
 	struct list_head multicast_list;
 	struct list_head multicast_list;
 	struct rb_root multicast_tree;
 	struct rb_root multicast_tree;
 
 
-	struct delayed_work pkey_poll_task;
 	struct delayed_work mcast_task;
 	struct delayed_work mcast_task;
 	struct work_struct carrier_on_task;
 	struct work_struct carrier_on_task;
 	struct work_struct flush_light;
 	struct work_struct flush_light;
@@ -477,6 +475,7 @@ int ipoib_ib_dev_open(struct net_device *dev);
 int ipoib_ib_dev_up(struct net_device *dev);
 int ipoib_ib_dev_up(struct net_device *dev);
 int ipoib_ib_dev_down(struct net_device *dev, int flush);
 int ipoib_ib_dev_down(struct net_device *dev, int flush);
 int ipoib_ib_dev_stop(struct net_device *dev, int flush);
 int ipoib_ib_dev_stop(struct net_device *dev, int flush);
+void ipoib_pkey_dev_check_presence(struct net_device *dev);
 
 
 int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port);
 int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port);
 void ipoib_dev_cleanup(struct net_device *dev);
 void ipoib_dev_cleanup(struct net_device *dev);
@@ -532,8 +531,7 @@ int  ipoib_set_mode(struct net_device *dev, const char *buf);
 
 
 void ipoib_setup(struct net_device *dev);
 void ipoib_setup(struct net_device *dev);
 
 
-void ipoib_pkey_poll(struct work_struct *work);
-int ipoib_pkey_dev_delay_open(struct net_device *dev);
+void ipoib_pkey_open(struct ipoib_dev_priv *priv);
 void ipoib_drain_cq(struct net_device *dev);
 void ipoib_drain_cq(struct net_device *dev);
 
 
 void ipoib_set_ethtool_ops(struct net_device *dev);
 void ipoib_set_ethtool_ops(struct net_device *dev);

+ 14 - 59
drivers/infiniband/ulp/ipoib/ipoib_ib.c

@@ -709,7 +709,7 @@ dev_stop:
 	return -1;
 	return -1;
 }
 }
 
 
-static void ipoib_pkey_dev_check_presence(struct net_device *dev)
+void ipoib_pkey_dev_check_presence(struct net_device *dev)
 {
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 	u16 pkey_index = 0;
 	u16 pkey_index = 0;
@@ -745,14 +745,6 @@ int ipoib_ib_dev_down(struct net_device *dev, int flush)
 	clear_bit(IPOIB_FLAG_OPER_UP, &priv->flags);
 	clear_bit(IPOIB_FLAG_OPER_UP, &priv->flags);
 	netif_carrier_off(dev);
 	netif_carrier_off(dev);
 
 
-	/* Shutdown the P_Key thread if still active */
-	if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) {
-		mutex_lock(&pkey_mutex);
-		set_bit(IPOIB_PKEY_STOP, &priv->flags);
-		cancel_delayed_work_sync(&priv->pkey_poll_task);
-		mutex_unlock(&pkey_mutex);
-	}
-
 	ipoib_mcast_stop_thread(dev, flush);
 	ipoib_mcast_stop_thread(dev, flush);
 	ipoib_mcast_dev_flush(dev);
 	ipoib_mcast_dev_flush(dev);
 
 
@@ -988,9 +980,12 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv,
 
 
 	if (!test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) {
 	if (!test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) {
 		/* for non-child devices must check/update the pkey value here */
 		/* for non-child devices must check/update the pkey value here */
-		if (level == IPOIB_FLUSH_HEAVY &&
-		    !test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags))
-			update_parent_pkey(priv);
+		if (level == IPOIB_FLUSH_HEAVY) {
+			if (test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags))
+				ipoib_pkey_open(priv);
+			else
+				update_parent_pkey(priv);
+		}
 		ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_INITIALIZED not set.\n");
 		ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_INITIALIZED not set.\n");
 		return;
 		return;
 	}
 	}
@@ -1009,8 +1004,7 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv,
 				clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
 				clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
 				ipoib_ib_dev_down(dev, 0);
 				ipoib_ib_dev_down(dev, 0);
 				ipoib_ib_dev_stop(dev, 0);
 				ipoib_ib_dev_stop(dev, 0);
-				if (ipoib_pkey_dev_delay_open(dev))
-					return;
+				return;
 			}
 			}
 			/* restart QP only if P_Key index is changed */
 			/* restart QP only if P_Key index is changed */
 			if (test_and_set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags) &&
 			if (test_and_set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags) &&
@@ -1094,54 +1088,15 @@ void ipoib_ib_dev_cleanup(struct net_device *dev)
 	ipoib_transport_dev_cleanup(dev);
 	ipoib_transport_dev_cleanup(dev);
 }
 }
 
 
-/*
- * Delayed P_Key Assigment Interim Support
- *
- * The following is initial implementation of delayed P_Key assigment
- * mechanism. It is using the same approach implemented for the multicast
- * group join. The single goal of this implementation is to quickly address
- * Bug #2507. This implementation will probably be removed when the P_Key
- * change async notification is available.
- */
-
-void ipoib_pkey_poll(struct work_struct *work)
+void ipoib_pkey_open(struct ipoib_dev_priv *priv)
 {
 {
-	struct ipoib_dev_priv *priv =
-		container_of(work, struct ipoib_dev_priv, pkey_poll_task.work);
-	struct net_device *dev = priv->dev;
 
 
-	ipoib_pkey_dev_check_presence(dev);
+	if (test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags))
+		return;
+
+	ipoib_pkey_dev_check_presence(priv->dev);
 
 
 	if (test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags))
 	if (test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags))
-		ipoib_open(dev);
-	else {
-		mutex_lock(&pkey_mutex);
-		if (!test_bit(IPOIB_PKEY_STOP, &priv->flags))
-			queue_delayed_work(ipoib_workqueue,
-					   &priv->pkey_poll_task,
-					   HZ);
-		mutex_unlock(&pkey_mutex);
-	}
+		ipoib_open(priv->dev);
 }
 }
 
 
-int ipoib_pkey_dev_delay_open(struct net_device *dev)
-{
-	struct ipoib_dev_priv *priv = netdev_priv(dev);
-
-	/* Look for the interface pkey value in the IB Port P_Key table and */
-	/* set the interface pkey assigment flag                            */
-	ipoib_pkey_dev_check_presence(dev);
-
-	/* P_Key value not assigned yet - start polling */
-	if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) {
-		mutex_lock(&pkey_mutex);
-		clear_bit(IPOIB_PKEY_STOP, &priv->flags);
-		queue_delayed_work(ipoib_workqueue,
-				   &priv->pkey_poll_task,
-				   HZ);
-		mutex_unlock(&pkey_mutex);
-		return 1;
-	}
-
-	return 0;
-}

+ 4 - 2
drivers/infiniband/ulp/ipoib/ipoib_main.c

@@ -108,7 +108,10 @@ int ipoib_open(struct net_device *dev)
 
 
 	set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags);
 	set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags);
 
 
-	if (ipoib_pkey_dev_delay_open(dev))
+
+	ipoib_pkey_dev_check_presence(dev);
+
+	if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags))
 		return 0;
 		return 0;
 
 
 	if (ipoib_ib_dev_open(dev))
 	if (ipoib_ib_dev_open(dev))
@@ -1379,7 +1382,6 @@ void ipoib_setup(struct net_device *dev)
 	INIT_LIST_HEAD(&priv->dead_ahs);
 	INIT_LIST_HEAD(&priv->dead_ahs);
 	INIT_LIST_HEAD(&priv->multicast_list);
 	INIT_LIST_HEAD(&priv->multicast_list);
 
 
-	INIT_DELAYED_WORK(&priv->pkey_poll_task, ipoib_pkey_poll);
 	INIT_DELAYED_WORK(&priv->mcast_task,   ipoib_mcast_join_task);
 	INIT_DELAYED_WORK(&priv->mcast_task,   ipoib_mcast_join_task);
 	INIT_WORK(&priv->carrier_on_task, ipoib_mcast_carrier_on_task);
 	INIT_WORK(&priv->carrier_on_task, ipoib_mcast_carrier_on_task);
 	INIT_WORK(&priv->flush_light,   ipoib_ib_dev_flush_light);
 	INIT_WORK(&priv->flush_light,   ipoib_ib_dev_flush_light);