[openib-general] [PATCH] [CM] add stale connection test to active side
Sean Hefty
mshefty at ichips.intel.com
Thu Feb 17 17:44:42 PST 2005
This patch adds testing for a stale connection on the active side of
the connection protocol. It also fixes a bug where a duplicate REP
would have been dropped, rather than forcing a resend of the RTU.
Signed-off-by: Sean Hefty <sean.hefty at intel.com>
Index: infiniband/core/cm.c
===================================================================
--- infiniband/core/cm.c (revision 1818)
+++ infiniband/core/cm.c (working copy)
@@ -1302,6 +1302,27 @@ static void cm_format_rep_event(struct c
work->cm_event.private_data = &rep_msg->private_data;
}
+static void cm_dup_rep_handler(struct cm_rep_msg *rep_msg)
+{
+ struct cm_id_private *cm_id_priv;
+ enum ib_cm_state state;
+ unsigned long flags;
+
+ cm_id_priv = cm_acquire_id(rep_msg->remote_comm_id,
+ rep_msg->local_comm_id);
+ if (!cm_id_priv)
+ return;
+
+ spin_lock_irqsave(&cm_id_priv->lock, flags);
+ state = cm_id_priv->id.state;
+ spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+ /* RTU's received in an invalid state will be dropped. */
+ if (state == IB_CM_ESTABLISHED)
+ cm_resend_rtu(cm_id_priv);
+ cm_deref_id(cm_id_priv);
+}
+
static int cm_rep_handler(struct cm_work *work)
{
struct cm_id_private *cm_id_priv;
@@ -1313,8 +1334,10 @@ static int cm_rep_handler(struct cm_work
rep_msg = (struct cm_rep_msg *)work->mad_recv_wc->recv_buf.mad;
cm_id_priv = cm_acquire_id(rep_msg->remote_comm_id, 0);
- if (!cm_id_priv)
+ if (!cm_id_priv) {
+ cm_dup_rep_handler(rep_msg);
return -EINVAL;
+ }
timewait_info = cm_create_timewait_info(cm_id_priv->id.local_id,
rep_msg->local_comm_id,
@@ -1324,6 +1347,22 @@ static int cm_rep_handler(struct cm_work
ret = PTR_ERR(timewait_info);
goto error1;
}
+ spin_lock_irqsave(&cm.lock, flags);
+ /* Check for duplicate REP. */
+ if (cm_insert_remote_id(timewait_info)) {
+ spin_unlock_irqrestore(&cm.lock, flags);
+ ret = -EINVAL;
+ goto error2;
+ }
+ /* Check for a stale connection. */
+ if (cm_insert_remote_qpn(timewait_info)) {
+ spin_unlock_irqrestore(&cm.lock, flags);
+ /* todo: reject as stale */
+ ret = -EINVAL;
+ goto error2;
+ }
+ spin_unlock_irqrestore(&cm.lock, flags);
+
cm_format_rep_event(work);
spin_lock_irqsave(&cm_id_priv->lock, flags);
@@ -1331,11 +1370,6 @@ static int cm_rep_handler(struct cm_work
case IB_CM_REQ_SENT:
case IB_CM_MRA_REQ_RCVD:
break;
- case IB_CM_ESTABLISHED:
- spin_unlock_irqrestore(&cm_id_priv->lock, flags);
- cm_resend_rtu(cm_id_priv);
- ret = -EINVAL;
- goto error2;
default:
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
ret = -EINVAL;
@@ -1365,6 +1399,7 @@ static int cm_rep_handler(struct cm_work
cm_deref_id(cm_id_priv);
return 0;
error2:
+ cm_cleanup_timewait(timewait_info);
kfree(timewait_info);
error1:
cm_deref_id(cm_id_priv);
More information about the general
mailing list