[openib-general] [PATCH] [CM] add reject handling for timeouts

Sean Hefty mshefty at ichips.intel.com
Tue Feb 22 16:17:11 PST 2005


The following patch adds reject handling for reject code 4, timeout.
The update requires searching for the local cm_id based on the remote
CA GUID and remote communication ID.

Signed-off-by: Sean Hefty <sean.hefty at intel.com>

Index: infiniband/core/cm.c
===================================================================
--- infiniband/core/cm.c	(revision 1864)
+++ infiniband/core/cm.c	(working copy)
@@ -400,30 +400,28 @@ static struct cm_timewait_info * cm_inse
 	return NULL;
 }
 
-/*
- * Call will be needed when implementing REJ handling.
-static struct cm_id_private * cm_find_id_by_remote_id(u64 remote_ca_guid,
-						      u32 remote_id)
+static struct cm_timewait_info * cm_find_remote_id(u64 remote_ca_guid,
+						   u32 remote_id)
 {
 	struct rb_node *node = cm.remote_id_table.rb_node;
-	struct cm_id_private *cm_id_priv;
+	struct cm_timewait_info *timewait_info;
 
 	while (node) {
-		cm_id_priv = rb_entry(node, struct cm_id_private, remote_id_node);
-		if (remote_id < cm_id_priv->id.remote_id)
+		timewait_info = rb_entry(node, struct cm_timewait_info,
+					 remote_id_node);
+		if (remote_id < timewait_info->work.remote_id)
 			node = node->rb_left;
-		else if (remote_id > cm_id_priv->id.remote_id)
+		else if (remote_id > timewait_info->work.remote_id)
 			node = node->rb_right;
-		else if (remote_ca_guid < cm_id_priv->remote_ca_guid)
+		else if (remote_ca_guid < timewait_info->remote_ca_guid)
 			node = node->rb_left;
-		else if (remote_ca_guid > cm_id_priv->remote_ca_guid)
+		else if (remote_ca_guid > timewait_info->remote_ca_guid)
 			node = node->rb_right;
 		else
-			return cm_id_priv;
+			return timewait_info;
 	}
 	return NULL;
 }
-*/
 
 static struct cm_timewait_info * cm_insert_remote_qpn(struct cm_timewait_info
 						      *timewait_info)
@@ -1809,13 +1807,34 @@ static void cm_format_rej_event(struct c
 
 static struct cm_id_private * cm_acquire_rejected_id(struct cm_rej_msg *rej_msg)
 {
-	u32 local_id, remote_id;
+	struct cm_timewait_info *timewait_info;
+	struct cm_id_private *cm_id_priv;
+	unsigned long flags;
+	u32 remote_id;
 
-	/* todo: lookup by remote CA for rejects due to timeouts */
-	local_id = rej_msg->remote_comm_id;
 	remote_id = rej_msg->local_comm_id;
 
-	return cm_acquire_id(local_id, remote_id);
+	if (rej_msg->reason == IB_CM_REJ_TIMEOUT) {
+		spin_lock_irqsave(&cm.lock, flags);
+		timewait_info = cm_find_remote_id( *((u64 *) rej_msg->ari),
+						  remote_id);
+		if (!timewait_info) {
+			spin_unlock_irqrestore(&cm.lock, flags);
+			return NULL;
+		}
+		cm_id_priv = idr_find(&cm.local_id_table,
+				      (int) timewait_info->work.local_id);
+		if (cm_id_priv) {
+			if (cm_id_priv->id.remote_id == remote_id)
+				atomic_inc(&cm_id_priv->refcount);
+			else
+				cm_id_priv = NULL;
+		}
+		spin_unlock_irqrestore(&cm.lock, flags);
+	} else
+		cm_id_priv = cm_acquire_id(rej_msg->remote_comm_id, remote_id);
+
+	return cm_id_priv;
 }
 
 static int cm_rej_handler(struct cm_work *work)



More information about the general mailing list