@@ -197,28 +197,6 @@ void svc_rdma_cc_release(struct svcxprt_rdma *rdma,
197
197
llist_add_batch (first , last , & rdma -> sc_rw_ctxts );
198
198
}
199
199
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
-
222
200
static struct svc_rdma_write_info *
223
201
svc_rdma_write_info_alloc (struct svcxprt_rdma * rdma ,
224
202
const struct svc_rdma_chunk * chunk )
@@ -252,6 +230,43 @@ static void svc_rdma_write_info_free(struct svc_rdma_write_info *info)
252
230
queue_work (svcrdma_wq , & info -> wi_work );
253
231
}
254
232
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
+
255
270
/**
256
271
* svc_rdma_write_done - Write chunk completion
257
272
* @cq: controlling Completion Queue
@@ -624,7 +639,8 @@ int svc_rdma_send_write_chunk(struct svcxprt_rdma *rdma,
624
639
/**
625
640
* svc_rdma_send_reply_chunk - Write all segments in the Reply chunk
626
641
* @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
628
644
* @xdr: xdr_buf containing an RPC Reply
629
645
*
630
646
* 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,
636
652
*/
637
653
int svc_rdma_send_reply_chunk (struct svcxprt_rdma * rdma ,
638
654
const struct svc_rdma_recv_ctxt * rctxt ,
655
+ struct svc_rdma_send_ctxt * sctxt ,
639
656
const struct xdr_buf * xdr )
640
657
{
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 ;
644
660
int ret ;
645
661
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 */
648
664
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 ;
654
671
655
672
ret = pcl_process_nonpayloads (& rctxt -> rc_write_pcl , xdr ,
656
673
svc_rdma_xb_write , info );
657
674
if (ret < 0 )
658
- goto out_err ;
675
+ return ret ;
659
676
660
677
trace_svcrdma_post_reply_chunk (& cc -> cc_cid , cc -> cc_sqecount );
661
678
ret = svc_rdma_post_chunk_ctxt (rdma , cc );
662
679
if (ret < 0 )
663
- goto out_err ;
680
+ return ret ;
664
681
665
682
return xdr -> len ;
666
-
667
- out_err :
668
- svc_rdma_write_info_free (info );
669
- return ret ;
670
683
}
671
684
672
685
/**
0 commit comments