[openib-general] [PATCH] [CM]: Add initial reject handling code

Sean Hefty mshefty at ichips.intel.com
Tue Feb 22 12:16:04 PST 2005


This patch adds initial support for handling CM reject messages.  It
should work with the following reject codes: 1-3, 5, 8-9, 11-23,
26-29, 32-33.  (These are basically rejections by the remote consumer,
versus by the remote CM.)

I still need to determine the proper handling for the reject codes not
listed above.

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

Index: infiniband/core/cm.c
===================================================================
--- infiniband/core/cm.c	(revision 1863)
+++ infiniband/core/cm.c	(working copy)
@@ -1794,9 +1794,85 @@ out:
 }
 EXPORT_SYMBOL(ib_send_cm_rej);
 
+static void cm_format_rej_event(struct cm_work *work)
+{
+	struct cm_rej_msg *rej_msg;
+	struct ib_cm_rej_event_param *param;
+
+	rej_msg = (struct cm_rej_msg *)work->mad_recv_wc->recv_buf.mad;
+	param = &work->cm_event.param.rej_rcvd;
+	param->ari = rej_msg->ari;
+	param->ari_length = cm_rej_get_reject_info_len(rej_msg);
+	param->reason = rej_msg->reason;
+	work->cm_event.private_data = &rej_msg->private_data;
+}
+
+static struct cm_id_private * cm_acquire_rejected_id(struct cm_rej_msg *rej_msg)
+{
+	u32 local_id, 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);
+}
+
 static int cm_rej_handler(struct cm_work *work)
 {
-	/* todo: write reject handler */
+	struct cm_id_private *cm_id_priv;
+	struct cm_rej_msg *rej_msg;
+	unsigned long flags;
+	u64 wr_id = 0;
+	int ret;
+
+	rej_msg = (struct cm_rej_msg *)work->mad_recv_wc->recv_buf.mad;
+	cm_id_priv = cm_acquire_rejected_id(rej_msg);
+	if (!cm_id_priv)
+		return -EINVAL;
+
+	cm_format_rej_event(work);
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	switch (cm_id_priv->id.state) {
+	case IB_CM_REQ_SENT:
+	case IB_CM_REP_SENT:
+		wr_id = (unsigned long) cm_id_priv->msg;
+		/* fall through */
+	case IB_CM_REQ_RCVD:
+	case IB_CM_MRA_REQ_SENT:
+	case IB_CM_MRA_REQ_RCVD:
+	case IB_CM_MRA_REP_RCVD:
+		cm_reset_to_idle(cm_id_priv);
+		break;
+	case IB_CM_DREQ_SENT:
+		wr_id = (unsigned long) cm_id_priv->msg;
+		/* fall through */
+	case IB_CM_REP_RCVD:
+	case IB_CM_MRA_REP_SENT:
+	case IB_CM_ESTABLISHED:
+		cm_enter_timewait(cm_id_priv);
+		break;
+	default:
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = atomic_inc_and_test(&cm_id_priv->work_count);
+	if (!ret)
+		list_add_tail(&work->list, &cm_id_priv->work_list);
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+	if (wr_id)
+		ib_cancel_mad(cm_id_priv->av.port->mad_agent, wr_id);
+	if (ret)
+		cm_process_work(cm_id_priv, work);
+	else
+		cm_deref_id(cm_id_priv);
+	return 0;
+out:
+	cm_deref_id(cm_id_priv);
 	return -EINVAL;
 }
 

 



More information about the general mailing list