1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2016-2018 Oracle. All rights reserved.
4 *
5 * Use the core R/W API to move RPC-over-RDMA Read and Write chunks.
6 */
7
8 #include <linux/bvec.h>
9 #include <linux/overflow.h>
10 #include <rdma/rw.h>
11
12 #include <linux/sunrpc/xdr.h>
13 #include <linux/sunrpc/rpc_rdma.h>
14 #include <linux/sunrpc/svc_rdma.h>
15
16 #include "xprt_rdma.h"
17 #include <trace/events/rpcrdma.h>
18
19 static void svc_rdma_write_done(struct ib_cq *cq, struct ib_wc *wc);
20 static void svc_rdma_wc_read_done(struct ib_cq *cq, struct ib_wc *wc);
21
22 /* Each R/W context contains state for one chain of RDMA Read or
23 * Write Work Requests.
24 *
25 * Each WR chain handles a single contiguous server-side buffer.
26 * - each xdr_buf iovec is a single contiguous buffer
27 * - the xdr_buf pages array is a single contiguous buffer because the
28 * second through the last element always start on a page boundary
29 *
30 * Each WR chain handles only one R_key. Each RPC-over-RDMA segment
31 * from a client may contain a unique R_key, so each WR chain moves
32 * up to one segment at a time.
33 *
34 * The inline bvec array is sized to handle most I/O requests without
35 * additional allocation. Larger requests fall back to dynamic allocation.
36 * These contexts are created on demand, but cached and reused until
37 * the controlling svcxprt_rdma is destroyed.
38 */
39 struct svc_rdma_rw_ctxt {
40 struct llist_node rw_node;
41 struct list_head rw_list;
42 struct rdma_rw_ctx rw_ctx;
43 unsigned int rw_nents;
44 unsigned int rw_first_bvec_nents;
45 struct bio_vec *rw_bvec;
46 struct bio_vec rw_first_bvec[];
47 };
48
49 static void svc_rdma_put_rw_ctxt(struct svcxprt_rdma *rdma,
50 struct svc_rdma_rw_ctxt *ctxt);
51
52 static inline struct svc_rdma_rw_ctxt *
svc_rdma_next_ctxt(struct list_head * list)53 svc_rdma_next_ctxt(struct list_head *list)
54 {
55 return list_first_entry_or_null(list, struct svc_rdma_rw_ctxt,
56 rw_list);
57 }
58
59 static struct svc_rdma_rw_ctxt *
svc_rdma_get_rw_ctxt(struct svcxprt_rdma * rdma,unsigned int nr_bvec)60 svc_rdma_get_rw_ctxt(struct svcxprt_rdma *rdma, unsigned int nr_bvec)
61 {
62 struct ib_device *dev = rdma->sc_cm_id->device;
63 unsigned int first_bvec_nents = dev->attrs.max_send_sge;
64 struct svc_rdma_rw_ctxt *ctxt;
65 struct llist_node *node;
66
67 spin_lock(&rdma->sc_rw_ctxt_lock);
68 node = llist_del_first(&rdma->sc_rw_ctxts);
69 spin_unlock(&rdma->sc_rw_ctxt_lock);
70 if (node) {
71 ctxt = llist_entry(node, struct svc_rdma_rw_ctxt, rw_node);
72 } else {
73 ctxt = kmalloc_node(struct_size(ctxt, rw_first_bvec,
74 first_bvec_nents),
75 GFP_KERNEL, ibdev_to_node(dev));
76 if (!ctxt)
77 goto out_noctx;
78
79 INIT_LIST_HEAD(&ctxt->rw_list);
80 ctxt->rw_first_bvec_nents = first_bvec_nents;
81 }
82
83 if (nr_bvec <= ctxt->rw_first_bvec_nents) {
84 ctxt->rw_bvec = ctxt->rw_first_bvec;
85 } else {
86 ctxt->rw_bvec = kmalloc_array_node(nr_bvec,
87 sizeof(*ctxt->rw_bvec),
88 GFP_KERNEL,
89 ibdev_to_node(dev));
90 if (!ctxt->rw_bvec)
91 goto out_free;
92 }
93 return ctxt;
94
95 out_free:
96 /* Return cached contexts to cache; free freshly allocated ones */
97 if (node)
98 svc_rdma_put_rw_ctxt(rdma, ctxt);
99 else
100 kfree(ctxt);
101 out_noctx:
102 trace_svcrdma_rwctx_empty(rdma, nr_bvec);
103 return NULL;
104 }
105
__svc_rdma_put_rw_ctxt(struct svc_rdma_rw_ctxt * ctxt,struct llist_head * list)106 static void __svc_rdma_put_rw_ctxt(struct svc_rdma_rw_ctxt *ctxt,
107 struct llist_head *list)
108 {
109 if (ctxt->rw_bvec != ctxt->rw_first_bvec)
110 kfree(ctxt->rw_bvec);
111 llist_add(&ctxt->rw_node, list);
112 }
113
svc_rdma_put_rw_ctxt(struct svcxprt_rdma * rdma,struct svc_rdma_rw_ctxt * ctxt)114 static void svc_rdma_put_rw_ctxt(struct svcxprt_rdma *rdma,
115 struct svc_rdma_rw_ctxt *ctxt)
116 {
117 __svc_rdma_put_rw_ctxt(ctxt, &rdma->sc_rw_ctxts);
118 }
119
120 /**
121 * svc_rdma_destroy_rw_ctxts - Free accumulated R/W contexts
122 * @rdma: transport about to be destroyed
123 *
124 */
svc_rdma_destroy_rw_ctxts(struct svcxprt_rdma * rdma)125 void svc_rdma_destroy_rw_ctxts(struct svcxprt_rdma *rdma)
126 {
127 struct svc_rdma_rw_ctxt *ctxt;
128 struct llist_node *node;
129
130 while ((node = llist_del_first(&rdma->sc_rw_ctxts)) != NULL) {
131 ctxt = llist_entry(node, struct svc_rdma_rw_ctxt, rw_node);
132 kfree(ctxt);
133 }
134 }
135
136 /**
137 * svc_rdma_rw_ctx_init - Prepare a R/W context for I/O
138 * @rdma: controlling transport instance
139 * @ctxt: R/W context to prepare
140 * @offset: RDMA offset
141 * @handle: RDMA tag/handle
142 * @length: total number of bytes in the bvec array
143 * @direction: I/O direction
144 *
145 * Returns on success, the number of WQEs that will be needed
146 * on the workqueue, or a negative errno.
147 */
svc_rdma_rw_ctx_init(struct svcxprt_rdma * rdma,struct svc_rdma_rw_ctxt * ctxt,u64 offset,u32 handle,unsigned int length,enum dma_data_direction direction)148 static int svc_rdma_rw_ctx_init(struct svcxprt_rdma *rdma,
149 struct svc_rdma_rw_ctxt *ctxt,
150 u64 offset, u32 handle, unsigned int length,
151 enum dma_data_direction direction)
152 {
153 struct bvec_iter iter = {
154 .bi_size = length,
155 };
156 int ret;
157
158 ret = rdma_rw_ctx_init_bvec(&ctxt->rw_ctx, rdma->sc_qp,
159 rdma->sc_port_num,
160 ctxt->rw_bvec, ctxt->rw_nents,
161 iter, offset, handle, direction);
162 if (unlikely(ret < 0)) {
163 trace_svcrdma_dma_map_rw_err(rdma, offset, handle,
164 ctxt->rw_nents, ret);
165 svc_rdma_put_rw_ctxt(rdma, ctxt);
166 }
167 return ret;
168 }
169
170 /**
171 * svc_rdma_cc_init - Initialize an svc_rdma_chunk_ctxt
172 * @rdma: controlling transport instance
173 * @cc: svc_rdma_chunk_ctxt to be initialized
174 */
svc_rdma_cc_init(struct svcxprt_rdma * rdma,struct svc_rdma_chunk_ctxt * cc)175 void svc_rdma_cc_init(struct svcxprt_rdma *rdma,
176 struct svc_rdma_chunk_ctxt *cc)
177 {
178 struct rpc_rdma_cid *cid = &cc->cc_cid;
179
180 if (unlikely(!cid->ci_completion_id))
181 svc_rdma_send_cid_init(rdma, cid);
182
183 INIT_LIST_HEAD(&cc->cc_rwctxts);
184 cc->cc_sqecount = 0;
185 }
186
187 /**
188 * svc_rdma_cc_release - Release resources held by a svc_rdma_chunk_ctxt
189 * @rdma: controlling transport instance
190 * @cc: svc_rdma_chunk_ctxt to be released
191 * @dir: DMA direction
192 */
svc_rdma_cc_release(struct svcxprt_rdma * rdma,struct svc_rdma_chunk_ctxt * cc,enum dma_data_direction dir)193 void svc_rdma_cc_release(struct svcxprt_rdma *rdma,
194 struct svc_rdma_chunk_ctxt *cc,
195 enum dma_data_direction dir)
196 {
197 struct llist_node *first, *last;
198 struct svc_rdma_rw_ctxt *ctxt;
199
200 trace_svcrdma_cc_release(&cc->cc_cid, cc->cc_sqecount);
201
202 first = last = NULL;
203 while ((ctxt = svc_rdma_next_ctxt(&cc->cc_rwctxts)) != NULL) {
204 list_del(&ctxt->rw_list);
205
206 rdma_rw_ctx_destroy_bvec(&ctxt->rw_ctx, rdma->sc_qp,
207 rdma->sc_port_num,
208 ctxt->rw_bvec, ctxt->rw_nents, dir);
209 if (ctxt->rw_bvec != ctxt->rw_first_bvec)
210 kfree(ctxt->rw_bvec);
211
212 ctxt->rw_node.next = first;
213 first = &ctxt->rw_node;
214 if (!last)
215 last = first;
216 }
217 if (first)
218 llist_add_batch(first, last, &rdma->sc_rw_ctxts);
219 }
220
221 static struct svc_rdma_write_info *
svc_rdma_write_info_alloc(struct svcxprt_rdma * rdma,const struct svc_rdma_chunk * chunk)222 svc_rdma_write_info_alloc(struct svcxprt_rdma *rdma,
223 const struct svc_rdma_chunk *chunk)
224 {
225 struct svc_rdma_write_info *info;
226
227 info = kzalloc_node(sizeof(*info), GFP_KERNEL,
228 ibdev_to_node(rdma->sc_cm_id->device));
229 if (!info)
230 return info;
231
232 info->wi_rdma = rdma;
233 info->wi_chunk = chunk;
234 svc_rdma_cc_init(rdma, &info->wi_cc);
235 info->wi_cc.cc_cqe.done = svc_rdma_write_done;
236 return info;
237 }
238
svc_rdma_write_info_free(struct svc_rdma_write_info * info)239 static void svc_rdma_write_info_free(struct svc_rdma_write_info *info)
240 {
241 svc_rdma_cc_release(info->wi_rdma, &info->wi_cc, DMA_TO_DEVICE);
242 kfree(info);
243 }
244
245 /**
246 * svc_rdma_write_chunk_release - Release Write chunk I/O resources
247 * @rdma: controlling transport
248 * @ctxt: Send context that is being released
249 *
250 * Write chunk resources remain live until Send completion because
251 * Write WRs are chained to the Send WR. This function releases all
252 * write_info structures accumulated on @ctxt->sc_write_info_list.
253 */
svc_rdma_write_chunk_release(struct svcxprt_rdma * rdma,struct svc_rdma_send_ctxt * ctxt)254 void svc_rdma_write_chunk_release(struct svcxprt_rdma *rdma,
255 struct svc_rdma_send_ctxt *ctxt)
256 {
257 struct svc_rdma_write_info *info;
258
259 while (!list_empty(&ctxt->sc_write_info_list)) {
260 info = list_first_entry(&ctxt->sc_write_info_list,
261 struct svc_rdma_write_info, wi_list);
262 list_del(&info->wi_list);
263 svc_rdma_write_info_free(info);
264 }
265 }
266
267 /**
268 * svc_rdma_reply_chunk_release - Release Reply chunk I/O resources
269 * @rdma: controlling transport
270 * @ctxt: Send context that is being released
271 */
svc_rdma_reply_chunk_release(struct svcxprt_rdma * rdma,struct svc_rdma_send_ctxt * ctxt)272 void svc_rdma_reply_chunk_release(struct svcxprt_rdma *rdma,
273 struct svc_rdma_send_ctxt *ctxt)
274 {
275 struct svc_rdma_chunk_ctxt *cc = &ctxt->sc_reply_info.wi_cc;
276
277 if (!cc->cc_sqecount)
278 return;
279 svc_rdma_cc_release(rdma, cc, DMA_TO_DEVICE);
280 }
281
282 /**
283 * svc_rdma_reply_done - Reply chunk Write completion handler
284 * @cq: controlling Completion Queue
285 * @wc: Work Completion report
286 *
287 * Pages under I/O are released by a subsequent Send completion.
288 */
svc_rdma_reply_done(struct ib_cq * cq,struct ib_wc * wc)289 static void svc_rdma_reply_done(struct ib_cq *cq, struct ib_wc *wc)
290 {
291 struct ib_cqe *cqe = wc->wr_cqe;
292 struct svc_rdma_chunk_ctxt *cc =
293 container_of(cqe, struct svc_rdma_chunk_ctxt, cc_cqe);
294 struct svcxprt_rdma *rdma = cq->cq_context;
295
296 switch (wc->status) {
297 case IB_WC_SUCCESS:
298 trace_svcrdma_wc_reply(&cc->cc_cid);
299 return;
300 case IB_WC_WR_FLUSH_ERR:
301 trace_svcrdma_wc_reply_flush(wc, &cc->cc_cid);
302 break;
303 default:
304 trace_svcrdma_wc_reply_err(wc, &cc->cc_cid);
305 }
306
307 svc_rdma_xprt_deferred_close(rdma);
308 }
309
310 /**
311 * svc_rdma_write_done - Write chunk completion
312 * @cq: controlling Completion Queue
313 * @wc: Work Completion
314 *
315 * Pages under I/O are freed by a subsequent Send completion.
316 */
svc_rdma_write_done(struct ib_cq * cq,struct ib_wc * wc)317 static void svc_rdma_write_done(struct ib_cq *cq, struct ib_wc *wc)
318 {
319 struct svcxprt_rdma *rdma = cq->cq_context;
320 struct ib_cqe *cqe = wc->wr_cqe;
321 struct svc_rdma_chunk_ctxt *cc =
322 container_of(cqe, struct svc_rdma_chunk_ctxt, cc_cqe);
323
324 switch (wc->status) {
325 case IB_WC_SUCCESS:
326 trace_svcrdma_wc_write(&cc->cc_cid);
327 return;
328 case IB_WC_WR_FLUSH_ERR:
329 trace_svcrdma_wc_write_flush(wc, &cc->cc_cid);
330 break;
331 default:
332 trace_svcrdma_wc_write_err(wc, &cc->cc_cid);
333 }
334
335 /* The RDMA Write has flushed, so the client won't get
336 * some of the outgoing RPC message. Signal the loss
337 * to the client by closing the connection.
338 */
339 svc_rdma_xprt_deferred_close(rdma);
340 }
341
342 /**
343 * svc_rdma_wc_read_done - Handle completion of an RDMA Read ctx
344 * @cq: controlling Completion Queue
345 * @wc: Work Completion
346 *
347 */
svc_rdma_wc_read_done(struct ib_cq * cq,struct ib_wc * wc)348 static void svc_rdma_wc_read_done(struct ib_cq *cq, struct ib_wc *wc)
349 {
350 struct svcxprt_rdma *rdma = cq->cq_context;
351 struct ib_cqe *cqe = wc->wr_cqe;
352 struct svc_rdma_chunk_ctxt *cc =
353 container_of(cqe, struct svc_rdma_chunk_ctxt, cc_cqe);
354 struct svc_rdma_recv_ctxt *ctxt;
355
356 svc_rdma_wake_send_waiters(rdma, cc->cc_sqecount);
357
358 ctxt = container_of(cc, struct svc_rdma_recv_ctxt, rc_cc);
359 switch (wc->status) {
360 case IB_WC_SUCCESS:
361 trace_svcrdma_wc_read(wc, &cc->cc_cid, ctxt->rc_readbytes,
362 cc->cc_posttime);
363
364 spin_lock(&rdma->sc_rq_dto_lock);
365 list_add_tail(&ctxt->rc_list, &rdma->sc_read_complete_q);
366 /* the unlock pairs with the smp_rmb in svc_xprt_ready */
367 set_bit(XPT_DATA, &rdma->sc_xprt.xpt_flags);
368 spin_unlock(&rdma->sc_rq_dto_lock);
369 svc_xprt_enqueue(&rdma->sc_xprt);
370 return;
371 case IB_WC_WR_FLUSH_ERR:
372 trace_svcrdma_wc_read_flush(wc, &cc->cc_cid);
373 break;
374 default:
375 trace_svcrdma_wc_read_err(wc, &cc->cc_cid);
376 }
377
378 /* The RDMA Read has flushed, so the incoming RPC message
379 * cannot be constructed and must be dropped. Signal the
380 * loss to the client by closing the connection.
381 */
382 svc_rdma_cc_release(rdma, cc, DMA_FROM_DEVICE);
383 svc_rdma_recv_ctxt_put(rdma, ctxt);
384 svc_rdma_xprt_deferred_close(rdma);
385 }
386
387 /*
388 * Assumptions:
389 * - If ib_post_send() succeeds, only one completion is expected,
390 * even if one or more WRs are flushed. This is true when posting
391 * an rdma_rw_ctx or when posting a single signaled WR.
392 */
svc_rdma_post_chunk_ctxt(struct svcxprt_rdma * rdma,struct svc_rdma_chunk_ctxt * cc)393 static int svc_rdma_post_chunk_ctxt(struct svcxprt_rdma *rdma,
394 struct svc_rdma_chunk_ctxt *cc)
395 {
396 struct ib_send_wr *first_wr;
397 const struct ib_send_wr *bad_wr;
398 struct list_head *tmp;
399 struct ib_cqe *cqe;
400 int ret;
401
402 might_sleep();
403
404 if (cc->cc_sqecount > rdma->sc_sq_depth)
405 return -EINVAL;
406
407 first_wr = NULL;
408 cqe = &cc->cc_cqe;
409 list_for_each(tmp, &cc->cc_rwctxts) {
410 struct svc_rdma_rw_ctxt *ctxt;
411
412 ctxt = list_entry(tmp, struct svc_rdma_rw_ctxt, rw_list);
413 first_wr = rdma_rw_ctx_wrs(&ctxt->rw_ctx, rdma->sc_qp,
414 rdma->sc_port_num, cqe, first_wr);
415 cqe = NULL;
416 }
417
418 ret = svc_rdma_sq_wait(rdma, &cc->cc_cid, cc->cc_sqecount);
419 if (ret < 0)
420 return ret;
421
422 cc->cc_posttime = ktime_get();
423 ret = ib_post_send(rdma->sc_qp, first_wr, &bad_wr);
424 if (ret)
425 return svc_rdma_post_send_err(rdma, &cc->cc_cid, bad_wr,
426 first_wr, cc->cc_sqecount,
427 ret);
428 return 0;
429 }
430
431 /* Build a bvec that covers one kvec in an xdr_buf.
432 */
svc_rdma_vec_to_bvec(struct svc_rdma_write_info * info,unsigned int len,struct svc_rdma_rw_ctxt * ctxt)433 static void svc_rdma_vec_to_bvec(struct svc_rdma_write_info *info,
434 unsigned int len,
435 struct svc_rdma_rw_ctxt *ctxt)
436 {
437 bvec_set_virt(&ctxt->rw_bvec[0], info->wi_base, len);
438 info->wi_base += len;
439
440 ctxt->rw_nents = 1;
441 }
442
443 /* Build a bvec array that covers part of an xdr_buf's pagelist.
444 */
svc_rdma_pagelist_to_bvec(struct svc_rdma_write_info * info,unsigned int remaining,struct svc_rdma_rw_ctxt * ctxt)445 static void svc_rdma_pagelist_to_bvec(struct svc_rdma_write_info *info,
446 unsigned int remaining,
447 struct svc_rdma_rw_ctxt *ctxt)
448 {
449 unsigned int bvec_idx, bvec_len, page_off, page_no;
450 const struct xdr_buf *xdr = info->wi_xdr;
451 struct page **page;
452
453 page_off = info->wi_next_off + xdr->page_base;
454 page_no = page_off >> PAGE_SHIFT;
455 page_off = offset_in_page(page_off);
456 page = xdr->pages + page_no;
457 info->wi_next_off += remaining;
458 bvec_idx = 0;
459 do {
460 bvec_len = min_t(unsigned int, remaining,
461 PAGE_SIZE - page_off);
462 bvec_set_page(&ctxt->rw_bvec[bvec_idx], *page, bvec_len,
463 page_off);
464 remaining -= bvec_len;
465 page_off = 0;
466 bvec_idx++;
467 page++;
468 } while (remaining);
469
470 ctxt->rw_nents = bvec_idx;
471 }
472
473 /* Construct RDMA Write WRs to send a portion of an xdr_buf containing
474 * an RPC Reply.
475 */
476 static int
svc_rdma_build_writes(struct svc_rdma_write_info * info,void (* constructor)(struct svc_rdma_write_info * info,unsigned int len,struct svc_rdma_rw_ctxt * ctxt),unsigned int remaining)477 svc_rdma_build_writes(struct svc_rdma_write_info *info,
478 void (*constructor)(struct svc_rdma_write_info *info,
479 unsigned int len,
480 struct svc_rdma_rw_ctxt *ctxt),
481 unsigned int remaining)
482 {
483 struct svc_rdma_chunk_ctxt *cc = &info->wi_cc;
484 struct svcxprt_rdma *rdma = info->wi_rdma;
485 const struct svc_rdma_segment *seg;
486 struct svc_rdma_rw_ctxt *ctxt;
487 int ret;
488
489 do {
490 unsigned int write_len;
491 u64 offset;
492
493 if (info->wi_seg_no >= info->wi_chunk->ch_segcount)
494 goto out_overflow;
495
496 seg = &info->wi_chunk->ch_segments[info->wi_seg_no];
497 write_len = min(remaining, seg->rs_length - info->wi_seg_off);
498 if (!write_len)
499 goto out_overflow;
500 ctxt = svc_rdma_get_rw_ctxt(rdma,
501 (write_len >> PAGE_SHIFT) + 2);
502 if (!ctxt)
503 return -ENOMEM;
504
505 constructor(info, write_len, ctxt);
506 offset = seg->rs_offset + info->wi_seg_off;
507 ret = svc_rdma_rw_ctx_init(rdma, ctxt, offset, seg->rs_handle,
508 write_len, DMA_TO_DEVICE);
509 if (ret < 0)
510 return -EIO;
511 percpu_counter_inc(&svcrdma_stat_write);
512
513 list_add(&ctxt->rw_list, &cc->cc_rwctxts);
514 cc->cc_sqecount += ret;
515 if (write_len == seg->rs_length - info->wi_seg_off) {
516 info->wi_seg_no++;
517 info->wi_seg_off = 0;
518 } else {
519 info->wi_seg_off += write_len;
520 }
521 remaining -= write_len;
522 } while (remaining);
523
524 return 0;
525
526 out_overflow:
527 trace_svcrdma_small_wrch_err(&cc->cc_cid, remaining, info->wi_seg_no,
528 info->wi_chunk->ch_segcount);
529 return -E2BIG;
530 }
531
532 /**
533 * svc_rdma_iov_write - Construct RDMA Writes from an iov
534 * @info: pointer to write arguments
535 * @iov: kvec to write
536 *
537 * Returns:
538 * On success, returns zero
539 * %-E2BIG if the client-provided Write chunk is too small
540 * %-ENOMEM if a resource has been exhausted
541 * %-EIO if an rdma-rw error occurred
542 */
svc_rdma_iov_write(struct svc_rdma_write_info * info,const struct kvec * iov)543 static int svc_rdma_iov_write(struct svc_rdma_write_info *info,
544 const struct kvec *iov)
545 {
546 info->wi_base = iov->iov_base;
547 return svc_rdma_build_writes(info, svc_rdma_vec_to_bvec,
548 iov->iov_len);
549 }
550
551 /**
552 * svc_rdma_pages_write - Construct RDMA Writes from pages
553 * @info: pointer to write arguments
554 * @xdr: xdr_buf with pages to write
555 * @offset: offset into the content of @xdr
556 * @length: number of bytes to write
557 *
558 * Returns:
559 * On success, returns zero
560 * %-E2BIG if the client-provided Write chunk is too small
561 * %-ENOMEM if a resource has been exhausted
562 * %-EIO if an rdma-rw error occurred
563 */
svc_rdma_pages_write(struct svc_rdma_write_info * info,const struct xdr_buf * xdr,unsigned int offset,unsigned long length)564 static int svc_rdma_pages_write(struct svc_rdma_write_info *info,
565 const struct xdr_buf *xdr,
566 unsigned int offset,
567 unsigned long length)
568 {
569 info->wi_xdr = xdr;
570 info->wi_next_off = offset - xdr->head[0].iov_len;
571 return svc_rdma_build_writes(info, svc_rdma_pagelist_to_bvec,
572 length);
573 }
574
575 /**
576 * svc_rdma_xb_write - Construct RDMA Writes to write an xdr_buf
577 * @xdr: xdr_buf to write
578 * @data: pointer to write arguments
579 *
580 * Returns:
581 * On success, returns zero
582 * %-E2BIG if the client-provided Write chunk is too small
583 * %-ENOMEM if a resource has been exhausted
584 * %-EIO if an rdma-rw error occurred
585 */
svc_rdma_xb_write(const struct xdr_buf * xdr,void * data)586 static int svc_rdma_xb_write(const struct xdr_buf *xdr, void *data)
587 {
588 struct svc_rdma_write_info *info = data;
589 int ret;
590
591 if (xdr->head[0].iov_len) {
592 ret = svc_rdma_iov_write(info, &xdr->head[0]);
593 if (ret < 0)
594 return ret;
595 }
596
597 if (xdr->page_len) {
598 ret = svc_rdma_pages_write(info, xdr, xdr->head[0].iov_len,
599 xdr->page_len);
600 if (ret < 0)
601 return ret;
602 }
603
604 if (xdr->tail[0].iov_len) {
605 ret = svc_rdma_iov_write(info, &xdr->tail[0]);
606 if (ret < 0)
607 return ret;
608 }
609
610 return xdr->len;
611 }
612
613 /* Link chunk WRs onto @sctxt's WR chain. Completion is requested
614 * for the tail WR, which is posted first.
615 */
svc_rdma_cc_link_wrs(struct svcxprt_rdma * rdma,struct svc_rdma_send_ctxt * sctxt,struct svc_rdma_chunk_ctxt * cc)616 static void svc_rdma_cc_link_wrs(struct svcxprt_rdma *rdma,
617 struct svc_rdma_send_ctxt *sctxt,
618 struct svc_rdma_chunk_ctxt *cc)
619 {
620 struct ib_send_wr *first_wr;
621 struct list_head *pos;
622 struct ib_cqe *cqe;
623
624 first_wr = sctxt->sc_wr_chain;
625 cqe = &cc->cc_cqe;
626 list_for_each(pos, &cc->cc_rwctxts) {
627 struct svc_rdma_rw_ctxt *rwc;
628
629 rwc = list_entry(pos, struct svc_rdma_rw_ctxt, rw_list);
630 first_wr = rdma_rw_ctx_wrs(&rwc->rw_ctx, rdma->sc_qp,
631 rdma->sc_port_num, cqe, first_wr);
632 cqe = NULL;
633 }
634 sctxt->sc_wr_chain = first_wr;
635 sctxt->sc_sqecount += cc->cc_sqecount;
636 }
637
638 /* Link Write WRs for @chunk onto @sctxt's WR chain.
639 */
svc_rdma_prepare_write_chunk(struct svcxprt_rdma * rdma,struct svc_rdma_send_ctxt * sctxt,const struct svc_rdma_chunk * chunk,const struct xdr_buf * xdr)640 static int svc_rdma_prepare_write_chunk(struct svcxprt_rdma *rdma,
641 struct svc_rdma_send_ctxt *sctxt,
642 const struct svc_rdma_chunk *chunk,
643 const struct xdr_buf *xdr)
644 {
645 struct svc_rdma_write_info *info;
646 struct svc_rdma_chunk_ctxt *cc;
647 struct xdr_buf payload;
648 int ret;
649
650 if (xdr_buf_subsegment(xdr, &payload, chunk->ch_position,
651 chunk->ch_payload_length))
652 return -EMSGSIZE;
653
654 info = svc_rdma_write_info_alloc(rdma, chunk);
655 if (!info)
656 return -ENOMEM;
657 cc = &info->wi_cc;
658
659 ret = svc_rdma_xb_write(&payload, info);
660 if (ret != payload.len)
661 goto out_err;
662
663 ret = -EINVAL;
664 if (unlikely(sctxt->sc_sqecount + cc->cc_sqecount > rdma->sc_sq_depth))
665 goto out_err;
666
667 svc_rdma_cc_link_wrs(rdma, sctxt, cc);
668 list_add(&info->wi_list, &sctxt->sc_write_info_list);
669
670 trace_svcrdma_post_write_chunk(&cc->cc_cid, cc->cc_sqecount);
671 return 0;
672
673 out_err:
674 svc_rdma_write_info_free(info);
675 return ret;
676 }
677
678 /**
679 * svc_rdma_prepare_write_list - Construct WR chain for sending Write list
680 * @rdma: controlling RDMA transport
681 * @rctxt: Write list provisioned by the client
682 * @sctxt: Send WR resources
683 * @xdr: xdr_buf containing an RPC Reply message
684 *
685 * Returns zero on success, or a negative errno if WR chain
686 * construction fails for one or more Write chunks.
687 */
svc_rdma_prepare_write_list(struct svcxprt_rdma * rdma,const struct svc_rdma_recv_ctxt * rctxt,struct svc_rdma_send_ctxt * sctxt,const struct xdr_buf * xdr)688 int svc_rdma_prepare_write_list(struct svcxprt_rdma *rdma,
689 const struct svc_rdma_recv_ctxt *rctxt,
690 struct svc_rdma_send_ctxt *sctxt,
691 const struct xdr_buf *xdr)
692 {
693 struct svc_rdma_chunk *chunk;
694 int ret;
695
696 pcl_for_each_chunk(chunk, &rctxt->rc_write_pcl) {
697 if (!chunk->ch_payload_length)
698 break;
699 ret = svc_rdma_prepare_write_chunk(rdma, sctxt, chunk, xdr);
700 if (ret < 0)
701 return ret;
702 }
703 return 0;
704 }
705
706 /**
707 * svc_rdma_prepare_reply_chunk - Construct WR chain for writing the Reply chunk
708 * @rdma: controlling RDMA transport
709 * @write_pcl: Write chunk list provided by client
710 * @reply_pcl: Reply chunk provided by client
711 * @sctxt: Send WR resources
712 * @xdr: xdr_buf containing an RPC Reply
713 *
714 * Returns a non-negative number of bytes the chunk consumed, or
715 * %-E2BIG if the payload was larger than the Reply chunk,
716 * %-EINVAL if client provided too many segments,
717 * %-ENOMEM if rdma_rw context pool was exhausted,
718 * %-ENOTCONN if posting failed (connection is lost),
719 * %-EIO if rdma_rw initialization failed (DMA mapping, etc).
720 */
svc_rdma_prepare_reply_chunk(struct svcxprt_rdma * rdma,const struct svc_rdma_pcl * write_pcl,const struct svc_rdma_pcl * reply_pcl,struct svc_rdma_send_ctxt * sctxt,const struct xdr_buf * xdr)721 int svc_rdma_prepare_reply_chunk(struct svcxprt_rdma *rdma,
722 const struct svc_rdma_pcl *write_pcl,
723 const struct svc_rdma_pcl *reply_pcl,
724 struct svc_rdma_send_ctxt *sctxt,
725 const struct xdr_buf *xdr)
726 {
727 struct svc_rdma_write_info *info = &sctxt->sc_reply_info;
728 struct svc_rdma_chunk_ctxt *cc = &info->wi_cc;
729 int ret;
730
731 info->wi_rdma = rdma;
732 info->wi_chunk = pcl_first_chunk(reply_pcl);
733 info->wi_seg_off = 0;
734 info->wi_seg_no = 0;
735 info->wi_cc.cc_cqe.done = svc_rdma_reply_done;
736
737 ret = pcl_process_nonpayloads(write_pcl, xdr,
738 svc_rdma_xb_write, info);
739 if (ret < 0)
740 return ret;
741
742 svc_rdma_cc_link_wrs(rdma, sctxt, cc);
743
744 trace_svcrdma_post_reply_chunk(&cc->cc_cid, cc->cc_sqecount);
745 return xdr->len;
746 }
747
748 /**
749 * svc_rdma_build_read_segment - Build RDMA Read WQEs to pull one RDMA segment
750 * @rqstp: RPC transaction context
751 * @head: context for ongoing I/O
752 * @segment: co-ordinates of remote memory to be read
753 *
754 * Returns:
755 * %0: the Read WR chain was constructed successfully
756 * %-EINVAL: there were not enough rq_pages to finish
757 * %-ENOMEM: allocating a local resources failed
758 * %-EIO: a DMA mapping error occurred
759 */
svc_rdma_build_read_segment(struct svc_rqst * rqstp,struct svc_rdma_recv_ctxt * head,const struct svc_rdma_segment * segment)760 static int svc_rdma_build_read_segment(struct svc_rqst *rqstp,
761 struct svc_rdma_recv_ctxt *head,
762 const struct svc_rdma_segment *segment)
763 {
764 struct svcxprt_rdma *rdma = svc_rdma_rqst_rdma(rqstp);
765 struct svc_rdma_chunk_ctxt *cc = &head->rc_cc;
766 unsigned int bvec_idx, nr_bvec, seg_len, len, total;
767 struct svc_rdma_rw_ctxt *ctxt;
768 int ret;
769
770 len = segment->rs_length;
771 if (check_add_overflow(head->rc_pageoff, len, &total))
772 return -EINVAL;
773 nr_bvec = PAGE_ALIGN(total) >> PAGE_SHIFT;
774 ctxt = svc_rdma_get_rw_ctxt(rdma, nr_bvec);
775 if (!ctxt)
776 return -ENOMEM;
777 ctxt->rw_nents = nr_bvec;
778
779 for (bvec_idx = 0; bvec_idx < ctxt->rw_nents; bvec_idx++) {
780 seg_len = min_t(unsigned int, len,
781 PAGE_SIZE - head->rc_pageoff);
782
783 if (!head->rc_pageoff)
784 head->rc_page_count++;
785
786 bvec_set_page(&ctxt->rw_bvec[bvec_idx],
787 rqstp->rq_pages[head->rc_curpage],
788 seg_len, head->rc_pageoff);
789
790 head->rc_pageoff += seg_len;
791 if (head->rc_pageoff == PAGE_SIZE) {
792 head->rc_curpage++;
793 head->rc_pageoff = 0;
794 }
795 len -= seg_len;
796
797 if (len && ((head->rc_curpage + 1) > rqstp->rq_maxpages))
798 goto out_put;
799 }
800
801 ret = svc_rdma_rw_ctx_init(rdma, ctxt, segment->rs_offset,
802 segment->rs_handle, segment->rs_length,
803 DMA_FROM_DEVICE);
804 if (ret < 0)
805 return -EIO;
806 percpu_counter_inc(&svcrdma_stat_read);
807
808 list_add(&ctxt->rw_list, &cc->cc_rwctxts);
809 cc->cc_sqecount += ret;
810 return 0;
811
812 out_put:
813 svc_rdma_put_rw_ctxt(rdma, ctxt);
814 trace_svcrdma_page_overrun_err(&cc->cc_cid, head->rc_curpage);
815 return -EINVAL;
816 }
817
818 /**
819 * svc_rdma_build_read_chunk - Build RDMA Read WQEs to pull one RDMA chunk
820 * @rqstp: RPC transaction context
821 * @head: context for ongoing I/O
822 * @chunk: Read chunk to pull
823 *
824 * Return values:
825 * %0: the Read WR chain was constructed successfully
826 * %-EINVAL: there were not enough resources to finish
827 * %-ENOMEM: allocating a local resources failed
828 * %-EIO: a DMA mapping error occurred
829 */
svc_rdma_build_read_chunk(struct svc_rqst * rqstp,struct svc_rdma_recv_ctxt * head,const struct svc_rdma_chunk * chunk)830 static int svc_rdma_build_read_chunk(struct svc_rqst *rqstp,
831 struct svc_rdma_recv_ctxt *head,
832 const struct svc_rdma_chunk *chunk)
833 {
834 const struct svc_rdma_segment *segment;
835 int ret;
836
837 ret = -EINVAL;
838 pcl_for_each_segment(segment, chunk) {
839 ret = svc_rdma_build_read_segment(rqstp, head, segment);
840 if (ret < 0)
841 break;
842 head->rc_readbytes += segment->rs_length;
843 }
844 return ret;
845 }
846
847 /**
848 * svc_rdma_copy_inline_range - Copy part of the inline content into pages
849 * @rqstp: RPC transaction context
850 * @head: context for ongoing I/O
851 * @offset: offset into the inline content of region to copy
852 * @remaining: length of region to copy
853 *
854 * Take a page at a time from rqstp->rq_pages and copy the inline
855 * content from the Receive buffer into that page. Update
856 * head->rc_curpage and head->rc_pageoff so that the next RDMA Read
857 * result will land contiguously with the copied content.
858 *
859 * Return values:
860 * %0: Inline content was successfully copied
861 * %-EINVAL: offset or length was incorrect
862 */
svc_rdma_copy_inline_range(struct svc_rqst * rqstp,struct svc_rdma_recv_ctxt * head,unsigned int offset,unsigned int remaining)863 static int svc_rdma_copy_inline_range(struct svc_rqst *rqstp,
864 struct svc_rdma_recv_ctxt *head,
865 unsigned int offset,
866 unsigned int remaining)
867 {
868 unsigned char *dst, *src = head->rc_saved_arg.head[0].iov_base;
869 unsigned int inline_len = head->rc_saved_arg.head[0].iov_len;
870 unsigned int page_no, numpages;
871
872 if (offset > inline_len || remaining > inline_len - offset)
873 return -EINVAL;
874
875 numpages = PAGE_ALIGN(head->rc_pageoff + remaining) >> PAGE_SHIFT;
876 for (page_no = 0; page_no < numpages; page_no++) {
877 unsigned int page_len;
878
879 if (head->rc_curpage >= rqstp->rq_maxpages)
880 return -EINVAL;
881
882 page_len = min_t(unsigned int, remaining,
883 PAGE_SIZE - head->rc_pageoff);
884
885 if (!head->rc_pageoff)
886 head->rc_page_count++;
887
888 dst = page_address(rqstp->rq_pages[head->rc_curpage]);
889 memcpy((unsigned char *)dst + head->rc_pageoff, src + offset, page_len);
890
891 head->rc_readbytes += page_len;
892 head->rc_pageoff += page_len;
893 if (head->rc_pageoff == PAGE_SIZE) {
894 head->rc_curpage++;
895 head->rc_pageoff = 0;
896 }
897 remaining -= page_len;
898 offset += page_len;
899 }
900
901 return 0;
902 }
903
904 /**
905 * svc_rdma_read_multiple_chunks - Construct RDMA Reads to pull data item Read chunks
906 * @rqstp: RPC transaction context
907 * @head: context for ongoing I/O
908 *
909 * The chunk data lands in rqstp->rq_arg as a series of contiguous pages,
910 * like an incoming TCP call.
911 *
912 * Return values:
913 * %0: RDMA Read WQEs were successfully built
914 * %-EINVAL: client provided too many chunks or segments,
915 * %-ENOMEM: rdma_rw context pool was exhausted,
916 * %-ENOTCONN: posting failed (connection is lost),
917 * %-EIO: rdma_rw initialization failed (DMA mapping, etc).
918 */
919 static noinline int
svc_rdma_read_multiple_chunks(struct svc_rqst * rqstp,struct svc_rdma_recv_ctxt * head)920 svc_rdma_read_multiple_chunks(struct svc_rqst *rqstp,
921 struct svc_rdma_recv_ctxt *head)
922 {
923 const struct svc_rdma_pcl *pcl = &head->rc_read_pcl;
924 struct svc_rdma_chunk *chunk, *next;
925 unsigned int inline_len, start, length;
926 int ret;
927
928 inline_len = head->rc_saved_arg.head[0].iov_len;
929 start = 0;
930 chunk = pcl_first_chunk(pcl);
931 length = chunk->ch_position;
932 ret = svc_rdma_copy_inline_range(rqstp, head, start, length);
933 if (ret < 0)
934 return ret;
935
936 pcl_for_each_chunk(chunk, pcl) {
937 ret = svc_rdma_build_read_chunk(rqstp, head, chunk);
938 if (ret < 0)
939 return ret;
940
941 next = pcl_next_chunk(pcl, chunk);
942 if (!next)
943 break;
944
945 start += length;
946 if (head->rc_readbytes > next->ch_position)
947 return -EINVAL;
948 length = next->ch_position - head->rc_readbytes;
949 ret = svc_rdma_copy_inline_range(rqstp, head, start, length);
950 if (ret < 0)
951 return ret;
952 }
953
954 start += length;
955 if (start > inline_len)
956 return -EINVAL;
957 length = inline_len - start;
958 return svc_rdma_copy_inline_range(rqstp, head, start, length);
959 }
960
961 /**
962 * svc_rdma_read_data_item - Construct RDMA Reads to pull data item Read chunks
963 * @rqstp: RPC transaction context
964 * @head: context for ongoing I/O
965 *
966 * The chunk data lands in the page list of rqstp->rq_arg.pages.
967 *
968 * Currently NFSD does not look at the rqstp->rq_arg.tail[0] kvec.
969 * Therefore, XDR round-up of the Read chunk and trailing
970 * inline content must both be added at the end of the pagelist.
971 *
972 * Return values:
973 * %0: RDMA Read WQEs were successfully built
974 * %-EINVAL: client provided too many chunks or segments,
975 * %-ENOMEM: rdma_rw context pool was exhausted,
976 * %-ENOTCONN: posting failed (connection is lost),
977 * %-EIO: rdma_rw initialization failed (DMA mapping, etc).
978 */
svc_rdma_read_data_item(struct svc_rqst * rqstp,struct svc_rdma_recv_ctxt * head)979 static int svc_rdma_read_data_item(struct svc_rqst *rqstp,
980 struct svc_rdma_recv_ctxt *head)
981 {
982 struct svc_rdma_chunk *chunk = pcl_first_chunk(&head->rc_read_pcl);
983
984 if (chunk->ch_position > head->rc_saved_arg.head[0].iov_len)
985 return -EINVAL;
986
987 return svc_rdma_build_read_chunk(rqstp, head, chunk);
988 }
989
990 /**
991 * svc_rdma_read_chunk_range - Build RDMA Read WRs for portion of a chunk
992 * @rqstp: RPC transaction context
993 * @head: context for ongoing I/O
994 * @chunk: parsed Call chunk to pull
995 * @offset: offset of region to pull
996 * @length: length of region to pull
997 *
998 * Return values:
999 * %0: RDMA Read WQEs were successfully built
1000 * %-EINVAL: there were not enough resources to finish
1001 * %-ENOMEM: rdma_rw context pool was exhausted,
1002 * %-ENOTCONN: posting failed (connection is lost),
1003 * %-EIO: rdma_rw initialization failed (DMA mapping, etc).
1004 */
svc_rdma_read_chunk_range(struct svc_rqst * rqstp,struct svc_rdma_recv_ctxt * head,const struct svc_rdma_chunk * chunk,unsigned int offset,unsigned int length)1005 static int svc_rdma_read_chunk_range(struct svc_rqst *rqstp,
1006 struct svc_rdma_recv_ctxt *head,
1007 const struct svc_rdma_chunk *chunk,
1008 unsigned int offset, unsigned int length)
1009 {
1010 const struct svc_rdma_segment *segment;
1011 int ret;
1012
1013 if (!length)
1014 return 0;
1015
1016 ret = -EINVAL;
1017 pcl_for_each_segment(segment, chunk) {
1018 struct svc_rdma_segment dummy;
1019
1020 if (offset >= segment->rs_length) {
1021 offset -= segment->rs_length;
1022 continue;
1023 }
1024
1025 dummy.rs_handle = segment->rs_handle;
1026 dummy.rs_length = min_t(u32, length, segment->rs_length - offset);
1027 dummy.rs_offset = segment->rs_offset + offset;
1028
1029 ret = svc_rdma_build_read_segment(rqstp, head, &dummy);
1030 if (ret < 0)
1031 break;
1032
1033 head->rc_readbytes += dummy.rs_length;
1034 length -= dummy.rs_length;
1035 if (!length)
1036 break;
1037 offset = 0;
1038 }
1039 return ret;
1040 }
1041
1042 /**
1043 * svc_rdma_read_call_chunk - Build RDMA Read WQEs to pull a Long Message
1044 * @rqstp: RPC transaction context
1045 * @head: context for ongoing I/O
1046 *
1047 * Return values:
1048 * %0: RDMA Read WQEs were successfully built
1049 * %-EINVAL: there were not enough resources to finish
1050 * %-ENOMEM: rdma_rw context pool was exhausted,
1051 * %-ENOTCONN: posting failed (connection is lost),
1052 * %-EIO: rdma_rw initialization failed (DMA mapping, etc).
1053 */
svc_rdma_read_call_chunk(struct svc_rqst * rqstp,struct svc_rdma_recv_ctxt * head)1054 static int svc_rdma_read_call_chunk(struct svc_rqst *rqstp,
1055 struct svc_rdma_recv_ctxt *head)
1056 {
1057 const struct svc_rdma_chunk *call_chunk =
1058 pcl_first_chunk(&head->rc_call_pcl);
1059 const struct svc_rdma_pcl *pcl = &head->rc_read_pcl;
1060 struct svc_rdma_chunk *chunk, *next;
1061 unsigned int call_len, start, length;
1062 int ret;
1063
1064 if (pcl_is_empty(pcl))
1065 return svc_rdma_build_read_chunk(rqstp, head, call_chunk);
1066
1067 call_len = call_chunk->ch_length;
1068 start = 0;
1069 chunk = pcl_first_chunk(pcl);
1070 if (chunk->ch_position > call_len)
1071 return -EINVAL;
1072 length = chunk->ch_position;
1073 ret = svc_rdma_read_chunk_range(rqstp, head, call_chunk,
1074 start, length);
1075 if (ret < 0)
1076 return ret;
1077
1078 pcl_for_each_chunk(chunk, pcl) {
1079 ret = svc_rdma_build_read_chunk(rqstp, head, chunk);
1080 if (ret < 0)
1081 return ret;
1082
1083 next = pcl_next_chunk(pcl, chunk);
1084 if (!next)
1085 break;
1086
1087 start += length;
1088 if (next->ch_position > call_len)
1089 return -EINVAL;
1090 if (head->rc_readbytes > next->ch_position)
1091 return -EINVAL;
1092 length = next->ch_position - head->rc_readbytes;
1093 ret = svc_rdma_read_chunk_range(rqstp, head, call_chunk,
1094 start, length);
1095 if (ret < 0)
1096 return ret;
1097 }
1098
1099 start += length;
1100 if (start > call_len)
1101 return -EINVAL;
1102 length = call_len - start;
1103 return svc_rdma_read_chunk_range(rqstp, head, call_chunk,
1104 start, length);
1105 }
1106
1107 /**
1108 * svc_rdma_read_special - Build RDMA Read WQEs to pull a Long Message
1109 * @rqstp: RPC transaction context
1110 * @head: context for ongoing I/O
1111 *
1112 * The start of the data lands in the first page just after the
1113 * Transport header, and the rest lands in rqstp->rq_arg.pages.
1114 *
1115 * Assumptions:
1116 * - A PZRC is never sent in an RDMA_MSG message, though it's
1117 * allowed by spec.
1118 *
1119 * Return values:
1120 * %0: RDMA Read WQEs were successfully built
1121 * %-EINVAL: client provided too many chunks or segments,
1122 * %-ENOMEM: rdma_rw context pool was exhausted,
1123 * %-ENOTCONN: posting failed (connection is lost),
1124 * %-EIO: rdma_rw initialization failed (DMA mapping, etc).
1125 */
svc_rdma_read_special(struct svc_rqst * rqstp,struct svc_rdma_recv_ctxt * head)1126 static noinline int svc_rdma_read_special(struct svc_rqst *rqstp,
1127 struct svc_rdma_recv_ctxt *head)
1128 {
1129 return svc_rdma_read_call_chunk(rqstp, head);
1130 }
1131
1132 /* Pages under I/O have been copied to head->rc_pages. Ensure that
1133 * svc_xprt_release() does not put them when svc_rdma_recvfrom()
1134 * returns. This has to be done after all Read WRs are constructed
1135 * to properly handle a page that happens to be part of I/O on behalf
1136 * of two different RDMA segments.
1137 *
1138 * Note: if the subsequent post_send fails, these pages have already
1139 * been moved to head->rc_pages and thus will be cleaned up by
1140 * svc_rdma_recv_ctxt_put().
1141 */
svc_rdma_clear_rqst_pages(struct svc_rqst * rqstp,struct svc_rdma_recv_ctxt * head)1142 static void svc_rdma_clear_rqst_pages(struct svc_rqst *rqstp,
1143 struct svc_rdma_recv_ctxt *head)
1144 {
1145 unsigned int i;
1146
1147 for (i = 0; i < head->rc_page_count; i++) {
1148 head->rc_pages[i] = rqstp->rq_pages[i];
1149 rqstp->rq_pages[i] = NULL;
1150 }
1151 rqstp->rq_pages_nfree = head->rc_page_count;
1152 }
1153
1154 /**
1155 * svc_rdma_process_read_list - Pull list of Read chunks from the client
1156 * @rdma: controlling RDMA transport
1157 * @rqstp: set of pages to use as Read sink buffers
1158 * @head: pages under I/O collect here
1159 *
1160 * The RPC/RDMA protocol assumes that the upper layer's XDR decoders
1161 * pull each Read chunk as they decode an incoming RPC message.
1162 *
1163 * On Linux, however, the server needs to have a fully-constructed RPC
1164 * message in rqstp->rq_arg when there is a positive return code from
1165 * ->xpo_recvfrom. So the Read list is safety-checked immediately when
1166 * it is received, then here the whole Read list is pulled all at once.
1167 * The ingress RPC message is fully reconstructed once all associated
1168 * RDMA Reads have completed.
1169 *
1170 * Return values:
1171 * %1: all needed RDMA Reads were posted successfully,
1172 * %-EINVAL: client provided too many chunks or segments,
1173 * %-ENOMEM: rdma_rw context pool was exhausted,
1174 * %-ENOTCONN: posting failed (connection is lost),
1175 * %-EIO: rdma_rw initialization failed (DMA mapping, etc).
1176 */
svc_rdma_process_read_list(struct svcxprt_rdma * rdma,struct svc_rqst * rqstp,struct svc_rdma_recv_ctxt * head)1177 int svc_rdma_process_read_list(struct svcxprt_rdma *rdma,
1178 struct svc_rqst *rqstp,
1179 struct svc_rdma_recv_ctxt *head)
1180 {
1181 struct svc_rdma_chunk_ctxt *cc = &head->rc_cc;
1182 int ret;
1183
1184 cc->cc_cqe.done = svc_rdma_wc_read_done;
1185 cc->cc_sqecount = 0;
1186 head->rc_pageoff = 0;
1187 head->rc_curpage = 0;
1188 head->rc_readbytes = 0;
1189
1190 if (pcl_is_empty(&head->rc_call_pcl)) {
1191 if (head->rc_read_pcl.cl_count == 1)
1192 ret = svc_rdma_read_data_item(rqstp, head);
1193 else
1194 ret = svc_rdma_read_multiple_chunks(rqstp, head);
1195 } else
1196 ret = svc_rdma_read_special(rqstp, head);
1197 svc_rdma_clear_rqst_pages(rqstp, head);
1198 if (ret < 0)
1199 return ret;
1200
1201 trace_svcrdma_post_read_chunk(&cc->cc_cid, cc->cc_sqecount);
1202 ret = svc_rdma_post_chunk_ctxt(rdma, cc);
1203 return ret < 0 ? ret : 1;
1204 }
1205