[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