aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
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;