Commit 2239535f authored by Chuck Lever's avatar Chuck Lever
Browse files

svcrdma: Factor out WR chain linking into helper



svc_rdma_prepare_write_chunk() and svc_rdma_prepare_reply_chunk()
contain identical code for linking RDMA R/W work requests onto a
Send context's WR chain. This duplication increases maintenance
burden and risks divergent bug fixes.

Introduce svc_rdma_cc_link_wrs() to consolidate the WR chain
linking logic. The helper walks the chunk context's rwctxts list,
chains each WR via rdma_rw_ctx_wrs(), and updates the Send
context's chain head and SQE count. Completion signaling is
requested only for the tail WR (posted first).

No functional change.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent d16f060f
Loading
Loading
Loading
Loading
+28 −39
Original line number Diff line number Diff line
@@ -619,15 +619,32 @@ static int svc_rdma_xb_write(const struct xdr_buf *xdr, void *data)
	return xdr->len;
}

/*
 * svc_rdma_prepare_write_chunk - Link Write WRs for @chunk onto @sctxt's chain
 *
 * Write WRs are prepended to the Send WR chain so that a single
 * ib_post_send() posts both RDMA Writes and the final Send. Only
 * the first WR in each chunk gets a CQE for error detection;
 * subsequent WRs complete without individual completion events.
 * The Send WR's signaled completion indicates all chained
 * operations have finished.
/* Link chunk WRs onto @sctxt's WR chain. Completion is requested
 * for the tail WR, which is posted first.
 */
static void svc_rdma_cc_link_wrs(struct svcxprt_rdma *rdma,
				 struct svc_rdma_send_ctxt *sctxt,
				 struct svc_rdma_chunk_ctxt *cc)
{
	struct ib_send_wr *first_wr;
	struct list_head *pos;
	struct ib_cqe *cqe;

	first_wr = sctxt->sc_wr_chain;
	cqe = &cc->cc_cqe;
	list_for_each(pos, &cc->cc_rwctxts) {
		struct svc_rdma_rw_ctxt *rwc;

		rwc = list_entry(pos, struct svc_rdma_rw_ctxt, rw_list);
		first_wr = rdma_rw_ctx_wrs(&rwc->rw_ctx, rdma->sc_qp,
					   rdma->sc_port_num, cqe, first_wr);
		cqe = NULL;
	}
	sctxt->sc_wr_chain = first_wr;
	sctxt->sc_sqecount += cc->cc_sqecount;
}

/* Link Write WRs for @chunk onto @sctxt's WR chain.
 */
static int svc_rdma_prepare_write_chunk(struct svcxprt_rdma *rdma,
					struct svc_rdma_send_ctxt *sctxt,
@@ -636,10 +653,7 @@ static int svc_rdma_prepare_write_chunk(struct svcxprt_rdma *rdma,
{
	struct svc_rdma_write_info *info;
	struct svc_rdma_chunk_ctxt *cc;
	struct ib_send_wr *first_wr;
	struct xdr_buf payload;
	struct list_head *pos;
	struct ib_cqe *cqe;
	int ret;

	if (xdr_buf_subsegment(xdr, &payload, chunk->ch_position,
@@ -659,18 +673,7 @@ static int svc_rdma_prepare_write_chunk(struct svcxprt_rdma *rdma,
	if (unlikely(sctxt->sc_sqecount + cc->cc_sqecount > rdma->sc_sq_depth))
		goto out_err;

	first_wr = sctxt->sc_wr_chain;
	cqe = &cc->cc_cqe;
	list_for_each(pos, &cc->cc_rwctxts) {
		struct svc_rdma_rw_ctxt *rwc;

		rwc = list_entry(pos, struct svc_rdma_rw_ctxt, rw_list);
		first_wr = rdma_rw_ctx_wrs(&rwc->rw_ctx, rdma->sc_qp,
					   rdma->sc_port_num, cqe, first_wr);
		cqe = NULL;
	}
	sctxt->sc_wr_chain = first_wr;
	sctxt->sc_sqecount += cc->cc_sqecount;
	svc_rdma_cc_link_wrs(rdma, sctxt, cc);
	list_add(&info->wi_list, &sctxt->sc_write_info_list);

	trace_svcrdma_post_write_chunk(&cc->cc_cid, cc->cc_sqecount);
@@ -732,9 +735,6 @@ int svc_rdma_prepare_reply_chunk(struct svcxprt_rdma *rdma,
{
	struct svc_rdma_write_info *info = &sctxt->sc_reply_info;
	struct svc_rdma_chunk_ctxt *cc = &info->wi_cc;
	struct ib_send_wr *first_wr;
	struct list_head *pos;
	struct ib_cqe *cqe;
	int ret;

	info->wi_rdma = rdma;
@@ -748,18 +748,7 @@ int svc_rdma_prepare_reply_chunk(struct svcxprt_rdma *rdma,
	if (ret < 0)
		return ret;

	first_wr = sctxt->sc_wr_chain;
	cqe = &cc->cc_cqe;
	list_for_each(pos, &cc->cc_rwctxts) {
		struct svc_rdma_rw_ctxt *rwc;

		rwc = list_entry(pos, struct svc_rdma_rw_ctxt, rw_list);
		first_wr = rdma_rw_ctx_wrs(&rwc->rw_ctx, rdma->sc_qp,
					   rdma->sc_port_num, cqe, first_wr);
		cqe = NULL;
	}
	sctxt->sc_wr_chain = first_wr;
	sctxt->sc_sqecount += cc->cc_sqecount;
	svc_rdma_cc_link_wrs(rdma, sctxt, cc);

	trace_svcrdma_post_reply_chunk(&cc->cc_cid, cc->cc_sqecount);
	return xdr->len;