[openib-general] [PATCH] CM: add code to handle additional state transitions

Sean Hefty mshefty at ichips.intel.com
Thu Jan 20 17:30:03 PST 2005


This patch will handling received messages in additional states.

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

Index: core/cm.c
===================================================================
--- core/cm.c	(revision 1608)
+++ core/cm.c	(working copy)
@@ -1307,40 +1307,6 @@ out:
 }
 EXPORT_SYMBOL(ib_send_cm_dreq);
 
-static void cm_dreq_handler(struct cm_recv_work *recv_work)
-{
-	struct cm_id_private *cm_id_priv;
-	struct cm_dreq_msg *dreq_msg;
-	unsigned long flags;
-	int ret;
-
-	dreq_msg = (struct cm_dreq_msg *)recv_work->mad_recv_wc->recv_buf.mad;
-	cm_id_priv = cm_acquire_id_by_local_id(dreq_msg->remote_comm_id);
-	if (!cm_id_priv)
-		return;
-
-	spin_lock_irqsave(&cm_id_priv->lock, flags);
-	if (cm_id_priv->id.state != IB_CM_ESTABLISHED ||
-	    cm_id_priv->local_qpn != cm_dreq_get_remote_qpn(dreq_msg)) {
-		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
-		/* todo: resend DREP */
-		goto out;
-	}
-	cm_id_priv->id.state = IB_CM_DREQ_RCVD;
-	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
-
-	recv_work->cm_event.event = IB_CM_DREQ_RECEIVED;
-	recv_work->cm_event.private_data = &dreq_msg->private_data;
-	ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, &recv_work->cm_event);
-	if (ret) {
-		atomic_dec(&cm_id_priv->refcount);
-		ib_destroy_cm_id(&cm_id_priv->id);
-		return;
-	}
-out:
-	cm_deref_id(cm_id_priv);
-}
-
 static void cm_format_drep(struct cm_drep_msg *drep_msg,
 			  struct cm_id_private *cm_id_priv,
 			  void *private_data,
@@ -1356,6 +1322,23 @@ static void cm_format_drep(struct cm_dre
 		memcpy(drep_msg->private_data, private_data, private_data_len);
 }
 
+static void cm_resend_drep(struct cm_id_private *cm_id_priv)
+{
+	struct cm_msg *msg;
+	struct ib_send_wr *bad_send_wr;
+	int ret;
+
+	ret = cm_alloc_msg(cm_id_priv, &msg);
+	if (ret)
+		return;
+
+	cm_format_drep((struct cm_drep_msg *)&msg->mad, cm_id_priv, NULL, 0);
+	ret = ib_post_send_mad(cm_id_priv->port->mad_agent,
+			       &msg->send_wr, &bad_send_wr);
+	if (ret)
+		cm_free_msg(cm_id_priv->msg);
+}
+
 int ib_send_cm_drep(struct ib_cm_id *cm_id,
 		    void *private_data,
 		    u8 private_data_len)
@@ -1397,6 +1380,52 @@ out:
 }
 EXPORT_SYMBOL(ib_send_cm_drep);
 
+static void cm_dreq_handler(struct cm_recv_work *recv_work)
+{
+	struct cm_id_private *cm_id_priv;
+	struct cm_dreq_msg *dreq_msg;
+	unsigned long flags;
+	int ret;
+
+	dreq_msg = (struct cm_dreq_msg *)recv_work->mad_recv_wc->recv_buf.mad;
+	cm_id_priv = cm_acquire_id_by_local_id(dreq_msg->remote_comm_id);
+	if (!cm_id_priv)
+		return;
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	if (cm_id_priv->local_qpn != cm_dreq_get_remote_qpn(dreq_msg)) {
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		goto out;
+	}
+	switch (cm_id_priv->id.state) {
+	case IB_CM_REP_SENT:
+	case IB_CM_MRA_REP_RCVD:
+	case IB_CM_ESTABLISHED:
+	case IB_CM_DREQ_SENT:
+		break;
+	case IB_CM_TIMEWAIT:
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		cm_resend_drep(cm_id_priv);
+		goto out;
+	default:
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		goto out;
+	}
+	cm_id_priv->id.state = IB_CM_DREQ_RCVD;
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+	recv_work->cm_event.event = IB_CM_DREQ_RECEIVED;
+	recv_work->cm_event.private_data = &dreq_msg->private_data;
+	ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, &recv_work->cm_event);
+	if (ret) {
+		atomic_dec(&cm_id_priv->refcount);
+		ib_destroy_cm_id(&cm_id_priv->id);
+		return;
+	}
+out:
+	cm_deref_id(cm_id_priv);
+}
+
 static void cm_drep_handler(struct cm_recv_work *recv_work)
 {
 	struct cm_id_private *cm_id_priv;



More information about the general mailing list