diff options
author | Sean Hefty <sean.hefty@intel.com> | 2007-05-21 17:38:02 -0700 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2007-05-29 16:07:09 -0700 |
commit | d998ccce020e2cfcf11c6b57503532930ede2894 (patch) | |
tree | ee9756ab7c9bf087dc47ecd43c1e3a4c439a26c5 /drivers/infiniband/core/cm.c | |
parent | ec56dc0b7f6c3fec20bbc2e98ff1a06edf2fc9b9 (diff) |
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: Sean Hefty <sean.hefty@intel.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/core/cm.c')
-rw-r--r-- | drivers/infiniband/core/cm.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index e840434a96d..40c004a2697 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -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; - /* Check for duplicate REQ and stale connections. */ + /* Check for possible duplicate REQ. */ spin_lock_irqsave(&cm.lock, flags); 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) { cur_cm_id_priv = cm_get_id(timewait_info->work.local_id, timewait_info->work.remote_id); - cm_cleanup_timewait(cm_id_priv->timewait_info); spin_unlock_irqrestore(&cm.lock, flags); if (cur_cm_id_priv) { cm_dup_req_handler(work, cur_cm_id_priv); cm_deref_id(cur_cm_id_priv); - } else - cm_issue_rej(work->port, work->mad_recv_wc, - IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REQ, - NULL, 0); - listen_cm_id_priv = NULL; - goto out; + } + return NULL; + } + + /* Check for stale connections. */ + 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. */ |