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 <[EMAIL PROTECTED]> 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); _______________________________________________ openib-general mailing list openib-general@openib.org http://openib.org/mailman/listinfo/openib-general To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general