Skip to content

Commit a1f5788

Browse files
committed
svcrdma: Move write_info for Reply chunks into struct svc_rdma_send_ctxt
Since the RPC transaction's svc_rdma_send_ctxt will stay around for the duration of the RDMA Write operation, the write_info structure for the Reply chunk can reside in the request's svc_rdma_send_ctxt instead of being allocated separately. Signed-off-by: Chuck Lever <[email protected]>
1 parent 71b4353 commit a1f5788

File tree

4 files changed

+82
-40
lines changed

4 files changed

+82
-40
lines changed

include/linux/sunrpc/svc_rdma.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,29 @@ struct svc_rdma_recv_ctxt {
203203
struct page *rc_pages[RPCSVC_MAXPAGES];
204204
};
205205

206+
/*
207+
* State for sending a Write chunk.
208+
* - Tracks progress of writing one chunk over all its segments
209+
* - Stores arguments for the SGL constructor functions
210+
*/
211+
struct svc_rdma_write_info {
212+
struct svcxprt_rdma *wi_rdma;
213+
214+
const struct svc_rdma_chunk *wi_chunk;
215+
216+
/* write state of this chunk */
217+
unsigned int wi_seg_off;
218+
unsigned int wi_seg_no;
219+
220+
/* SGL constructor arguments */
221+
const struct xdr_buf *wi_xdr;
222+
unsigned char *wi_base;
223+
unsigned int wi_next_off;
224+
225+
struct svc_rdma_chunk_ctxt wi_cc;
226+
struct work_struct wi_work;
227+
};
228+
206229
struct svc_rdma_send_ctxt {
207230
struct llist_node sc_node;
208231
struct rpc_rdma_cid sc_cid;
@@ -215,6 +238,7 @@ struct svc_rdma_send_ctxt {
215238
struct ib_cqe sc_cqe;
216239
struct xdr_buf sc_hdrbuf;
217240
struct xdr_stream sc_stream;
241+
struct svc_rdma_write_info sc_reply_info;
218242
void *sc_xprt_buf;
219243
int sc_page_count;
220244
int sc_cur_sge_no;
@@ -249,6 +273,7 @@ extern int svc_rdma_send_write_chunk(struct svcxprt_rdma *rdma,
249273
const struct xdr_buf *xdr);
250274
extern int svc_rdma_send_reply_chunk(struct svcxprt_rdma *rdma,
251275
const struct svc_rdma_recv_ctxt *rctxt,
276+
struct svc_rdma_send_ctxt *sctxt,
252277
const struct xdr_buf *xdr);
253278
extern int svc_rdma_process_read_list(struct svcxprt_rdma *rdma,
254279
struct svc_rqst *rqstp,

include/trace/events/rpcrdma.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2118,6 +2118,10 @@ DEFINE_SIMPLE_CID_EVENT(svcrdma_wc_write);
21182118
DEFINE_SEND_FLUSH_EVENT(svcrdma_wc_write_flush);
21192119
DEFINE_SEND_FLUSH_EVENT(svcrdma_wc_write_err);
21202120

2121+
DEFINE_SIMPLE_CID_EVENT(svcrdma_wc_reply);
2122+
DEFINE_SEND_FLUSH_EVENT(svcrdma_wc_reply_flush);
2123+
DEFINE_SEND_FLUSH_EVENT(svcrdma_wc_reply_err);
2124+
21212125
TRACE_EVENT(svcrdma_qp_error,
21222126
TP_PROTO(
21232127
const struct ib_event *event,

net/sunrpc/xprtrdma/svc_rdma_rw.c

Lines changed: 52 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -197,28 +197,6 @@ void svc_rdma_cc_release(struct svcxprt_rdma *rdma,
197197
llist_add_batch(first, last, &rdma->sc_rw_ctxts);
198198
}
199199

200-
/* State for sending a Write or Reply chunk.
201-
* - Tracks progress of writing one chunk over all its segments
202-
* - Stores arguments for the SGL constructor functions
203-
*/
204-
struct svc_rdma_write_info {
205-
struct svcxprt_rdma *wi_rdma;
206-
207-
const struct svc_rdma_chunk *wi_chunk;
208-
209-
/* write state of this chunk */
210-
unsigned int wi_seg_off;
211-
unsigned int wi_seg_no;
212-
213-
/* SGL constructor arguments */
214-
const struct xdr_buf *wi_xdr;
215-
unsigned char *wi_base;
216-
unsigned int wi_next_off;
217-
218-
struct svc_rdma_chunk_ctxt wi_cc;
219-
struct work_struct wi_work;
220-
};
221-
222200
static struct svc_rdma_write_info *
223201
svc_rdma_write_info_alloc(struct svcxprt_rdma *rdma,
224202
const struct svc_rdma_chunk *chunk)
@@ -252,6 +230,43 @@ static void svc_rdma_write_info_free(struct svc_rdma_write_info *info)
252230
queue_work(svcrdma_wq, &info->wi_work);
253231
}
254232

233+
static void svc_rdma_reply_chunk_release(struct svcxprt_rdma *rdma,
234+
struct svc_rdma_chunk_ctxt *cc)
235+
{
236+
svc_rdma_wake_send_waiters(rdma, cc->cc_sqecount);
237+
svc_rdma_cc_release(rdma, cc, DMA_TO_DEVICE);
238+
}
239+
240+
/**
241+
* svc_rdma_reply_done - Reply chunk Write completion handler
242+
* @cq: controlling Completion Queue
243+
* @wc: Work Completion report
244+
*
245+
* Pages under I/O are released by a subsequent Send completion.
246+
*/
247+
static void svc_rdma_reply_done(struct ib_cq *cq, struct ib_wc *wc)
248+
{
249+
struct ib_cqe *cqe = wc->wr_cqe;
250+
struct svc_rdma_chunk_ctxt *cc =
251+
container_of(cqe, struct svc_rdma_chunk_ctxt, cc_cqe);
252+
struct svcxprt_rdma *rdma = cq->cq_context;
253+
254+
switch (wc->status) {
255+
case IB_WC_SUCCESS:
256+
trace_svcrdma_wc_reply(&cc->cc_cid);
257+
svc_rdma_reply_chunk_release(rdma, cc);
258+
return;
259+
case IB_WC_WR_FLUSH_ERR:
260+
trace_svcrdma_wc_reply_flush(wc, &cc->cc_cid);
261+
break;
262+
default:
263+
trace_svcrdma_wc_reply_err(wc, &cc->cc_cid);
264+
}
265+
266+
svc_rdma_reply_chunk_release(rdma, cc);
267+
svc_xprt_deferred_close(&rdma->sc_xprt);
268+
}
269+
255270
/**
256271
* svc_rdma_write_done - Write chunk completion
257272
* @cq: controlling Completion Queue
@@ -624,7 +639,8 @@ int svc_rdma_send_write_chunk(struct svcxprt_rdma *rdma,
624639
/**
625640
* svc_rdma_send_reply_chunk - Write all segments in the Reply chunk
626641
* @rdma: controlling RDMA transport
627-
* @rctxt: Write and Reply chunks from client
642+
* @rctxt: Write and Reply chunks provisioned by the client
643+
* @sctxt: Send WR resources
628644
* @xdr: xdr_buf containing an RPC Reply
629645
*
630646
* Returns a non-negative number of bytes the chunk consumed, or
@@ -636,37 +652,34 @@ int svc_rdma_send_write_chunk(struct svcxprt_rdma *rdma,
636652
*/
637653
int svc_rdma_send_reply_chunk(struct svcxprt_rdma *rdma,
638654
const struct svc_rdma_recv_ctxt *rctxt,
655+
struct svc_rdma_send_ctxt *sctxt,
639656
const struct xdr_buf *xdr)
640657
{
641-
struct svc_rdma_write_info *info;
642-
struct svc_rdma_chunk_ctxt *cc;
643-
struct svc_rdma_chunk *chunk;
658+
struct svc_rdma_write_info *info = &sctxt->sc_reply_info;
659+
struct svc_rdma_chunk_ctxt *cc = &info->wi_cc;
644660
int ret;
645661

646-
if (pcl_is_empty(&rctxt->rc_reply_pcl))
647-
return 0;
662+
if (likely(pcl_is_empty(&rctxt->rc_reply_pcl)))
663+
return 0; /* client provided no Reply chunk */
648664

649-
chunk = pcl_first_chunk(&rctxt->rc_reply_pcl);
650-
info = svc_rdma_write_info_alloc(rdma, chunk);
651-
if (!info)
652-
return -ENOMEM;
653-
cc = &info->wi_cc;
665+
info->wi_rdma = rdma;
666+
info->wi_chunk = pcl_first_chunk(&rctxt->rc_reply_pcl);
667+
info->wi_seg_off = 0;
668+
info->wi_seg_no = 0;
669+
svc_rdma_cc_init(rdma, &info->wi_cc);
670+
info->wi_cc.cc_cqe.done = svc_rdma_reply_done;
654671

655672
ret = pcl_process_nonpayloads(&rctxt->rc_write_pcl, xdr,
656673
svc_rdma_xb_write, info);
657674
if (ret < 0)
658-
goto out_err;
675+
return ret;
659676

660677
trace_svcrdma_post_reply_chunk(&cc->cc_cid, cc->cc_sqecount);
661678
ret = svc_rdma_post_chunk_ctxt(rdma, cc);
662679
if (ret < 0)
663-
goto out_err;
680+
return ret;
664681

665682
return xdr->len;
666-
667-
out_err:
668-
svc_rdma_write_info_free(info);
669-
return ret;
670683
}
671684

672685
/**

net/sunrpc/xprtrdma/svc_rdma_sendto.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,7 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
10121012
if (!p)
10131013
goto put_ctxt;
10141014

1015-
ret = svc_rdma_send_reply_chunk(rdma, rctxt, &rqstp->rq_res);
1015+
ret = svc_rdma_send_reply_chunk(rdma, rctxt, sctxt, &rqstp->rq_res);
10161016
if (ret < 0)
10171017
goto reply_chunk;
10181018
rc_size = ret;

0 commit comments

Comments
 (0)