From 0763baaad6a33e4e65048d0048e18f57c858f59c Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 27 Mar 2013 15:32:31 +0000 Subject: [PATCH] ib_srpt: Process cmd_wait_list immediately after QP RTS transition git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@4826 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- srpt/src/ib_srpt.c | 45 ++++++++++++++++++++++++++++++++++----------- srpt/src/ib_srpt.h | 1 + 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/srpt/src/ib_srpt.c b/srpt/src/ib_srpt.c index 39ea7b5d1..5ea5459ef 100644 --- a/srpt/src/ib_srpt.c +++ b/srpt/src/ib_srpt.c @@ -1937,22 +1937,21 @@ static void srpt_process_send_completion(struct ib_cq *cq, struct srpt_rdma_ch *ch, struct ib_wc *wc) { - struct srpt_send_ioctx *send_ioctx; uint32_t index; enum srpt_opcode opcode; index = idx_from_wr_id(wc->wr_id); opcode = opcode_from_wr_id(wc->wr_id); - send_ioctx = ch->ioctx_ring[index]; if (wc->status == IB_WC_SUCCESS) { - if (opcode == SRPT_SEND) - srpt_handle_send_comp(ch, send_ioctx, + if (opcode == SRPT_SEND) { + srpt_handle_send_comp(ch, ch->ioctx_ring[index], srpt_send_context); - else { - EXTRACHECKS_WARN_ON(opcode != SRPT_RDMA_ABORT && - wc->opcode != IB_WC_RDMA_READ); - srpt_handle_rdma_comp(ch, send_ioctx, opcode, + } else if (opcode == SRPT_RDMA_READ_LAST || + opcode == SRPT_RDMA_ABORT) { + srpt_handle_rdma_comp(ch, ch->ioctx_ring[index], opcode, srpt_xmt_rsp_context); + } else if (opcode != SRPT_RDMA_ZEROLENGTH_WRITE) { + WARN(true, "unexpected opcode %d", opcode); } } else { if (opcode == SRPT_SEND) { @@ -1960,11 +1959,15 @@ static void srpt_process_send_completion(struct ib_cq *cq, " status %d", index, wc->status); srpt_handle_send_err_comp(ch, wc->wr_id, srpt_send_context); - } else if (opcode != SRPT_RDMA_MID) { + } else if (opcode == SRPT_RDMA_READ_LAST || + opcode == SRPT_RDMA_WRITE_LAST) { PRINT_INFO("RDMA t %d for idx %u failed with status %d", opcode, index, wc->status); - srpt_handle_rdma_err_comp(ch, send_ioctx, opcode, - srpt_xmt_rsp_context); + srpt_handle_rdma_err_comp(ch, ch->ioctx_ring[index], + opcode, srpt_xmt_rsp_context); + } else if (opcode != SRPT_RDMA_MID && + opcode != SRPT_RDMA_ZEROLENGTH_WRITE) { + WARN(true, "unexpected opcode %d", opcode); } } @@ -2737,6 +2740,25 @@ static void srpt_cm_rej_recv(struct ib_cm_id *cm_id) srpt_drain_channel(cm_id); } +/** + * srpt_zerolength_write() - Perform a zero-length RDMA write. + * + * A quote from the InfiniBand specification: C9-88: For an HCA responder + * using Reliable Connection service, for each zero-length RDMA READ or WRITE + * request, the R_Key shall not be validated, even if the request includes + * Immediate data. + */ +static int srpt_zerolength_write(struct srpt_rdma_ch *ch) +{ + struct ib_send_wr wr, *bad_wr; + + memset(&wr, 0, sizeof(wr)); + wr.opcode = IB_WR_RDMA_WRITE; + wr.wr_id = encode_wr_id(SRPT_RDMA_ZEROLENGTH_WRITE, 0xffffffffUL); + wr.send_flags = IB_SEND_SIGNALED; + return ib_post_send(ch->qp, &wr, &bad_wr); +} + /** * srpt_cm_rtu_recv() - Process IB CM RTU_RECEIVED and USER_ESTABLISHED events. * @@ -2752,6 +2774,7 @@ static void srpt_cm_rtu_recv(struct ib_cm_id *cm_id) if (ret == 0) { smp_mb(); ch->rts = true; + WARN_ON(srpt_zerolength_write(ch) < 0); } else { srpt_close_ch(ch); } diff --git a/srpt/src/ib_srpt.h b/srpt/src/ib_srpt.h index 8661a23cd..a9cdbad85 100644 --- a/srpt/src/ib_srpt.h +++ b/srpt/src/ib_srpt.h @@ -139,6 +139,7 @@ enum srpt_opcode { SRPT_RDMA_ABORT, SRPT_RDMA_READ_LAST, SRPT_RDMA_WRITE_LAST, + SRPT_RDMA_ZEROLENGTH_WRITE, }; static inline u64 encode_wr_id(enum srpt_opcode opcode, u32 idx)