aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
authorTom Talpey <talpey@netapp.com>2008-10-09 15:00:09 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-10-10 15:09:26 -0400
commitbd7ed1d13304d914648dacec4dbb9145aaae614e (patch)
treea0eee0c8304ab4bab7baca4675ebf8fffef1e288 /net/sunrpc
parentfe9053b30bb48b99f7b45541249f5cfe96bdf7f7 (diff)
RPC/RDMA: check selected memory registration mode at runtime.
At transport creation, check for, and use, any local dma lkey. Then, check that the selected memory registration mode is in fact supported by the RDMA adapter selected for the mount. Fall back to best alternative if not. Signed-off-by: Tom Talpey <talpey@netapp.com> Acked-by: Tom Tucker <tom@opengridcomputing.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/xprtrdma/verbs.c95
1 files changed, 80 insertions, 15 deletions
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index d04208a02f67..0f3b43148b7f 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -423,7 +423,8 @@ rpcrdma_clean_cq(struct ib_cq *cq)
423int 423int
424rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg) 424rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
425{ 425{
426 int rc; 426 int rc, mem_priv;
427 struct ib_device_attr devattr;
427 struct rpcrdma_ia *ia = &xprt->rx_ia; 428 struct rpcrdma_ia *ia = &xprt->rx_ia;
428 429
429 init_completion(&ia->ri_done); 430 init_completion(&ia->ri_done);
@@ -443,6 +444,53 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
443 } 444 }
444 445
445 /* 446 /*
447 * Query the device to determine if the requested memory
448 * registration strategy is supported. If it isn't, set the
449 * strategy to a globally supported model.
450 */
451 rc = ib_query_device(ia->ri_id->device, &devattr);
452 if (rc) {
453 dprintk("RPC: %s: ib_query_device failed %d\n",
454 __func__, rc);
455 goto out2;
456 }
457
458 if (devattr.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY) {
459 ia->ri_have_dma_lkey = 1;
460 ia->ri_dma_lkey = ia->ri_id->device->local_dma_lkey;
461 }
462
463 switch (memreg) {
464 case RPCRDMA_MEMWINDOWS:
465 case RPCRDMA_MEMWINDOWS_ASYNC:
466 if (!(devattr.device_cap_flags & IB_DEVICE_MEM_WINDOW)) {
467 dprintk("RPC: %s: MEMWINDOWS registration "
468 "specified but not supported by adapter, "
469 "using slower RPCRDMA_REGISTER\n",
470 __func__);
471 memreg = RPCRDMA_REGISTER;
472 }
473 break;
474 case RPCRDMA_MTHCAFMR:
475 if (!ia->ri_id->device->alloc_fmr) {
476#if RPCRDMA_PERSISTENT_REGISTRATION
477 dprintk("RPC: %s: MTHCAFMR registration "
478 "specified but not supported by adapter, "
479 "using riskier RPCRDMA_ALLPHYSICAL\n",
480 __func__);
481 memreg = RPCRDMA_ALLPHYSICAL;
482#else
483 dprintk("RPC: %s: MTHCAFMR registration "
484 "specified but not supported by adapter, "
485 "using slower RPCRDMA_REGISTER\n",
486 __func__);
487 memreg = RPCRDMA_REGISTER;
488#endif
489 }
490 break;
491 }
492
493 /*
446 * Optionally obtain an underlying physical identity mapping in 494 * Optionally obtain an underlying physical identity mapping in
447 * order to do a memory window-based bind. This base registration 495 * order to do a memory window-based bind. This base registration
448 * is protected from remote access - that is enabled only by binding 496 * is protected from remote access - that is enabled only by binding
@@ -450,22 +498,27 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
450 * revoked after the corresponding completion similar to a storage 498 * revoked after the corresponding completion similar to a storage
451 * adapter. 499 * adapter.
452 */ 500 */
453 if (memreg > RPCRDMA_REGISTER) { 501 switch (memreg) {
454 int mem_priv = IB_ACCESS_LOCAL_WRITE; 502 case RPCRDMA_BOUNCEBUFFERS:
455 switch (memreg) { 503 case RPCRDMA_REGISTER:
504 break;
456#if RPCRDMA_PERSISTENT_REGISTRATION 505#if RPCRDMA_PERSISTENT_REGISTRATION
457 case RPCRDMA_ALLPHYSICAL: 506 case RPCRDMA_ALLPHYSICAL:
458 mem_priv |= IB_ACCESS_REMOTE_WRITE; 507 mem_priv = IB_ACCESS_LOCAL_WRITE |
459 mem_priv |= IB_ACCESS_REMOTE_READ; 508 IB_ACCESS_REMOTE_WRITE |
460 break; 509 IB_ACCESS_REMOTE_READ;
510 goto register_setup;
461#endif 511#endif
462 case RPCRDMA_MEMWINDOWS_ASYNC: 512 case RPCRDMA_MEMWINDOWS_ASYNC:
463 case RPCRDMA_MEMWINDOWS: 513 case RPCRDMA_MEMWINDOWS:
464 mem_priv |= IB_ACCESS_MW_BIND; 514 mem_priv = IB_ACCESS_LOCAL_WRITE |
465 break; 515 IB_ACCESS_MW_BIND;
466 default: 516 goto register_setup;
517 case RPCRDMA_MTHCAFMR:
518 if (ia->ri_have_dma_lkey)
467 break; 519 break;
468 } 520 mem_priv = IB_ACCESS_LOCAL_WRITE;
521 register_setup:
469 ia->ri_bind_mem = ib_get_dma_mr(ia->ri_pd, mem_priv); 522 ia->ri_bind_mem = ib_get_dma_mr(ia->ri_pd, mem_priv);
470 if (IS_ERR(ia->ri_bind_mem)) { 523 if (IS_ERR(ia->ri_bind_mem)) {
471 printk(KERN_ALERT "%s: ib_get_dma_mr for " 524 printk(KERN_ALERT "%s: ib_get_dma_mr for "
@@ -475,7 +528,15 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
475 memreg = RPCRDMA_REGISTER; 528 memreg = RPCRDMA_REGISTER;
476 ia->ri_bind_mem = NULL; 529 ia->ri_bind_mem = NULL;
477 } 530 }
531 break;
532 default:
533 printk(KERN_ERR "%s: invalid memory registration mode %d\n",
534 __func__, memreg);
535 rc = -EINVAL;
536 goto out2;
478 } 537 }
538 dprintk("RPC: %s: memory registration strategy is %d\n",
539 __func__, memreg);
479 540
480 /* Else will do memory reg/dereg for each chunk */ 541 /* Else will do memory reg/dereg for each chunk */
481 ia->ri_memreg_strategy = memreg; 542 ia->ri_memreg_strategy = memreg;
@@ -1248,7 +1309,11 @@ rpcrdma_register_internal(struct rpcrdma_ia *ia, void *va, int len,
1248 va, len, DMA_BIDIRECTIONAL); 1309 va, len, DMA_BIDIRECTIONAL);
1249 iov->length = len; 1310 iov->length = len;
1250 1311
1251 if (ia->ri_bind_mem != NULL) { 1312 if (ia->ri_have_dma_lkey) {
1313 *mrp = NULL;
1314 iov->lkey = ia->ri_dma_lkey;
1315 return 0;
1316 } else if (ia->ri_bind_mem != NULL) {
1252 *mrp = NULL; 1317 *mrp = NULL;
1253 iov->lkey = ia->ri_bind_mem->lkey; 1318 iov->lkey = ia->ri_bind_mem->lkey;
1254 return 0; 1319 return 0;