Commit d998ccce authored by Sean Hefty's avatar Sean Hefty Committed by Roland Dreier

IB/cm: Fix stale connection detection

The ib_cm can incorrectly detect a stale connection (a new connection
request for a QPN that is already connected) as a duplicate connection
request.  Separate the handling of potential duplicate REQs from stale
connections.
Signed-off-by: default avatarSean Hefty <sean.hefty@intel.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent ec56dc0b
...@@ -1297,26 +1297,29 @@ static struct cm_id_private * cm_match_req(struct cm_work *work, ...@@ -1297,26 +1297,29 @@ static struct cm_id_private * cm_match_req(struct cm_work *work,
req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad; req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
/* Check for duplicate REQ and stale connections. */ /* Check for possible duplicate REQ. */
spin_lock_irqsave(&cm.lock, flags); spin_lock_irqsave(&cm.lock, flags);
timewait_info = cm_insert_remote_id(cm_id_priv->timewait_info); timewait_info = cm_insert_remote_id(cm_id_priv->timewait_info);
if (!timewait_info)
timewait_info = cm_insert_remote_qpn(cm_id_priv->timewait_info);
if (timewait_info) { if (timewait_info) {
cur_cm_id_priv = cm_get_id(timewait_info->work.local_id, cur_cm_id_priv = cm_get_id(timewait_info->work.local_id,
timewait_info->work.remote_id); timewait_info->work.remote_id);
cm_cleanup_timewait(cm_id_priv->timewait_info);
spin_unlock_irqrestore(&cm.lock, flags); spin_unlock_irqrestore(&cm.lock, flags);
if (cur_cm_id_priv) { if (cur_cm_id_priv) {
cm_dup_req_handler(work, cur_cm_id_priv); cm_dup_req_handler(work, cur_cm_id_priv);
cm_deref_id(cur_cm_id_priv); cm_deref_id(cur_cm_id_priv);
} else }
cm_issue_rej(work->port, work->mad_recv_wc, return NULL;
IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REQ, }
NULL, 0);
listen_cm_id_priv = NULL; /* Check for stale connections. */
goto out; timewait_info = cm_insert_remote_qpn(cm_id_priv->timewait_info);
if (timewait_info) {
cm_cleanup_timewait(cm_id_priv->timewait_info);
spin_unlock_irqrestore(&cm.lock, flags);
cm_issue_rej(work->port, work->mad_recv_wc,
IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REQ,
NULL, 0);
return NULL;
} }
/* Find matching listen request. */ /* Find matching listen request. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment