diff options
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/xprtrdma/verbs.c | 95 |
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) | |||
423 | int | 423 | int |
424 | rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg) | 424 | rpcrdma_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; |