summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Marciniszyn <mike.marciniszyn@intel.com>2017-08-22 04:26:20 +0300
committerBen Hutchings <ben@decadent.org.uk>2017-11-26 16:50:25 +0300
commit5f250ed5f469ce7b000b4fcc67965195ca499d08 (patch)
treee914990a60b60629188bb118ecc2d7a3ef61a7a4
parent638b42cdd3fef8e876fd08d67a88230631bda6e6 (diff)
downloadlinux-5f250ed5f469ce7b000b4fcc67965195ca499d08.tar.xz
IB/{qib, hfi1}: Avoid flow control testing for RDMA write operation
commit 5b0ef650bd0f820e922fcc42f1985d4621ae19cf upstream. Section 9.7.7.2.5 of the 1.3 IBTA spec clearly says that receive credits should never apply to RDMA write. qib and hfi1 were doing that. The following situation will result in a QP hang: - A prior SEND or RDMA_WRITE with immmediate consumed the last credit for a QP using RC receive buffer credits - The prior op is acked so there are no more acks - The peer ULP fails to post receive for some reason - An RDMA write sees that the credits are exhausted and waits - The peer ULP posts receive buffers - The ULP posts a send or RDMA write that will be hung The fix is to avoid the credit test for the RDMA write operation. Reviewed-by: Kaike Wan <kaike.wan@intel.com> Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com> [bwh: Backported to 3.16: - Drop changes to hfi1 - Adjust context] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--drivers/infiniband/hw/qib/qib_rc.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/qib/qib_rc.c b/drivers/infiniband/hw/qib/qib_rc.c
index 2f2501890c4e..d135c1cc99ac 100644
--- a/drivers/infiniband/hw/qib/qib_rc.c
+++ b/drivers/infiniband/hw/qib/qib_rc.c
@@ -365,7 +365,7 @@ int qib_make_rc_req(struct qib_qp *qp)
case IB_WR_RDMA_WRITE:
if (newreq && !(qp->s_flags & QIB_S_UNLIMITED_CREDIT))
qp->s_lsn++;
- /* FALLTHROUGH */
+ goto no_flow_control;
case IB_WR_RDMA_WRITE_WITH_IMM:
/* If no credit, return. */
if (!(qp->s_flags & QIB_S_UNLIMITED_CREDIT) &&
@@ -373,6 +373,7 @@ int qib_make_rc_req(struct qib_qp *qp)
qp->s_flags |= QIB_S_WAIT_SSN_CREDIT;
goto bail;
}
+no_flow_control:
ohdr->u.rc.reth.vaddr =
cpu_to_be64(wqe->wr.wr.rdma.remote_addr);
ohdr->u.rc.reth.rkey =