The following patch adds reject handling for reject code 4, timeout.
The update requires searching for the local cm_id based on the remote
CA GUID and remote communication ID.

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

Index: infiniband/core/cm.c
===================================================================
--- infiniband/core/cm.c        (revision 1864)
+++ infiniband/core/cm.c        (working copy)
@@ -400,30 +400,28 @@ static struct cm_timewait_info * cm_inse
        return NULL;
 }
 
-/*
- * Call will be needed when implementing REJ handling.
-static struct cm_id_private * cm_find_id_by_remote_id(u64 remote_ca_guid,
-                                                     u32 remote_id)
+static struct cm_timewait_info * cm_find_remote_id(u64 remote_ca_guid,
+                                                  u32 remote_id)
 {
        struct rb_node *node = cm.remote_id_table.rb_node;
-       struct cm_id_private *cm_id_priv;
+       struct cm_timewait_info *timewait_info;
 
        while (node) {
-               cm_id_priv = rb_entry(node, struct cm_id_private, 
remote_id_node);
-               if (remote_id < cm_id_priv->id.remote_id)
+               timewait_info = rb_entry(node, struct cm_timewait_info,
+                                        remote_id_node);
+               if (remote_id < timewait_info->work.remote_id)
                        node = node->rb_left;
-               else if (remote_id > cm_id_priv->id.remote_id)
+               else if (remote_id > timewait_info->work.remote_id)
                        node = node->rb_right;
-               else if (remote_ca_guid < cm_id_priv->remote_ca_guid)
+               else if (remote_ca_guid < timewait_info->remote_ca_guid)
                        node = node->rb_left;
-               else if (remote_ca_guid > cm_id_priv->remote_ca_guid)
+               else if (remote_ca_guid > timewait_info->remote_ca_guid)
                        node = node->rb_right;
                else
-                       return cm_id_priv;
+                       return timewait_info;
        }
        return NULL;
 }
-*/
 
 static struct cm_timewait_info * cm_insert_remote_qpn(struct cm_timewait_info
                                                      *timewait_info)
@@ -1809,13 +1807,34 @@ static void cm_format_rej_event(struct c
 
 static struct cm_id_private * cm_acquire_rejected_id(struct cm_rej_msg 
*rej_msg)
 {
-       u32 local_id, remote_id;
+       struct cm_timewait_info *timewait_info;
+       struct cm_id_private *cm_id_priv;
+       unsigned long flags;
+       u32 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);
+       if (rej_msg->reason == IB_CM_REJ_TIMEOUT) {
+               spin_lock_irqsave(&cm.lock, flags);
+               timewait_info = cm_find_remote_id( *((u64 *) rej_msg->ari),
+                                                 remote_id);
+               if (!timewait_info) {
+                       spin_unlock_irqrestore(&cm.lock, flags);
+                       return NULL;
+               }
+               cm_id_priv = idr_find(&cm.local_id_table,
+                                     (int) timewait_info->work.local_id);
+               if (cm_id_priv) {
+                       if (cm_id_priv->id.remote_id == remote_id)
+                               atomic_inc(&cm_id_priv->refcount);
+                       else
+                               cm_id_priv = NULL;
+               }
+               spin_unlock_irqrestore(&cm.lock, flags);
+       } else
+               cm_id_priv = cm_acquire_id(rej_msg->remote_comm_id, remote_id);
+
+       return cm_id_priv;
 }
 
 static int cm_rej_handler(struct cm_work *work)
_______________________________________________
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