[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