[openib-general] [PATCH] [CM] add stale connection test to active side

Sean Hefty mshefty at ichips.intel.com
Thu Feb 17 17:44:42 PST 2005


This patch adds testing for a stale connection on the active side of
the connection protocol.  It also fixes a bug where a duplicate REP
would have been dropped, rather than forcing a resend of the RTU.

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


Index: infiniband/core/cm.c
===================================================================
--- infiniband/core/cm.c	(revision 1818)
+++ infiniband/core/cm.c	(working copy)
@@ -1302,6 +1302,27 @@ static void cm_format_rep_event(struct c
 	work->cm_event.private_data = &rep_msg->private_data;
 }
 
+static void cm_dup_rep_handler(struct cm_rep_msg *rep_msg)
+{
+	struct cm_id_private *cm_id_priv;
+	enum ib_cm_state state;
+	unsigned long flags;
+
+	cm_id_priv = cm_acquire_id(rep_msg->remote_comm_id,
+				   rep_msg->local_comm_id);
+	if (!cm_id_priv)
+		return;
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	state = cm_id_priv->id.state;
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	
+	/* RTU's received in an invalid state will be dropped. */
+	if (state == IB_CM_ESTABLISHED)
+		cm_resend_rtu(cm_id_priv);
+	cm_deref_id(cm_id_priv);
+}
+
 static int cm_rep_handler(struct cm_work *work)
 {
 	struct cm_id_private *cm_id_priv;
@@ -1313,8 +1334,10 @@ static int cm_rep_handler(struct cm_work
 
 	rep_msg = (struct cm_rep_msg *)work->mad_recv_wc->recv_buf.mad;
 	cm_id_priv = cm_acquire_id(rep_msg->remote_comm_id, 0);
-	if (!cm_id_priv)
+	if (!cm_id_priv) {
+		cm_dup_rep_handler(rep_msg);
 		return -EINVAL;
+	}
 
 	timewait_info = cm_create_timewait_info(cm_id_priv->id.local_id,
 						rep_msg->local_comm_id,
@@ -1324,6 +1347,22 @@ static int cm_rep_handler(struct cm_work
 		ret = PTR_ERR(timewait_info);
 		goto error1;
 	}
+	spin_lock_irqsave(&cm.lock, flags);
+	/* Check for duplicate REP. */
+	if (cm_insert_remote_id(timewait_info)) {
+		spin_unlock_irqrestore(&cm.lock, flags);
+		ret = -EINVAL;
+		goto error2;
+	}
+	/* Check for a stale connection. */
+	if (cm_insert_remote_qpn(timewait_info)) {
+		spin_unlock_irqrestore(&cm.lock, flags);
+		/* todo: reject as stale */
+		ret = -EINVAL;
+		goto error2;
+	}
+	spin_unlock_irqrestore(&cm.lock, flags);
+
 	cm_format_rep_event(work);
 
 	spin_lock_irqsave(&cm_id_priv->lock, flags);
@@ -1331,11 +1370,6 @@ static int cm_rep_handler(struct cm_work
 	case IB_CM_REQ_SENT:
 	case IB_CM_MRA_REQ_RCVD:
 		break;
-	case IB_CM_ESTABLISHED:
-		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
-		cm_resend_rtu(cm_id_priv);
-		ret = -EINVAL;
-		goto error2;
 	default:
 		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 		ret = -EINVAL;
@@ -1365,6 +1399,7 @@ static int cm_rep_handler(struct cm_work
 		cm_deref_id(cm_id_priv);
 	return 0;
 error2:
+	cm_cleanup_timewait(timewait_info);
 	kfree(timewait_info);
 error1:
 	cm_deref_id(cm_id_priv);



More information about the general mailing list