summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kim <ted.h.kim@oracle.com>2015-05-14 22:49:01 +0300
committerDoug Ledford <dledford@redhat.com>2015-05-20 19:41:38 +0300
commitc29ed5a4566fc7e0c5d06324d62974c6163d1e06 (patch)
tree698db733ae350ebd4070a6c34f7eb0b6ba9a5a46
parent235dfcd47e4442b2d8766bed3ebaf655b36c7f1c (diff)
downloadlinux-c29ed5a4566fc7e0c5d06324d62974c6163d1e06.tar.xz
ib/cm: Change reject message type when destroying cm_id
Problem reported by: Ted Kim <ted.h.kim@oracle.com>: We have a case where a Linux system and a non-Linux system are trying to interoperate. The Linux host is the active side and starts the connection establishment, but later decides to not go through with the connection setup and does rdma_destroy_id(). The rdma_destroy_id() eventually works its way down to cm_destroy_id() in core/cm.c, where a REJ is sent. The non-Linux system has some trouble recognizing the REJ because of: A. CM states which can't receive the REJ B. Some issues about REJ formatting (missing comm ID) ISSUE A: That part of the spec says, a Consumer Reject REJ can be sent for a connection abort, but it goes further and says: can send a REJ message with a "Consumer Reject" Reason code if they are in a CM state (i.e. REP Rcvd, MRA(REP) Sent, REQ Rcvd, MRA Sent) that allows a REJ to be sent (lines 35-38). Of the states listed there in that sentence, it would seem to limit the active side to using the Consumer Reject (for the abort case) in just the REP-Rcvd and MRA-REP-Sent states. That is basically only after the active side sees a REP (or alternatively goes down the state transitions to timeout in which case a Timeout REJ is sent). As a fix, in cm-destroy-id() move the IB-CM-MRA-REQ-RCVD case to the same as REQ-SENT. Essentially, make a REJ sent after getting an MRA on active side a timeout rather than Consumer- Reject, which is arguably more correct with the CM state diagrams previous to getting a REP. Signed-off-by: Ted Kim <ted.h.kim@oracle.com> Signed-off-by: Sean Hefty <sean.hefty@intel.com>
-rw-r--r--drivers/infiniband/core/cm.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 0c1419105ff0..0271608a51c4 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -861,6 +861,7 @@ retest:
cm_reject_sidr_req(cm_id_priv, IB_SIDR_REJECT);
break;
case IB_CM_REQ_SENT:
+ case IB_CM_MRA_REQ_RCVD:
ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
spin_unlock_irq(&cm_id_priv->lock);
ib_send_cm_rej(cm_id, IB_CM_REJ_TIMEOUT,
@@ -879,7 +880,6 @@ retest:
NULL, 0, NULL, 0);
}
break;
- case IB_CM_MRA_REQ_RCVD:
case IB_CM_REP_SENT:
case IB_CM_MRA_REP_RCVD:
ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);