[openib-general] [PATCH] [CM] add reject handling for timeouts
Sean Hefty
mshefty at ichips.intel.com
Tue Feb 22 16:17:11 PST 2005
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 <sean.hefty at intel.com>
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)
More information about the general
mailing list