mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 04:21:09 -04:00
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: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user