aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2016-06-29 13:52:21 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2016-07-11 15:50:43 -0400
commit564471d2f2f1ddaf02119b8759813666db93abba (patch)
tree9c619e238fe4e31a7135e8f9a694640df5b8e5e2
parent38f1932e60ba249660bbae585f61ef2dee3313a4 (diff)
xprtrdma: Create common scatterlist fields in rpcrdma_mw
Clean up: FMR is about to replace the rpcrdma_map_one code with scatterlists. Move the scatterlist fields out of the FRWR-specific union and into the generic part of rpcrdma_mw. One minor change: -EIO is now returned if FRWR registration fails. The RPC is terminated immediately, since the problem is likely due to a software bug, thus retrying likely won't help. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Tested-by: Steve Wise <swise@opengridcomputing.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
-rw-r--r--net/sunrpc/xprtrdma/frwr_ops.c85
-rw-r--r--net/sunrpc/xprtrdma/xprt_rdma.h8
2 files changed, 46 insertions, 47 deletions
diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c
index c0947544babe..f02ab80aa6ee 100644
--- a/net/sunrpc/xprtrdma/frwr_ops.c
+++ b/net/sunrpc/xprtrdma/frwr_ops.c
@@ -125,17 +125,16 @@ __frwr_reset_mr(struct rpcrdma_ia *ia, struct rpcrdma_mw *r)
125} 125}
126 126
127static void 127static void
128__frwr_reset_and_unmap(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mw *mw) 128__frwr_reset_and_unmap(struct rpcrdma_mw *mw)
129{ 129{
130 struct rpcrdma_xprt *r_xprt = mw->mw_xprt;
130 struct rpcrdma_ia *ia = &r_xprt->rx_ia; 131 struct rpcrdma_ia *ia = &r_xprt->rx_ia;
131 struct rpcrdma_frmr *f = &mw->frmr;
132 int rc; 132 int rc;
133 133
134 rc = __frwr_reset_mr(ia, mw); 134 rc = __frwr_reset_mr(ia, mw);
135 ib_dma_unmap_sg(ia->ri_device, f->fr_sg, f->fr_nents, f->fr_dir); 135 ib_dma_unmap_sg(ia->ri_device, mw->mw_sg, mw->mw_nents, mw->mw_dir);
136 if (rc) 136 if (rc)
137 return; 137 return;
138
139 rpcrdma_put_mw(r_xprt, mw); 138 rpcrdma_put_mw(r_xprt, mw);
140} 139}
141 140
@@ -152,8 +151,7 @@ __frwr_recovery_worker(struct work_struct *work)
152 struct rpcrdma_mw *r = container_of(work, struct rpcrdma_mw, 151 struct rpcrdma_mw *r = container_of(work, struct rpcrdma_mw,
153 mw_work); 152 mw_work);
154 153
155 __frwr_reset_and_unmap(r->mw_xprt, r); 154 __frwr_reset_and_unmap(r);
156 return;
157} 155}
158 156
159/* A broken MR was discovered in a context that can't sleep. 157/* A broken MR was discovered in a context that can't sleep.
@@ -167,8 +165,7 @@ __frwr_queue_recovery(struct rpcrdma_mw *r)
167} 165}
168 166
169static int 167static int
170__frwr_init(struct rpcrdma_mw *r, struct ib_pd *pd, struct ib_device *device, 168__frwr_init(struct rpcrdma_mw *r, struct ib_pd *pd, unsigned int depth)
171 unsigned int depth)
172{ 169{
173 struct rpcrdma_frmr *f = &r->frmr; 170 struct rpcrdma_frmr *f = &r->frmr;
174 int rc; 171 int rc;
@@ -177,11 +174,11 @@ __frwr_init(struct rpcrdma_mw *r, struct ib_pd *pd, struct ib_device *device,
177 if (IS_ERR(f->fr_mr)) 174 if (IS_ERR(f->fr_mr))
178 goto out_mr_err; 175 goto out_mr_err;
179 176
180 f->fr_sg = kcalloc(depth, sizeof(*f->fr_sg), GFP_KERNEL); 177 r->mw_sg = kcalloc(depth, sizeof(*r->mw_sg), GFP_KERNEL);
181 if (!f->fr_sg) 178 if (!r->mw_sg)
182 goto out_list_err; 179 goto out_list_err;
183 180
184 sg_init_table(f->fr_sg, depth); 181 sg_init_table(r->mw_sg, depth);
185 182
186 init_completion(&f->fr_linv_done); 183 init_completion(&f->fr_linv_done);
187 184
@@ -210,7 +207,7 @@ __frwr_release(struct rpcrdma_mw *r)
210 if (rc) 207 if (rc)
211 dprintk("RPC: %s: ib_dereg_mr status %i\n", 208 dprintk("RPC: %s: ib_dereg_mr status %i\n",
212 __func__, rc); 209 __func__, rc);
213 kfree(r->frmr.fr_sg); 210 kfree(r->mw_sg);
214} 211}
215 212
216static int 213static int
@@ -350,7 +347,6 @@ static int
350frwr_op_init(struct rpcrdma_xprt *r_xprt) 347frwr_op_init(struct rpcrdma_xprt *r_xprt)
351{ 348{
352 struct rpcrdma_buffer *buf = &r_xprt->rx_buf; 349 struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
353 struct ib_device *device = r_xprt->rx_ia.ri_device;
354 unsigned int depth = r_xprt->rx_ia.ri_max_frmr_depth; 350 unsigned int depth = r_xprt->rx_ia.ri_max_frmr_depth;
355 struct ib_pd *pd = r_xprt->rx_ia.ri_pd; 351 struct ib_pd *pd = r_xprt->rx_ia.ri_pd;
356 int i; 352 int i;
@@ -372,7 +368,7 @@ frwr_op_init(struct rpcrdma_xprt *r_xprt)
372 if (!r) 368 if (!r)
373 return -ENOMEM; 369 return -ENOMEM;
374 370
375 rc = __frwr_init(r, pd, device, depth); 371 rc = __frwr_init(r, pd, depth);
376 if (rc) { 372 if (rc) {
377 kfree(r); 373 kfree(r);
378 return rc; 374 return rc;
@@ -386,7 +382,7 @@ frwr_op_init(struct rpcrdma_xprt *r_xprt)
386 return 0; 382 return 0;
387} 383}
388 384
389/* Post a FAST_REG Work Request to register a memory region 385/* Post a REG_MR Work Request to register a memory region
390 * for remote access via RDMA READ or RDMA WRITE. 386 * for remote access via RDMA READ or RDMA WRITE.
391 */ 387 */
392static int 388static int
@@ -394,8 +390,6 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg,
394 int nsegs, bool writing) 390 int nsegs, bool writing)
395{ 391{
396 struct rpcrdma_ia *ia = &r_xprt->rx_ia; 392 struct rpcrdma_ia *ia = &r_xprt->rx_ia;
397 struct ib_device *device = ia->ri_device;
398 enum dma_data_direction direction = rpcrdma_data_dir(writing);
399 struct rpcrdma_mr_seg *seg1 = seg; 393 struct rpcrdma_mr_seg *seg1 = seg;
400 struct rpcrdma_mw *mw; 394 struct rpcrdma_mw *mw;
401 struct rpcrdma_frmr *frmr; 395 struct rpcrdma_frmr *frmr;
@@ -421,15 +415,14 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg,
421 415
422 if (nsegs > ia->ri_max_frmr_depth) 416 if (nsegs > ia->ri_max_frmr_depth)
423 nsegs = ia->ri_max_frmr_depth; 417 nsegs = ia->ri_max_frmr_depth;
424
425 for (i = 0; i < nsegs;) { 418 for (i = 0; i < nsegs;) {
426 if (seg->mr_page) 419 if (seg->mr_page)
427 sg_set_page(&frmr->fr_sg[i], 420 sg_set_page(&mw->mw_sg[i],
428 seg->mr_page, 421 seg->mr_page,
429 seg->mr_len, 422 seg->mr_len,
430 offset_in_page(seg->mr_offset)); 423 offset_in_page(seg->mr_offset));
431 else 424 else
432 sg_set_buf(&frmr->fr_sg[i], seg->mr_offset, 425 sg_set_buf(&mw->mw_sg[i], seg->mr_offset,
433 seg->mr_len); 426 seg->mr_len);
434 427
435 ++seg; 428 ++seg;
@@ -440,26 +433,20 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg,
440 offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len)) 433 offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len))
441 break; 434 break;
442 } 435 }
443 frmr->fr_nents = i; 436 mw->mw_nents = i;
444 frmr->fr_dir = direction; 437 mw->mw_dir = rpcrdma_data_dir(writing);
445
446 dma_nents = ib_dma_map_sg(device, frmr->fr_sg, frmr->fr_nents, direction);
447 if (!dma_nents) {
448 pr_err("RPC: %s: failed to dma map sg %p sg_nents %u\n",
449 __func__, frmr->fr_sg, frmr->fr_nents);
450 return -ENOMEM;
451 }
452 438
453 n = ib_map_mr_sg(mr, frmr->fr_sg, frmr->fr_nents, NULL, PAGE_SIZE); 439 dma_nents = ib_dma_map_sg(ia->ri_device,
454 if (unlikely(n != frmr->fr_nents)) { 440 mw->mw_sg, mw->mw_nents, mw->mw_dir);
455 pr_err("RPC: %s: failed to map mr %p (%u/%u)\n", 441 if (!dma_nents)
456 __func__, frmr->fr_mr, n, frmr->fr_nents); 442 goto out_dmamap_err;
457 rc = n < 0 ? n : -EINVAL; 443
458 goto out_senderr; 444 n = ib_map_mr_sg(mr, mw->mw_sg, mw->mw_nents, NULL, PAGE_SIZE);
459 } 445 if (unlikely(n != mw->mw_nents))
446 goto out_mapmr_err;
460 447
461 dprintk("RPC: %s: Using frmr %p to map %u segments (%u bytes)\n", 448 dprintk("RPC: %s: Using frmr %p to map %u segments (%u bytes)\n",
462 __func__, mw, frmr->fr_nents, mr->length); 449 __func__, mw, mw->mw_nents, mr->length);
463 450
464 key = (u8)(mr->rkey & 0x000000FF); 451 key = (u8)(mr->rkey & 0x000000FF);
465 ib_update_fast_reg_key(mr, ++key); 452 ib_update_fast_reg_key(mr, ++key);
@@ -484,13 +471,25 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg,
484 seg1->rl_mw = mw; 471 seg1->rl_mw = mw;
485 seg1->mr_rkey = mr->rkey; 472 seg1->mr_rkey = mr->rkey;
486 seg1->mr_base = mr->iova; 473 seg1->mr_base = mr->iova;
487 seg1->mr_nsegs = frmr->fr_nents; 474 seg1->mr_nsegs = mw->mw_nents;
488 seg1->mr_len = mr->length; 475 seg1->mr_len = mr->length;
489 476
490 return frmr->fr_nents; 477 return mw->mw_nents;
478
479out_dmamap_err:
480 pr_err("rpcrdma: failed to dma map sg %p sg_nents %u\n",
481 mw->mw_sg, mw->mw_nents);
482 return -ENOMEM;
483
484out_mapmr_err:
485 pr_err("rpcrdma: failed to map mr %p (%u/%u)\n",
486 frmr->fr_mr, n, mw->mw_nents);
487 rc = n < 0 ? n : -EIO;
488 __frwr_queue_recovery(mw);
489 return rc;
491 490
492out_senderr: 491out_senderr:
493 dprintk("RPC: %s: ib_post_send status %i\n", __func__, rc); 492 pr_err("rpcrdma: ib_post_send status %i\n", rc);
494 __frwr_queue_recovery(mw); 493 __frwr_queue_recovery(mw);
495 return rc; 494 return rc;
496} 495}
@@ -582,8 +581,8 @@ unmap:
582 mw = seg->rl_mw; 581 mw = seg->rl_mw;
583 seg->rl_mw = NULL; 582 seg->rl_mw = NULL;
584 583
585 ib_dma_unmap_sg(ia->ri_device, f->fr_sg, f->fr_nents, 584 ib_dma_unmap_sg(ia->ri_device,
586 f->fr_dir); 585 mw->mw_sg, mw->mw_nents, mw->mw_dir);
587 rpcrdma_put_mw(r_xprt, mw); 586 rpcrdma_put_mw(r_xprt, mw);
588 587
589 i += seg->mr_nsegs; 588 i += seg->mr_nsegs;
@@ -630,7 +629,7 @@ frwr_op_unmap_safe(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req,
630 mw = seg->rl_mw; 629 mw = seg->rl_mw;
631 630
632 if (sync) 631 if (sync)
633 __frwr_reset_and_unmap(r_xprt, mw); 632 __frwr_reset_and_unmap(mw);
634 else 633 else
635 __frwr_queue_recovery(mw); 634 __frwr_queue_recovery(mw);
636 635
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
index 95cdc66225ee..c53abd1281b3 100644
--- a/net/sunrpc/xprtrdma/xprt_rdma.h
+++ b/net/sunrpc/xprtrdma/xprt_rdma.h
@@ -221,9 +221,6 @@ enum rpcrdma_frmr_state {
221}; 221};
222 222
223struct rpcrdma_frmr { 223struct rpcrdma_frmr {
224 struct scatterlist *fr_sg;
225 int fr_nents;
226 enum dma_data_direction fr_dir;
227 struct ib_mr *fr_mr; 224 struct ib_mr *fr_mr;
228 struct ib_cqe fr_cqe; 225 struct ib_cqe fr_cqe;
229 enum rpcrdma_frmr_state fr_state; 226 enum rpcrdma_frmr_state fr_state;
@@ -240,13 +237,16 @@ struct rpcrdma_fmr {
240}; 237};
241 238
242struct rpcrdma_mw { 239struct rpcrdma_mw {
240 struct list_head mw_list;
241 struct scatterlist *mw_sg;
242 int mw_nents;
243 enum dma_data_direction mw_dir;
243 union { 244 union {
244 struct rpcrdma_fmr fmr; 245 struct rpcrdma_fmr fmr;
245 struct rpcrdma_frmr frmr; 246 struct rpcrdma_frmr frmr;
246 }; 247 };
247 struct work_struct mw_work; 248 struct work_struct mw_work;
248 struct rpcrdma_xprt *mw_xprt; 249 struct rpcrdma_xprt *mw_xprt;
249 struct list_head mw_list;
250 struct list_head mw_all; 250 struct list_head mw_all;
251}; 251};
252 252