@@ -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-
222200static struct svc_rdma_write_info *
223201svc_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 */
637653int 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/**
0 commit comments