From 5e2101ceb232f34712c43dcd8ba424f3f761d8bd Mon Sep 17 00:00:00 2001 From: Alexey Marchuk Date: Tue, 17 Mar 2020 16:42:41 +0300 Subject: [PATCH] rdma: Correct WR type checking The previous patch ce6b8a1313ffc1f18c13ef5ff0445715a7da008ea added a wrong assumption that every WC of RDMA_WR_TYPE_DATA type must point to rdma_req with IBV_WC_RDMA_READ opcode since RDMA_WRITE operations are non-signaled. However it is wrong since in the case of error all WRs will have WCs. Revert part of the problematic patch. Change-Id: I8d270c5313ebfe1ec44a338820a62f085996eb8f Signed-off-by: Alexey Marchuk Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1334 Reviewed-by: Ben Walker Reviewed-by: Jim Harris Tested-by: SPDK CI Jenkins --- lib/nvmf/rdma.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/nvmf/rdma.c b/lib/nvmf/rdma.c index a922346f5..01559ff1d 100644 --- a/lib/nvmf/rdma.c +++ b/lib/nvmf/rdma.c @@ -3915,13 +3915,12 @@ spdk_nvmf_rdma_poller_poll(struct spdk_nvmf_rdma_transport *rtransport, rqpair = SPDK_CONTAINEROF(rdma_req->req.qpair, struct spdk_nvmf_rdma_qpair, qpair); assert(rdma_req->num_outstanding_data_wr > 0); - assert(rdma_req->data.wr.opcode == IBV_WR_RDMA_READ); rqpair->current_send_depth--; - rqpair->current_read_depth--; rdma_req->num_outstanding_data_wr--; if (!wc[i].status) { assert(wc[i].opcode == IBV_WC_RDMA_READ); + rqpair->current_read_depth--; /* wait for all outstanding reads associated with the same rdma_req to complete before proceeding. */ if (rdma_req->num_outstanding_data_wr == 0) { rdma_req->state = RDMA_REQUEST_STATE_READY_TO_EXECUTE; @@ -3929,9 +3928,14 @@ spdk_nvmf_rdma_poller_poll(struct spdk_nvmf_rdma_transport *rtransport, } } else { /* If the data transfer fails still force the queue into the error state, - * in case of RDMA_READ, we need to force the request into a completed state */ - if (rdma_req->num_outstanding_data_wr == 0) { - rdma_req->state = RDMA_REQUEST_STATE_COMPLETED; + * if we were performing an RDMA_READ, we need to force the request into a + * completed state since it wasn't linked to a send. However, in the RDMA_WRITE + * case, we should wait for the SEND to complete. */ + if (rdma_req->data.wr.opcode == IBV_WR_RDMA_READ) { + rqpair->current_read_depth--; + if (rdma_req->num_outstanding_data_wr == 0) { + rdma_req->state = RDMA_REQUEST_STATE_COMPLETED; + } } } break;