This patch will handling received messages in additional states.

signed-off-by: Sean Hefty <[EMAIL PROTECTED]>

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;
_______________________________________________
openib-general mailing list
[email protected]
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to