summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2019-08-19 18:45:37 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2019-08-20 16:23:35 -0400
commit3b39f52a02d4b3322744a0a32d59142e01afa435 (patch)
treee2380bbe235ecb137d22aa44d963bf4af15204e2
parent1ca3f4c054a4e3765bdeb62c849d940b5bc8002d (diff)
xprtrdma: Move rpcrdma_mr_get out of frwr_map
Refactor: Retrieve an MR and handle error recovery entirely in rpc_rdma.c, as this is not a device-specific function. Note that since commit 89f90fe1ad8b ("SUNRPC: Allow calls to xprt_transmit() to drain the entire transmit queue"), the xprt_transmit function handles the cond_resched. The transport no longer has to do this itself. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
-rw-r--r--include/trace/events/rpcrdma.h29
-rw-r--r--net/sunrpc/xprtrdma/frwr_ops.c23
-rw-r--r--net/sunrpc/xprtrdma/rpc_rdma.c30
-rw-r--r--net/sunrpc/xprtrdma/verbs.c21
-rw-r--r--net/sunrpc/xprtrdma/xprt_rdma.h4
5 files changed, 63 insertions, 44 deletions
diff --git a/include/trace/events/rpcrdma.h b/include/trace/events/rpcrdma.h
index 6e6055eb67e7..83c4dfd7feea 100644
--- a/include/trace/events/rpcrdma.h
+++ b/include/trace/events/rpcrdma.h
@@ -464,7 +464,34 @@ TRACE_EVENT(xprtrdma_createmrs,
464 ) 464 )
465); 465);
466 466
467DEFINE_RXPRT_EVENT(xprtrdma_nomrs); 467TRACE_EVENT(xprtrdma_nomrs,
468 TP_PROTO(
469 const struct rpcrdma_req *req
470 ),
471
472 TP_ARGS(req),
473
474 TP_STRUCT__entry(
475 __field(const void *, req)
476 __field(unsigned int, task_id)
477 __field(unsigned int, client_id)
478 __field(u32, xid)
479 ),
480
481 TP_fast_assign(
482 const struct rpc_rqst *rqst = &req->rl_slot;
483
484 __entry->req = req;
485 __entry->task_id = rqst->rq_task->tk_pid;
486 __entry->client_id = rqst->rq_task->tk_client->cl_clid;
487 __entry->xid = be32_to_cpu(rqst->rq_xid);
488 ),
489
490 TP_printk("task:%u@%u xid=0x%08x req=%p",
491 __entry->task_id, __entry->client_id, __entry->xid,
492 __entry->req
493 )
494);
468 495
469DEFINE_RDCH_EVENT(read); 496DEFINE_RDCH_EVENT(read);
470DEFINE_WRCH_EVENT(write); 497DEFINE_WRCH_EVENT(write);
diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c
index 97e1804139b8..362056f4f48d 100644
--- a/net/sunrpc/xprtrdma/frwr_ops.c
+++ b/net/sunrpc/xprtrdma/frwr_ops.c
@@ -291,31 +291,25 @@ size_t frwr_maxpages(struct rpcrdma_xprt *r_xprt)
291 * @nsegs: number of segments remaining 291 * @nsegs: number of segments remaining
292 * @writing: true when RDMA Write will be used 292 * @writing: true when RDMA Write will be used
293 * @xid: XID of RPC using the registered memory 293 * @xid: XID of RPC using the registered memory
294 * @out: initialized MR 294 * @mr: MR to fill in
295 * 295 *
296 * Prepare a REG_MR Work Request to register a memory region 296 * Prepare a REG_MR Work Request to register a memory region
297 * for remote access via RDMA READ or RDMA WRITE. 297 * for remote access via RDMA READ or RDMA WRITE.
298 * 298 *
299 * Returns the next segment or a negative errno pointer. 299 * Returns the next segment or a negative errno pointer.
300 * On success, the prepared MR is planted in @out. 300 * On success, @mr is filled in.
301 */ 301 */
302struct rpcrdma_mr_seg *frwr_map(struct rpcrdma_xprt *r_xprt, 302struct rpcrdma_mr_seg *frwr_map(struct rpcrdma_xprt *r_xprt,
303 struct rpcrdma_mr_seg *seg, 303 struct rpcrdma_mr_seg *seg,
304 int nsegs, bool writing, __be32 xid, 304 int nsegs, bool writing, __be32 xid,
305 struct rpcrdma_mr **out) 305 struct rpcrdma_mr *mr)
306{ 306{
307 struct rpcrdma_ia *ia = &r_xprt->rx_ia; 307 struct rpcrdma_ia *ia = &r_xprt->rx_ia;
308 bool holes_ok = ia->ri_mrtype == IB_MR_TYPE_SG_GAPS;
309 struct rpcrdma_mr *mr;
310 struct ib_mr *ibmr;
311 struct ib_reg_wr *reg_wr; 308 struct ib_reg_wr *reg_wr;
309 struct ib_mr *ibmr;
312 int i, n; 310 int i, n;
313 u8 key; 311 u8 key;
314 312
315 mr = rpcrdma_mr_get(r_xprt);
316 if (!mr)
317 goto out_getmr_err;
318
319 if (nsegs > ia->ri_max_frwr_depth) 313 if (nsegs > ia->ri_max_frwr_depth)
320 nsegs = ia->ri_max_frwr_depth; 314 nsegs = ia->ri_max_frwr_depth;
321 for (i = 0; i < nsegs;) { 315 for (i = 0; i < nsegs;) {
@@ -330,7 +324,7 @@ struct rpcrdma_mr_seg *frwr_map(struct rpcrdma_xprt *r_xprt,
330 324
331 ++seg; 325 ++seg;
332 ++i; 326 ++i;
333 if (holes_ok) 327 if (ia->ri_mrtype == IB_MR_TYPE_SG_GAPS)
334 continue; 328 continue;
335 if ((i < nsegs && offset_in_page(seg->mr_offset)) || 329 if ((i < nsegs && offset_in_page(seg->mr_offset)) ||
336 offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len)) 330 offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len))
@@ -365,22 +359,15 @@ struct rpcrdma_mr_seg *frwr_map(struct rpcrdma_xprt *r_xprt,
365 mr->mr_offset = ibmr->iova; 359 mr->mr_offset = ibmr->iova;
366 trace_xprtrdma_mr_map(mr); 360 trace_xprtrdma_mr_map(mr);
367 361
368 *out = mr;
369 return seg; 362 return seg;
370 363
371out_getmr_err:
372 xprt_wait_for_buffer_space(&r_xprt->rx_xprt);
373 return ERR_PTR(-EAGAIN);
374
375out_dmamap_err: 364out_dmamap_err:
376 mr->mr_dir = DMA_NONE; 365 mr->mr_dir = DMA_NONE;
377 trace_xprtrdma_frwr_sgerr(mr, i); 366 trace_xprtrdma_frwr_sgerr(mr, i);
378 rpcrdma_mr_put(mr);
379 return ERR_PTR(-EIO); 367 return ERR_PTR(-EIO);
380 368
381out_mapmr_err: 369out_mapmr_err:
382 trace_xprtrdma_frwr_maperr(mr, n); 370 trace_xprtrdma_frwr_maperr(mr, n);
383 rpcrdma_mr_recycle(mr);
384 return ERR_PTR(-EIO); 371 return ERR_PTR(-EIO);
385} 372}
386 373
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c
index 0ac096a6348a..34772cb19286 100644
--- a/net/sunrpc/xprtrdma/rpc_rdma.c
+++ b/net/sunrpc/xprtrdma/rpc_rdma.c
@@ -342,6 +342,27 @@ encode_read_segment(struct xdr_stream *xdr, struct rpcrdma_mr *mr,
342 return 0; 342 return 0;
343} 343}
344 344
345static struct rpcrdma_mr_seg *rpcrdma_mr_prepare(struct rpcrdma_xprt *r_xprt,
346 struct rpcrdma_req *req,
347 struct rpcrdma_mr_seg *seg,
348 int nsegs, bool writing,
349 struct rpcrdma_mr **mr)
350{
351 *mr = rpcrdma_mr_get(r_xprt);
352 if (!*mr)
353 goto out_getmr_err;
354
355 rpcrdma_mr_push(*mr, &req->rl_registered);
356 return frwr_map(r_xprt, seg, nsegs, writing, req->rl_slot.rq_xid, *mr);
357
358out_getmr_err:
359 trace_xprtrdma_nomrs(req);
360 xprt_wait_for_buffer_space(&r_xprt->rx_xprt);
361 if (r_xprt->rx_ep.rep_connected != -ENODEV)
362 schedule_work(&r_xprt->rx_buf.rb_refresh_worker);
363 return ERR_PTR(-EAGAIN);
364}
365
345/* Register and XDR encode the Read list. Supports encoding a list of read 366/* Register and XDR encode the Read list. Supports encoding a list of read
346 * segments that belong to a single read chunk. 367 * segments that belong to a single read chunk.
347 * 368 *
@@ -379,10 +400,9 @@ rpcrdma_encode_read_list(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req,
379 return nsegs; 400 return nsegs;
380 401
381 do { 402 do {
382 seg = frwr_map(r_xprt, seg, nsegs, false, rqst->rq_xid, &mr); 403 seg = rpcrdma_mr_prepare(r_xprt, req, seg, nsegs, false, &mr);
383 if (IS_ERR(seg)) 404 if (IS_ERR(seg))
384 return PTR_ERR(seg); 405 return PTR_ERR(seg);
385 rpcrdma_mr_push(mr, &req->rl_registered);
386 406
387 if (encode_read_segment(xdr, mr, pos) < 0) 407 if (encode_read_segment(xdr, mr, pos) < 0)
388 return -EMSGSIZE; 408 return -EMSGSIZE;
@@ -440,10 +460,9 @@ rpcrdma_encode_write_list(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req,
440 460
441 nchunks = 0; 461 nchunks = 0;
442 do { 462 do {
443 seg = frwr_map(r_xprt, seg, nsegs, true, rqst->rq_xid, &mr); 463 seg = rpcrdma_mr_prepare(r_xprt, req, seg, nsegs, true, &mr);
444 if (IS_ERR(seg)) 464 if (IS_ERR(seg))
445 return PTR_ERR(seg); 465 return PTR_ERR(seg);
446 rpcrdma_mr_push(mr, &req->rl_registered);
447 466
448 if (encode_rdma_segment(xdr, mr) < 0) 467 if (encode_rdma_segment(xdr, mr) < 0)
449 return -EMSGSIZE; 468 return -EMSGSIZE;
@@ -501,10 +520,9 @@ rpcrdma_encode_reply_chunk(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req,
501 520
502 nchunks = 0; 521 nchunks = 0;
503 do { 522 do {
504 seg = frwr_map(r_xprt, seg, nsegs, true, rqst->rq_xid, &mr); 523 seg = rpcrdma_mr_prepare(r_xprt, req, seg, nsegs, true, &mr);
505 if (IS_ERR(seg)) 524 if (IS_ERR(seg))
506 return PTR_ERR(seg); 525 return PTR_ERR(seg);
507 rpcrdma_mr_push(mr, &req->rl_registered);
508 526
509 if (encode_rdma_segment(xdr, mr) < 0) 527 if (encode_rdma_segment(xdr, mr) < 0)
510 return -EMSGSIZE; 528 return -EMSGSIZE;
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index 5e0b774ed522..c9fa0f27b10a 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -408,7 +408,7 @@ rpcrdma_ia_remove(struct rpcrdma_ia *ia)
408 struct rpcrdma_req *req; 408 struct rpcrdma_req *req;
409 struct rpcrdma_rep *rep; 409 struct rpcrdma_rep *rep;
410 410
411 cancel_delayed_work_sync(&buf->rb_refresh_worker); 411 cancel_work_sync(&buf->rb_refresh_worker);
412 412
413 /* This is similar to rpcrdma_ep_destroy, but: 413 /* This is similar to rpcrdma_ep_destroy, but:
414 * - Don't cancel the connect worker. 414 * - Don't cancel the connect worker.
@@ -975,7 +975,7 @@ static void
975rpcrdma_mr_refresh_worker(struct work_struct *work) 975rpcrdma_mr_refresh_worker(struct work_struct *work)
976{ 976{
977 struct rpcrdma_buffer *buf = container_of(work, struct rpcrdma_buffer, 977 struct rpcrdma_buffer *buf = container_of(work, struct rpcrdma_buffer,
978 rb_refresh_worker.work); 978 rb_refresh_worker);
979 struct rpcrdma_xprt *r_xprt = container_of(buf, struct rpcrdma_xprt, 979 struct rpcrdma_xprt *r_xprt = container_of(buf, struct rpcrdma_xprt,
980 rx_buf); 980 rx_buf);
981 981
@@ -1086,8 +1086,7 @@ int rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
1086 spin_lock_init(&buf->rb_lock); 1086 spin_lock_init(&buf->rb_lock);
1087 INIT_LIST_HEAD(&buf->rb_mrs); 1087 INIT_LIST_HEAD(&buf->rb_mrs);
1088 INIT_LIST_HEAD(&buf->rb_all_mrs); 1088 INIT_LIST_HEAD(&buf->rb_all_mrs);
1089 INIT_DELAYED_WORK(&buf->rb_refresh_worker, 1089 INIT_WORK(&buf->rb_refresh_worker, rpcrdma_mr_refresh_worker);
1090 rpcrdma_mr_refresh_worker);
1091 1090
1092 rpcrdma_mrs_create(r_xprt); 1091 rpcrdma_mrs_create(r_xprt);
1093 1092
@@ -1177,7 +1176,7 @@ rpcrdma_mrs_destroy(struct rpcrdma_buffer *buf)
1177void 1176void
1178rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf) 1177rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
1179{ 1178{
1180 cancel_delayed_work_sync(&buf->rb_refresh_worker); 1179 cancel_work_sync(&buf->rb_refresh_worker);
1181 1180
1182 rpcrdma_sendctxs_destroy(buf); 1181 rpcrdma_sendctxs_destroy(buf);
1183 1182
@@ -1218,19 +1217,7 @@ rpcrdma_mr_get(struct rpcrdma_xprt *r_xprt)
1218 spin_lock(&buf->rb_mrlock); 1217 spin_lock(&buf->rb_mrlock);
1219 mr = rpcrdma_mr_pop(&buf->rb_mrs); 1218 mr = rpcrdma_mr_pop(&buf->rb_mrs);
1220 spin_unlock(&buf->rb_mrlock); 1219 spin_unlock(&buf->rb_mrlock);
1221 if (!mr)
1222 goto out_nomrs;
1223 return mr; 1220 return mr;
1224
1225out_nomrs:
1226 trace_xprtrdma_nomrs(r_xprt);
1227 if (r_xprt->rx_ep.rep_connected != -ENODEV)
1228 schedule_delayed_work(&buf->rb_refresh_worker, 0);
1229
1230 /* Allow the reply handler and refresh worker to run */
1231 cond_resched();
1232
1233 return NULL;
1234} 1221}
1235 1222
1236/** 1223/**
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
index 3e0839c2cda2..9573587ca602 100644
--- a/net/sunrpc/xprtrdma/xprt_rdma.h
+++ b/net/sunrpc/xprtrdma/xprt_rdma.h
@@ -379,7 +379,7 @@ struct rpcrdma_buffer {
379 u32 rb_bc_srv_max_requests; 379 u32 rb_bc_srv_max_requests;
380 u32 rb_bc_max_requests; 380 u32 rb_bc_max_requests;
381 381
382 struct delayed_work rb_refresh_worker; 382 struct work_struct rb_refresh_worker;
383}; 383};
384 384
385/* 385/*
@@ -548,7 +548,7 @@ size_t frwr_maxpages(struct rpcrdma_xprt *r_xprt);
548struct rpcrdma_mr_seg *frwr_map(struct rpcrdma_xprt *r_xprt, 548struct rpcrdma_mr_seg *frwr_map(struct rpcrdma_xprt *r_xprt,
549 struct rpcrdma_mr_seg *seg, 549 struct rpcrdma_mr_seg *seg,
550 int nsegs, bool writing, __be32 xid, 550 int nsegs, bool writing, __be32 xid,
551 struct rpcrdma_mr **mr); 551 struct rpcrdma_mr *mr);
552int frwr_send(struct rpcrdma_ia *ia, struct rpcrdma_req *req); 552int frwr_send(struct rpcrdma_ia *ia, struct rpcrdma_req *req);
553void frwr_reminv(struct rpcrdma_rep *rep, struct list_head *mrs); 553void frwr_reminv(struct rpcrdma_rep *rep, struct list_head *mrs);
554void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req); 554void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req);